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

add section empty state

This commit is contained in:
Harvey Kandola 2017-03-04 16:54:04 +00:00
parent a7ac034d2c
commit 8d2dcf376f
12 changed files with 80 additions and 248 deletions

View file

@ -21,7 +21,7 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
didReceiveAttrs() {
let toEdit = this.get('toEdit');
if (toEdit === this.get('page.id')) {
if (toEdit === this.get('page.id') && this.get('isEditor')) {
this.send('onEdit');
}
},

View file

@ -22,7 +22,7 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
sectionService: Ember.inject.service('section'),
appMeta: Ember.inject.service(),
link: Ember.inject.service(),
hasPages: computed.notEmpty('pages'),
newSectionName: '',
newSectionNameMissing: computed.empty('newSectionName'),
newSectionLocation: '',
@ -38,6 +38,7 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
this.set('blocks', blocks);
this.set('hasBlocks', blocks.get('length') > 0);
// to test
blocks.forEach((b) => {
b.set('deleteId', `delete-block-button-${b.id}`);
});
@ -54,12 +55,12 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
},
didInsertElement() {
$(".start-section").hoverIntent({interval: 100, over: function() {
$(".start-section:not(.start-section-empty-state)").hoverIntent({interval: 100, over: function() {
// in
$(this).find('.start-button').css("display", "block").removeClass('fadeOut').addClass('fadeIn');
$(this).find('.start-button').velocity("transition.slideDownIn", {duration: 300});
}, out: function() {
//out
$(this).find('.start-button').css("display", "none").removeClass('fadeIn').addClass('fadeOut');
// out
$(this).find('.start-button').velocity("transition.slideUpOut", {duration: 300});
} });
},
@ -109,12 +110,15 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
if (is.not.null(beforePage)) {
// get any page before the beforePage so we can insert this new section between them
let index = _.findIndex(this.get('pages'), function(p) { return p.get('id') === beforePage.get('id'); });
let beforeBeforePage = this.get('pages')[index-1];
if (is.not.undefined(beforeBeforePage)) {
sequence = (beforePage.get('sequence') + beforeBeforePage.get('sequence')) / 2;
} else {
sequence = beforePage.get('sequence') / 2;
if (index !== -1) {
let beforeBeforePage = this.get('pages')[index-1];
if (is.not.undefined(beforeBeforePage)) {
sequence = (beforePage.get('sequence') + beforeBeforePage.get('sequence')) / 2;
} else {
sequence = beforePage.get('sequence') / 2;
}
}
}
@ -124,7 +128,7 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
const promise = this.get('onInsertSection')(model);
promise.then((id) => {
if (model.page.contentType === 'section') {
if (model.page.pageType === 'section') {
this.set('toEdit', id);
} else {
this.get('onEditSection')(id);
@ -154,17 +158,26 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
},
// Section wizard related
onShowSectionWizard(page) {
let beforePage = this.get('beforePage');
if (is.undefined(page)) {
page = { id: '0' };
}
let beforePage = this.get('beforePage');
if (is.not.null(beforePage) && $("#new-section-wizard").is(':visible') && beforePage.get('id') === page.id) {
this.send('onHideSectionWizard');
return;
}
this.set('newSectionLocation', page.id);
this.set('beforePage', page);
if (page.id === '0') {
// this handles add section at the end of the document
// because we are not before another page
this.set('beforePage', null);
} else {
this.set('beforePage', page);
}
$("#new-section-wizard").insertAfter(`#add-section-button-${page.id}`);
$("#new-section-wizard").velocity("transition.slideDownIn", {duration: 300, complete:
@ -250,7 +263,6 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
// to test
onDeleteBlock(id) {
this.attrs.onDeleteBlock(id);
},
}
}
});

View file

@ -1,67 +0,0 @@
// 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 NotifierMixin from '../../mixins/notifier';
export default Ember.Component.extend(NotifierMixin, {
display: 'section', // which CSS to use
hasTemplates: false,
hasBlocks: false,
blockMode: false,
didReceiveAttrs() {
let blocks = this.get('blocks');
let blockMode = is.not.undefined(blocks);
this.set('blockMode', blockMode);
if (!blockMode) {
return;
}
this.set('hasBlocks', blocks.get('length') > 0);
blocks.forEach((b) => {
b.set('deleteId', `delete-block-button-${b.id}`);
});
},
didRender() {
let self = this;
Mousetrap.bind('esc', function () {
if (self.get('isDestroyed') || self.get('isDestroying')) {
return;
}
self.send('onCancel');
return false;
});
},
actions: {
onCancel() {
this.attrs.onCancel();
},
addSection(section) {
this.attrs.onAddSection(section);
},
onDeleteBlock(id) {
this.attrs.onDeleteBlock(id);
},
onInsertBlock(block) {
this.attrs.onInsertBlock(block);
}
}
});

View file

@ -40,7 +40,7 @@
</div>
<div id="page-content-wrapper">
<div class="container">
<div class="{{if toggled 'container' 'container-fluid'}}">
<div class="row">
<div class="col-lg-12">
{{#if toggled}}

View file

@ -1,54 +0,0 @@
import Ember from 'ember';
import NotifierMixin from '../../../mixins/notifier';
export default Ember.Controller.extend(NotifierMixin, {
documentService: Ember.inject.service('document'),
actions: {
onCancel() {
this.transitionToRoute('document');
},
onAddSection(section) {
this.audit.record("added-section-" + section.get('contentType'));
let page = {
documentId: this.get('model.document.id'),
title: `${section.get('title')}`,
level: 1,
sequence: 0,
body: "",
contentType: section.get('contentType'),
pageType: section.get('pageType')
};
let meta = {
documentId: this.get('model.document.id'),
rawBody: "",
config: "",
externaleSource: true
};
let model = {
page: page,
meta: meta
};
this.get('documentService').addPage(this.get('model.document.id'), model).then((newPage) => {
let data = this.get('store').normalize('page', newPage);
this.get('store').push(data);
this.get('documentService').getPages(this.get('model.document.id')).then((pages) => {
this.set('model.pages', pages.filterBy('pageType', 'section'));
this.set('model.tabs', pages.filterBy('pageType', 'tab'));
this.get('documentService').getPageMeta(this.get('model.document.id'), newPage.id).then(() => {
let options = {};
options['mode'] = 'edit';
this.transitionToRoute('document.section', newPage.id, { queryParams: options });
});
});
});
}
}
});

View file

@ -1,21 +0,0 @@
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() {
return Ember.RSVP.hash({
folders: this.modelFor('document').folders,
folder: this.modelFor('document').folder,
document: this.modelFor('document').document,
pages: this.modelFor('document').pages,
tabs: this.modelFor('document').tabs,
sections: this.get('sectionService').getAll().then(function (sections) {
return sections.filterBy('pageType', 'tab');
})
});
}
});

View file

@ -1 +0,0 @@
{{document/page-wizard display='tab' document=model.document folder=model.folder sections=model.sections onCancel=(action 'onCancel') onAddSection=(action 'onAddSection')}}

View file

@ -151,7 +151,6 @@
}
.start-section {
@include ease-in();
@extend .no-select;
height: 60px;
background-color: transparent;
@ -194,6 +193,12 @@
}
}
.start-section-empty-state {
> .start-button {
display: block;
}
}
.new-section-wizard {
@include border-radius(2px);
margin: 0 0 30px 0;

View file

@ -1,35 +1,51 @@
<div class="document-view">
{{#each pages key="id" as |page index|}}
{{#if hasPages}}
{{#each pages key="id" as |page index|}}
{{#if isEditor}}
<div class="start-section" data-index={{index}} data-before-id={{page.id}} id="add-section-button-{{page.id}}" {{action 'onShowSectionWizard' page}}>
<div class="start-button">
<div class="round-button round-button-small button-green">
<i class="material-icons">add</i>
</div>
<div class="label">section</div>
</div>
</div>
{{else}}
<div class="section-divider" />
{{/if}}
{{#if (is-equal page.pageType 'section')}}
{{#document/document-page document=document folder=folder page=page isEditor=isEditor toEdit=toEdit
onSavePage=(action 'onSavePage') onSavePageAsBlock=(action 'onSavePageAsBlock')
onCopyPage=(action 'onCopyPage') onMovePage=(action 'onMovePage') onDeletePage=(action 'onDeletePage')}}
{{/document/document-page}}
{{/if}}
{{#if (is-equal page.pageType 'tab')}}
{{#document/document-tab document=document folder=folder page=page isEditor=isEditor
onSavePage=(action 'onSavePage') onSavePageAsBlock=(action 'onSavePageAsBlock')
onCopyPage=(action 'onCopyPage') onMovePage=(action 'onMovePage') onDeletePage=(action 'onDeletePage')}}
{{/document/document-tab}}
{{/if}}
{{/each}}
<div class="start-section" data-index="0" data-before-id="0" id="add-section-button-0" {{action 'onShowSectionWizard'}}>
<div class="start-button">
<div class="round-button round-button-small button-green">
<i class="material-icons">add</i>
</div>
<div class="label">section</div>
</div>
</div>
{{else}}
{{#if isEditor}}
<div class="start-section" data-index={{index}} data-before-id={{page.id}} id="add-section-button-{{page.id}}" {{action 'onShowSectionWizard' page}}>
<div class="start-button animated">
<div class="start-section start-section-empty-state" data-index="-1" data-before-id="0" id="add-section-button-0" {{action 'onShowSectionWizard'}}>
<div class="start-button">
<div class="round-button round-button-small button-green">
<i class="material-icons">add</i>
</div>
<div class="label">section</div>
</div>
</div>
{{else}}
<div class="section-divider" />
{{/if}}
{{#if (is-equal page.pageType 'section')}}
{{#document/document-page document=document folder=folder page=page isEditor=isEditor toEdit=toEdit
onSavePage=(action 'onSavePage') onSavePageAsBlock=(action 'onSavePageAsBlock')
onCopyPage=(action 'onCopyPage') onMovePage=(action 'onMovePage') onDeletePage=(action 'onDeletePage')}}
{{/document/document-page}}
{{/if}}
{{#if (is-equal page.pageType 'tab')}}
{{#document/document-tab document=document folder=folder page=page isEditor=isEditor
onSavePage=(action 'onSavePage') onSavePageAsBlock=(action 'onSavePageAsBlock')
onCopyPage=(action 'onCopyPage') onMovePage=(action 'onMovePage') onDeletePage=(action 'onDeletePage')}}
{{/document/document-tab}}
{{/if}}
{{else}}
no sections!
<div class="empty-state-document">
<img src="/assets/img/empty-state-document.gif" />
</div>
{{/each}}
{{/if}}
<div id="new-section-wizard" class="new-section-wizard">
<div class="input-inline input-transparent pull-left width-80">

View file

@ -1,63 +0,0 @@
<div class="{{display}}-wizard">
<div class="canvas">
<ul class="list">
{{#each sections as |section|}}
<li class="item" {{action 'addSection' section}}>
<div class="icon">
<img class="img" src="/sections/{{section.contentType}}.png" srcset="/sections/{{section.contentType}}@2x.png" />
</div>
<div class="details">
<div class='title'>
{{section.title}}
{{#if section.preview}}
<div class="preview">coming soon</div>
{{/if}}
</div>
<div class='desc'>{{section.description}}</div>
</div>
<div class="clearfix" />
</li>
{{/each}}
</ul>
{{#if blockMode}}
{{#if hasBlocks}}
<div class="divider"></div>
<div class="template-caption">Reusable content</div>
<ul class="list">
{{#each blocks as |block|}}
<li class="item min-height">
<div class="icon">
<div class="symbol" {{action 'onInsertBlock' block}}>
<i class="material-icons">view_agenda</i>
</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}}
<i class="material-icons" id={{block.deleteId}}>delete</i>
</div>
</div>
<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="clearfix" />
{{#dropdown-dialog target=block.deleteId position="bottom left" 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>
{{/each}}
</ul>
{{else}}
<div class="divider"></div>
<div class="template-caption">Reusable content appears below</div>
{{/if}}
{{/if}}
</div>
</div>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

View file

@ -12,6 +12,7 @@
package endpoint
import (
"database/sql"
"encoding/json"
"io/ioutil"
"net/http"
@ -121,6 +122,10 @@ func RefreshSections(w http.ResponseWriter, r *http.Request) {
// Grab the page because we need content type and
page, err2 := p.GetPage(pm.PageID)
if err2 == sql.ErrNoRows {
continue
}
if err2 != nil {
writeGeneralSQLError(w, method, err2)
log.IfErr(tx.Rollback())