From cd543a1506c5ae3d9975e662b81c9d3f11f37ff7 Mon Sep 17 00:00:00 2001 From: Harvey Kandola Date: Mon, 18 Sep 2017 13:35:51 +0100 Subject: [PATCH] force space delete --- domain/document/mysql/store.go | 27 ++++++++++++++-- domain/space/endpoint.go | 10 +++++- domain/space/mysql/store.go | 3 +- domain/storer.go | 1 + gui/app/components/folder/folder-toolbar.js | 18 +++++++++++ gui/app/pods/folder/index/template.hbs | 3 +- .../folder/settings/category/controller.js | 15 +++++++++ .../pods/folder/settings/category/route.js | 25 +++++++++++++++ .../folder/settings/category/template.hbs | 1 + .../components/folder/folder-toolbar.hbs | 32 +++++++++++++------ 10 files changed, 119 insertions(+), 16 deletions(-) create mode 100644 gui/app/pods/folder/settings/category/controller.js create mode 100644 gui/app/pods/folder/settings/category/route.js create mode 100644 gui/app/pods/folder/settings/category/template.hbs diff --git a/domain/document/mysql/store.go b/domain/document/mysql/store.go index 04db5292..a32025a3 100644 --- a/domain/document/mysql/store.go +++ b/domain/document/mysql/store.go @@ -315,8 +315,8 @@ func (s Scope) MoveDocumentSpace(ctx domain.RequestContext, id, move string) (er return } -// Delete delete the document pages in the database, updates the search subsystem, deletes the associated revisions and attachments, -// audits the deletion, then finally deletes the document itself. +// Delete removes the specified document. +// Remove document pages, revisions, attachments, updates the search subsystem. func (s Scope) Delete(ctx domain.RequestContext, documentID string) (rows int64, err error) { b := mysql.BaseQuery{} rows, err = b.DeleteWhere(ctx.Transaction, fmt.Sprintf("DELETE from page WHERE documentid=\"%s\" AND orgid=\"%s\"", documentID, ctx.OrgID)) @@ -337,3 +337,26 @@ func (s Scope) Delete(ctx domain.RequestContext, documentID string) (rows int64, return b.DeleteConstrained(ctx.Transaction, "document", ctx.OrgID, documentID) } + +// Delete removes all documents for given space. +// Remove document pages, revisions, attachments, updates the search subsystem. +func (s Scope) DeleteBySpace(ctx domain.RequestContext, spaceID string) (rows int64, err error) { + b := mysql.BaseQuery{} + rows, err = b.DeleteWhere(ctx.Transaction, fmt.Sprintf("DELETE from page WHERE labelid=\"%s\" AND orgid=\"%s\"", spaceID, ctx.OrgID)) + + if err != nil { + return + } + + _, err = b.DeleteWhere(ctx.Transaction, fmt.Sprintf("DELETE from revision WHERE labelid=\"%s\" AND orgid=\"%s\"", spaceID, ctx.OrgID)) + if err != nil { + return + } + + _, err = b.DeleteWhere(ctx.Transaction, fmt.Sprintf("DELETE from attachment WHERE labelid=\"%s\" AND orgid=\"%s\"", spaceID, ctx.OrgID)) + if err != nil { + return + } + + return b.DeleteConstrained(ctx.Transaction, "document", ctx.OrgID, spaceID) +} diff --git a/domain/space/endpoint.go b/domain/space/endpoint.go index 30677b20..2e000a9b 100644 --- a/domain/space/endpoint.go +++ b/domain/space/endpoint.go @@ -474,7 +474,7 @@ func (h *Handler) Remove(w http.ResponseWriter, r *http.Request) { response.WriteEmpty(w) } -// Delete deletes empty space. +// Delete removes space. func (h *Handler) Delete(w http.ResponseWriter, r *http.Request) { method := "space.Delete" ctx := domain.GetRequestContext(r) @@ -503,6 +503,14 @@ func (h *Handler) Delete(w http.ResponseWriter, r *http.Request) { return } + _, err = h.Store.Document.DeleteBySpace(ctx, id) + if err != nil { + ctx.Transaction.Rollback() + response.WriteServerError(w, method, err) + h.Runtime.Log.Error(method, err) + return + } + _, err = h.Store.Space.Delete(ctx, id) if err != nil { ctx.Transaction.Rollback() diff --git a/domain/space/mysql/store.go b/domain/space/mysql/store.go index af00bd81..34f571fb 100644 --- a/domain/space/mysql/store.go +++ b/domain/space/mysql/store.go @@ -244,8 +244,7 @@ func (s Scope) GetPermissions(ctx domain.RequestContext, spaceID string) (r []sp func (s Scope) DeletePermissions(ctx domain.RequestContext, spaceID string) (rows int64, err error) { b := mysql.BaseQuery{} - sql := fmt.Sprintf("DELETE FROM permission WHERE orgid='%s' AND location='space' AND refid='%s'", - ctx.OrgID, spaceID) + sql := fmt.Sprintf("DELETE FROM permission WHERE orgid='%s' AND location='space' AND refid='%s'", ctx.OrgID, spaceID) return b.DeleteWhere(ctx.Transaction, sql) } diff --git a/domain/storer.go b/domain/storer.go index 04729e76..47218885 100644 --- a/domain/storer.go +++ b/domain/storer.go @@ -141,6 +141,7 @@ type DocumentStorer interface { ChangeDocumentSpace(ctx RequestContext, document, space string) (err error) MoveDocumentSpace(ctx RequestContext, id, move string) (err error) Delete(ctx RequestContext, documentID string) (rows int64, err error) + DeleteBySpace(ctx RequestContext, spaceID string) (rows int64, err error) } // SettingStorer defines required methods for persisting global and user level settings diff --git a/gui/app/components/folder/folder-toolbar.js b/gui/app/components/folder/folder-toolbar.js index b5902b7a..e8c12e80 100644 --- a/gui/app/components/folder/folder-toolbar.js +++ b/gui/app/components/folder/folder-toolbar.js @@ -33,6 +33,7 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, AuthMixin, { pinId: '', newName: '', }, + deleteSpaceName: '', didReceiveAttrs() { let targets = _.reject(this.get('folders'), { @@ -108,6 +109,23 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, AuthMixin, { this.attrs.onDeleteDocument(); }, + deleteSpace() { + let spaceName = this.get('folder').get('name'); + let spaceNameTyped = this.get('deleteSpaceName'); + + if (spaceNameTyped !== spaceName || spaceNameTyped === '' || spaceName === '') { + $("#delete-space-name").addClass("error").focus(); + return false; + } + + this.set('deleteSpaceName', ''); + $("#delete-space-name").removeClass("error"); + + this.attrs.onDeleteSpace(); + + return true; + }, + setMoveFolder(folderId) { this.set('moveFolderId', folderId); diff --git a/gui/app/pods/folder/index/template.hbs b/gui/app/pods/folder/index/template.hbs index 321282d0..faa4d54a 100644 --- a/gui/app/pods/folder/index/template.hbs +++ b/gui/app/pods/folder/index/template.hbs @@ -8,7 +8,8 @@ {{folder/folder-toolbar folders=model.folders folder=model.folder permissions=model.permissions hasSelectedDocuments=hasSelectedDocuments - onDeleteDocument=(action 'onDeleteDocument') onMoveDocument=(action 'onMoveDocument')}} + onDeleteDocument=(action 'onDeleteDocument') onMoveDocument=(action 'onMoveDocument') + onDeleteSpace=(action 'onDeleteSpace')}} {{folder/documents-list documents=model.documents folders=model.folders folder=model.folder templates=model.templates permissions=model.permissions selectedDocuments=(mut selectedDocuments) diff --git a/gui/app/pods/folder/settings/category/controller.js b/gui/app/pods/folder/settings/category/controller.js new file mode 100644 index 00000000..bef4c71c --- /dev/null +++ b/gui/app/pods/folder/settings/category/controller.js @@ -0,0 +1,15 @@ +// Copyright 2016 Documize Inc. . 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 . +// +// https://documize.com + +import Ember from 'ember'; + +export default Ember.Controller.extend({ +}); diff --git a/gui/app/pods/folder/settings/category/route.js b/gui/app/pods/folder/settings/category/route.js new file mode 100644 index 00000000..c289356a --- /dev/null +++ b/gui/app/pods/folder/settings/category/route.js @@ -0,0 +1,25 @@ +// Copyright 2016 Documize Inc. . 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 . +// +// https://documize.com + +import Ember from 'ember'; +import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin'; + +export default Ember.Route.extend(AuthenticatedRouteMixin, { + model() { + this.get('browser').setTitle(this.modelFor('folder').folder.get('name')); + + return Ember.RSVP.hash({ + folder: this.modelFor('folder').folder, + permissions: this.modelFor('folder').permissions, + folders: this.modelFor('folder').folders + }); + } +}); diff --git a/gui/app/pods/folder/settings/category/template.hbs b/gui/app/pods/folder/settings/category/template.hbs new file mode 100644 index 00000000..64fad17d --- /dev/null +++ b/gui/app/pods/folder/settings/category/template.hbs @@ -0,0 +1 @@ +{{folder/invite-user folders=model.folders folder=model.folder}} diff --git a/gui/app/templates/components/folder/folder-toolbar.hbs b/gui/app/templates/components/folder/folder-toolbar.hbs index 3cb48824..7a8f68c9 100644 --- a/gui/app/templates/components/folder/folder-toolbar.hbs +++ b/gui/app/templates/components/folder/folder-toolbar.hbs @@ -35,7 +35,18 @@ {{else}} + {{#if pinState.isPinned}} +
+ favorite +
+ {{else}} +
+ favorite_border +
+ {{/if}} + {{#if permissions.spaceManage}} +
{{#link-to 'folder.settings' folder.id folder.slug}}{{model.document.name}}
settings @@ -50,16 +61,7 @@
{{/if}} - {{#if pinState.isPinned}} -
-
- favorite -
- {{else}} -
-
- favorite_border -
+ {{#unless pinState.isPinned}} {{#dropdown-dialog target="space-pin-button" position="bottom right" button="Pin" color="flat-green" onAction=(action 'onPin') focusOn="pin-space-name" }}
@@ -67,6 +69,16 @@ {{input type='text' id="pin-space-name" value=pinState.newName}}
{{/dropdown-dialog}} + {{/unless}} + + {{#if permissions.spaceOwner}} + {{#dropdown-dialog target="space-delete-button" position="bottom right" button="Delete" color="flat-red" onAction=(action 'deleteSpace')}} +

Are you sure you want this space and all associated documents?

+
+
Please type the space name to confirm
+ {{input type='text' id="delete-space-name" value=deleteSpaceName}} +
+ {{/dropdown-dialog}} {{/if}} {{/if}}