Refactor app.views.AspectMembership
in order to support adding new aspect to a dropdown without full page reload
This commit is contained in:
parent
15e0f88758
commit
923fb8a763
44 changed files with 526 additions and 285 deletions
|
|
@ -120,9 +120,6 @@ var app = {
|
||||||
|
|
||||||
setupGlobalViews: function() {
|
setupGlobalViews: function() {
|
||||||
app.hovercard = new app.views.Hovercard();
|
app.hovercard = new app.views.Hovercard();
|
||||||
$('.aspect_membership_dropdown').each(function(){
|
|
||||||
new app.views.AspectMembership({el: this});
|
|
||||||
});
|
|
||||||
app.sidebar = new app.views.Sidebar();
|
app.sidebar = new app.views.Sidebar();
|
||||||
app.backToTop = new app.views.BackToTop({el: $(document)});
|
app.backToTop = new app.views.BackToTop({el: $(document)});
|
||||||
app.flashMessages = new app.views.FlashMessages({el: $("#flash-container")});
|
app.flashMessages = new app.views.FlashMessages({el: $("#flash-container")});
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,10 @@
|
||||||
// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3-or-Later
|
// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3-or-Later
|
||||||
|
|
||||||
app.collections.AspectMemberships = Backbone.Collection.extend({
|
app.collections.AspectMemberships = Backbone.Collection.extend({
|
||||||
model: app.models.AspectMembership
|
model: app.models.AspectMembership,
|
||||||
|
|
||||||
|
findByAspectId: function(id) {
|
||||||
|
return this.find(function(membership) { return membership.belongsToAspect(id); });
|
||||||
|
}
|
||||||
});
|
});
|
||||||
// @license-end
|
// @license-end
|
||||||
|
|
|
||||||
7
app/assets/javascripts/app/collections/aspects.js
Normal file
7
app/assets/javascripts/app/collections/aspects.js
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3-or-Later
|
||||||
|
|
||||||
|
app.collections.Aspects = Backbone.Collection.extend({
|
||||||
|
model: app.models.Aspect,
|
||||||
|
url: "/aspects"
|
||||||
|
});
|
||||||
|
// @license-end
|
||||||
|
|
@ -5,6 +5,11 @@
|
||||||
* (only valid for the context of the current user)
|
* (only valid for the context of the current user)
|
||||||
*/
|
*/
|
||||||
app.models.AspectMembership = Backbone.Model.extend({
|
app.models.AspectMembership = Backbone.Model.extend({
|
||||||
urlRoot: "/aspect_memberships"
|
urlRoot: "/aspect_memberships",
|
||||||
|
|
||||||
|
belongsToAspect: function(aspectId) {
|
||||||
|
var aspect = this.get("aspect");
|
||||||
|
return aspect && aspect.id === aspectId;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
// @license-end
|
// @license-end
|
||||||
|
|
|
||||||
|
|
@ -3,11 +3,14 @@
|
||||||
app.models.Contact = Backbone.Model.extend({
|
app.models.Contact = Backbone.Model.extend({
|
||||||
initialize : function() {
|
initialize : function() {
|
||||||
this.aspectMemberships = new app.collections.AspectMemberships(this.get("aspect_memberships"));
|
this.aspectMemberships = new app.collections.AspectMemberships(this.get("aspect_memberships"));
|
||||||
if(this.get("person")) { this.person = new app.models.Person(this.get("person")); }
|
if (this.get("person")) {
|
||||||
|
this.person = new app.models.Person(this.get("person"));
|
||||||
|
this.person.contact = this;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
inAspect : function(id) {
|
inAspect : function(id) {
|
||||||
return this.aspectMemberships.any(function(membership){ return membership.get("aspect").id === id; });
|
return this.aspectMemberships.any(function(membership) { return membership.belongsToAspect(id); });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// @license-end
|
// @license-end
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,13 @@ app.models.Person = Backbone.Model.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
initialize: function() {
|
initialize: function() {
|
||||||
if( this.get('profile') )
|
if (this.get("profile")) {
|
||||||
this.profile = new app.models.Profile(this.get('profile'));
|
this.profile = new app.models.Profile(this.get("profile"));
|
||||||
|
}
|
||||||
|
if (this.get("contact")) {
|
||||||
|
this.contact = new app.models.Contact(this.get("contact"));
|
||||||
|
this.contact.person = this;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
isSharing: function() {
|
isSharing: function() {
|
||||||
|
|
|
||||||
20
app/assets/javascripts/app/pages/getting_started.js
Normal file
20
app/assets/javascripts/app/pages/getting_started.js
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3-or-Later
|
||||||
|
app.pages.GettingStarted = app.views.Base.extend({
|
||||||
|
el: "#hello-there",
|
||||||
|
|
||||||
|
templateName: false,
|
||||||
|
|
||||||
|
subviews: {
|
||||||
|
".aspect_membership_dropdown": "aspectMembershipView"
|
||||||
|
},
|
||||||
|
|
||||||
|
initialize: function(opts) {
|
||||||
|
this.inviter = opts.inviter;
|
||||||
|
app.events.on("aspect:create", this.render, this);
|
||||||
|
},
|
||||||
|
|
||||||
|
aspectMembershipView: function() {
|
||||||
|
return new app.views.AspectMembership({person: this.inviter, dropdownMayCreateNewAspect: true});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// @license-end
|
||||||
|
|
@ -5,6 +5,7 @@ app.Router = Backbone.Router.extend({
|
||||||
"help/:section": "help",
|
"help/:section": "help",
|
||||||
"help/": "help",
|
"help/": "help",
|
||||||
"help": "help",
|
"help": "help",
|
||||||
|
"getting_started": "gettingStarted",
|
||||||
"contacts": "contacts",
|
"contacts": "contacts",
|
||||||
"conversations": "conversations",
|
"conversations": "conversations",
|
||||||
"user/edit": "settings",
|
"user/edit": "settings",
|
||||||
|
|
@ -60,6 +61,7 @@ app.Router = Backbone.Router.extend({
|
||||||
contacts: function() {
|
contacts: function() {
|
||||||
app.aspect = new app.models.Aspect(gon.preloads.aspect);
|
app.aspect = new app.models.Aspect(gon.preloads.aspect);
|
||||||
app.contacts = new app.collections.Contacts(app.parsePreload("contacts"));
|
app.contacts = new app.collections.Contacts(app.parsePreload("contacts"));
|
||||||
|
this._loadAspects();
|
||||||
|
|
||||||
var stream = new app.views.ContactStream({
|
var stream = new app.views.ContactStream({
|
||||||
collection: app.contacts,
|
collection: app.contacts,
|
||||||
|
|
@ -69,6 +71,13 @@ app.Router = Backbone.Router.extend({
|
||||||
app.page = new app.pages.Contacts({stream: stream});
|
app.page = new app.pages.Contacts({stream: stream});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
gettingStarted: function() {
|
||||||
|
this._loadAspects();
|
||||||
|
this.renderPage(function() {
|
||||||
|
return new app.pages.GettingStarted({inviter: new app.models.Person(app.parsePreload("inviter"))});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
conversations: function() {
|
conversations: function() {
|
||||||
app.conversations = new app.views.Conversations();
|
app.conversations = new app.views.Conversations();
|
||||||
},
|
},
|
||||||
|
|
@ -134,6 +143,7 @@ app.Router = Backbone.Router.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
aspects: function() {
|
aspects: function() {
|
||||||
|
this._loadAspects();
|
||||||
app.aspectSelections = app.aspectSelections ||
|
app.aspectSelections = app.aspectSelections ||
|
||||||
new app.collections.AspectSelections(app.currentUser.get("aspects"));
|
new app.collections.AspectSelections(app.currentUser.get("aspects"));
|
||||||
this.aspectsList = this.aspectsList || new app.views.AspectsList({collection: app.aspectSelections});
|
this.aspectsList = this.aspectsList || new app.views.AspectsList({collection: app.aspectSelections});
|
||||||
|
|
@ -157,6 +167,7 @@ app.Router = Backbone.Router.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
profile: function() {
|
profile: function() {
|
||||||
|
this._loadAspects();
|
||||||
this.renderPage(function() {
|
this.renderPage(function() {
|
||||||
return new app.pages.Profile({
|
return new app.pages.Profile({
|
||||||
el: $("body > #profile_container")
|
el: $("body > #profile_container")
|
||||||
|
|
@ -164,6 +175,10 @@ app.Router = Backbone.Router.extend({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_loadAspects: function() {
|
||||||
|
app.aspects = new app.collections.Aspects(app.currentUser.get("aspects"));
|
||||||
|
},
|
||||||
|
|
||||||
_hideInactiveStreamLists: function() {
|
_hideInactiveStreamLists: function() {
|
||||||
if(this.aspectsList && Backbone.history.fragment !== "aspects") {
|
if(this.aspectsList && Backbone.history.fragment !== "aspects") {
|
||||||
this.aspectsList.hideAspectsList();
|
this.aspectsList.hideAspectsList();
|
||||||
|
|
|
||||||
|
|
@ -9,20 +9,18 @@ app.views.AspectCreate = app.views.Base.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
initialize: function(opts) {
|
initialize: function(opts) {
|
||||||
this._personId = _.has(opts, "personId") ? opts.personId : null;
|
if (opts && opts.person) {
|
||||||
|
this.person = opts.person;
|
||||||
|
this._personId = opts.person.id;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
presenter: function() {
|
presenter: function() {
|
||||||
return _.extend(this.defaultPresenter(), {
|
return _.extend(this.defaultPresenter(), {
|
||||||
addPersonId: this._personId !== null,
|
|
||||||
personId : this._personId
|
personId : this._personId
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
postRenderTemplate: function() {
|
|
||||||
this.modal = this.$(".modal");
|
|
||||||
},
|
|
||||||
|
|
||||||
_contactsVisible: function() {
|
_contactsVisible: function() {
|
||||||
return this.$("#aspect_contacts_visible").is(":checked");
|
return this.$("#aspect_contacts_visible").is(":checked");
|
||||||
},
|
},
|
||||||
|
|
@ -38,28 +36,52 @@ app.views.AspectCreate = app.views.Base.extend({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
createAspect: function() {
|
postRenderTemplate: function() {
|
||||||
var aspect = new app.models.Aspect({
|
this.$(".modal").on("hidden.bs.modal", null, this, function(e) {
|
||||||
"person_id": this._personId,
|
e.data.ensureEventsOrder();
|
||||||
"name": this._name(),
|
|
||||||
"contacts_visible": this._contactsVisible()
|
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
|
||||||
var self = this;
|
createAspect: function() {
|
||||||
aspect.on("sync", function(response) {
|
this._eventsCounter = 0;
|
||||||
var aspectId = response.get("id"),
|
|
||||||
aspectName = response.get("name");
|
|
||||||
|
|
||||||
self.modal.modal("hide");
|
this.$(".modal").modal("hide");
|
||||||
app.events.trigger("aspect:create", aspectId);
|
|
||||||
|
this.listenToOnce(app.aspects, "sync", function(response) {
|
||||||
|
var aspectName = response.get("name"),
|
||||||
|
membership = response.get("aspect_membership");
|
||||||
|
|
||||||
|
this._newAspectId = response.get("id");
|
||||||
|
|
||||||
|
if (membership) {
|
||||||
|
if (!this.person.contact) {
|
||||||
|
this.person.contact = new app.models.Contact();
|
||||||
|
}
|
||||||
|
this.person.contact.aspectMemberships.add([membership]);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.ensureEventsOrder();
|
||||||
app.flashMessages.success(Diaspora.I18n.t("aspects.create.success", {"name": aspectName}));
|
app.flashMessages.success(Diaspora.I18n.t("aspects.create.success", {"name": aspectName}));
|
||||||
});
|
});
|
||||||
|
|
||||||
aspect.on("error", function() {
|
this.listenToOnce(app.aspects, "error", function() {
|
||||||
self.modal.modal("hide");
|
|
||||||
app.flashMessages.error(Diaspora.I18n.t("aspects.create.failure"));
|
app.flashMessages.error(Diaspora.I18n.t("aspects.create.failure"));
|
||||||
|
this.stopListening(app.aspects, "sync");
|
||||||
});
|
});
|
||||||
return aspect.save();
|
|
||||||
|
app.aspects.create({
|
||||||
|
"person_id": this._personId || null,
|
||||||
|
"name": this._name(),
|
||||||
|
"contacts_visible": this._contactsVisible()
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// ensure that we trigger the aspect:create event only after both hidden.bs.modal and and aspects sync happens
|
||||||
|
ensureEventsOrder: function() {
|
||||||
|
this._eventsCounter++;
|
||||||
|
if (this._eventsCounter > 1) {
|
||||||
|
app.events.trigger("aspect:create", this._newAspectId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// @license-end
|
// @license-end
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,5 @@
|
||||||
// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3-or-Later
|
// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3-or-Later
|
||||||
|
|
||||||
//= require ./aspects_dropdown_view
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* this view lets the user (de-)select aspect memberships in the context
|
* this view lets the user (de-)select aspect memberships in the context
|
||||||
* of another users profile or the contact page.
|
* of another users profile or the contact page.
|
||||||
|
|
@ -9,7 +7,13 @@
|
||||||
* updates to the list of aspects are immediately propagated to the server, and
|
* updates to the list of aspects are immediately propagated to the server, and
|
||||||
* the results are dislpayed as flash messages.
|
* the results are dislpayed as flash messages.
|
||||||
*/
|
*/
|
||||||
app.views.AspectMembership = app.views.AspectsDropdown.extend({
|
app.views.AspectMembership = app.views.Base.extend({
|
||||||
|
templateName: "aspect_membership_dropdown",
|
||||||
|
className: "btn-group aspect_dropdown aspect_membership_dropdown",
|
||||||
|
|
||||||
|
subviews: {
|
||||||
|
".newAspectContainer": "aspectCreateView"
|
||||||
|
},
|
||||||
|
|
||||||
events: {
|
events: {
|
||||||
"click ul.aspect_membership.dropdown-menu > li.aspect_selector"
|
"click ul.aspect_membership.dropdown-menu > li.aspect_selector"
|
||||||
|
|
@ -18,70 +22,89 @@ app.views.AspectMembership = app.views.AspectsDropdown.extend({
|
||||||
: "_clickHandler"
|
: "_clickHandler"
|
||||||
},
|
},
|
||||||
|
|
||||||
initialize: function() {
|
initialize: function(opts) {
|
||||||
|
_.extend(this, opts);
|
||||||
this.list_item = null;
|
this.list_item = null;
|
||||||
this.dropdown = null;
|
this.dropdown = null;
|
||||||
if (this.$(".newAspectContainer").length > 0) {
|
},
|
||||||
this.aspectCreateView = new app.views.AspectCreate({
|
|
||||||
el: this.$(".newAspectContainer"),
|
presenter: function() {
|
||||||
personId: this.$("ul.dropdown-menu").data("person_id")
|
var aspectMembershipsLength = this.person.contact ? this.person.contact.aspectMemberships.length : 0;
|
||||||
});
|
|
||||||
this.aspectCreateView.render();
|
return _.extend(this.defaultPresenter(), {
|
||||||
}
|
aspects: this.aspectsPresenter(),
|
||||||
|
dropdownMayCreateNewAspect: this.dropdownMayCreateNewAspect
|
||||||
|
}, aspectMembershipsLength === 0 ? {
|
||||||
|
extraButtonClass: "btn-default",
|
||||||
|
noAspectIsSelected: true
|
||||||
|
} : { // this.contact.aspectMemberships.length > 0
|
||||||
|
aspectMembershipsLength: aspectMembershipsLength,
|
||||||
|
allAspectsAreSelected: aspectMembershipsLength === app.aspects.length,
|
||||||
|
onlyOneAspectIsSelected: aspectMembershipsLength === 1,
|
||||||
|
firstMembershipName: this.person.contact.aspectMemberships.at(0).get("aspect").name,
|
||||||
|
extraButtonClass: "btn-success"
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
aspectsPresenter: function() {
|
||||||
|
return _.map(app.aspects.models, function(aspect) {
|
||||||
|
return _.extend(
|
||||||
|
this.person.contact ?
|
||||||
|
{membership: this.person.contact.aspectMemberships.findByAspectId(aspect.attributes.id)} : {},
|
||||||
|
aspect.attributes // id, name
|
||||||
|
);
|
||||||
|
}, this);
|
||||||
|
},
|
||||||
|
|
||||||
|
aspectCreateView: function() {
|
||||||
|
return new app.views.AspectCreate({
|
||||||
|
person: this.person
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
// decide what to do when clicked
|
// decide what to do when clicked
|
||||||
// -> addMembership
|
// -> addMembership
|
||||||
// -> removeMembership
|
// -> removeMembership
|
||||||
_clickHandler: function(evt) {
|
_clickHandler: function(evt) {
|
||||||
var promise = null;
|
|
||||||
this.list_item = $(evt.target).closest('li.aspect_selector');
|
this.list_item = $(evt.target).closest('li.aspect_selector');
|
||||||
this.dropdown = this.list_item.parent();
|
this.dropdown = this.list_item.parent();
|
||||||
|
|
||||||
this.list_item.addClass('loading');
|
this.list_item.addClass('loading');
|
||||||
|
|
||||||
if( this.list_item.is('.selected') ) {
|
if (this.list_item.is(".selected")) {
|
||||||
var membership_id = this.list_item.data('membership_id');
|
this.removeMembership(this.list_item.data("membership_id"));
|
||||||
promise = this.removeMembership(membership_id);
|
|
||||||
} else {
|
} else {
|
||||||
var aspect_id = this.list_item.data('aspect_id');
|
this.addMembership(this.list_item.data("aspect_id"));
|
||||||
var person_id = this.dropdown.data('person_id');
|
|
||||||
promise = this.addMembership(person_id, aspect_id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
promise && promise.always(function() {
|
|
||||||
// trigger a global event
|
|
||||||
app.events.trigger('aspect_membership:update');
|
|
||||||
});
|
|
||||||
|
|
||||||
return false; // stop the event
|
return false; // stop the event
|
||||||
},
|
},
|
||||||
|
|
||||||
// return the (short) name of the person associated with the current dropdown
|
// return the (short) name of the person associated with the current dropdown
|
||||||
_name: function() {
|
_name: function() {
|
||||||
return this.dropdown.data('person-short-name');
|
return this.person.name || this.person.get("name");
|
||||||
|
},
|
||||||
|
|
||||||
|
_personId: function() {
|
||||||
|
return this.person.id;
|
||||||
},
|
},
|
||||||
|
|
||||||
// create a membership for the given person in the given aspect
|
// create a membership for the given person in the given aspect
|
||||||
addMembership: function(person_id, aspect_id) {
|
addMembership: function(aspectId) {
|
||||||
var aspect_membership = new app.models.AspectMembership({
|
if (!this.person.contact) {
|
||||||
'person_id': person_id,
|
this.person.contact = new app.models.Contact();
|
||||||
'aspect_id': aspect_id
|
}
|
||||||
|
|
||||||
|
this.listenToOnce(this.person.contact.aspectMemberships, "sync", this._successSaveCb);
|
||||||
|
this.listenToOnce(this.person.contact.aspectMemberships, "error", function() {
|
||||||
|
this._displayError('aspect_dropdown.error');
|
||||||
});
|
});
|
||||||
|
|
||||||
aspect_membership.on('sync', this._successSaveCb, this);
|
return this.person.contact.aspectMemberships.create({"aspect_id": aspectId, "person_id": this._personId()});
|
||||||
aspect_membership.on('error', function() {
|
|
||||||
this._displayError('aspect_dropdown.error');
|
|
||||||
}, this);
|
|
||||||
|
|
||||||
return aspect_membership.save();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_successSaveCb: function(aspectMembership) {
|
_successSaveCb: function(aspectMembership) {
|
||||||
var aspectId = aspectMembership.get("aspect_id"),
|
var aspectId = aspectMembership.get("aspect_id"),
|
||||||
membershipId = aspectMembership.get("id"),
|
|
||||||
li = this.dropdown.find("li[data-aspect_id='" + aspectId + "']"),
|
|
||||||
personId = li.closest("ul.dropdown-menu").data("person_id"),
|
|
||||||
startSharing = false;
|
startSharing = false;
|
||||||
|
|
||||||
// the user didn't have this person in any aspects before, congratulate them
|
// the user didn't have this person in any aspects before, congratulate them
|
||||||
|
|
@ -93,15 +116,11 @@ app.views.AspectMembership = app.views.AspectsDropdown.extend({
|
||||||
}
|
}
|
||||||
|
|
||||||
app.events.trigger("aspect_membership:create", {
|
app.events.trigger("aspect_membership:create", {
|
||||||
membership: { aspectId: aspectId, personId: personId },
|
membership: {aspectId: aspectId, personId: this._personId()},
|
||||||
startSharing: startSharing
|
startSharing: startSharing
|
||||||
});
|
});
|
||||||
|
this.render();
|
||||||
li.attr("data-membership_id", membershipId) // just to be sure...
|
app.events.trigger("aspect_membership:update");
|
||||||
.data("membership_id", membershipId);
|
|
||||||
|
|
||||||
this.updateSummary(li);
|
|
||||||
this._done();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// show an error flash msg
|
// show an error flash msg
|
||||||
|
|
@ -114,44 +133,35 @@ app.views.AspectMembership = app.views.AspectsDropdown.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
// remove the membership with the given id
|
// remove the membership with the given id
|
||||||
removeMembership: function(membership_id) {
|
removeMembership: function(membershipId) {
|
||||||
var aspect_membership = new app.models.AspectMembership({
|
var membership = this.person.contact.aspectMemberships.get(membershipId);
|
||||||
'id': membership_id
|
this.listenToOnce(membership, "sync", this._successDestroyCb);
|
||||||
|
this.listenToOnce(membership, "error", function() {
|
||||||
|
this._displayError("aspect_dropdown.error_remove");
|
||||||
});
|
});
|
||||||
|
|
||||||
aspect_membership.on('sync', this._successDestroyCb, this);
|
return membership.destroy();
|
||||||
aspect_membership.on('error', function() {
|
|
||||||
this._displayError('aspect_dropdown.error_remove');
|
|
||||||
}, this);
|
|
||||||
|
|
||||||
return aspect_membership.destroy();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_successDestroyCb: function(aspectMembership) {
|
_successDestroyCb: function(aspectMembership) {
|
||||||
var membershipId = aspectMembership.get("id"),
|
var membershipId = aspectMembership.get("id"),
|
||||||
li = this.dropdown.find("li[data-membership_id='" + membershipId + "']"),
|
aspectId = aspectMembership.get("aspect").id,
|
||||||
aspectId = li.data("aspect_id"),
|
|
||||||
personId = li.closest("ul.dropdown-menu").data("person_id"),
|
|
||||||
stopSharing = false;
|
stopSharing = false;
|
||||||
|
|
||||||
li.removeAttr("data-membership_id")
|
this.render();
|
||||||
.removeData("membership_id");
|
|
||||||
this.updateSummary(li);
|
|
||||||
|
|
||||||
// we just removed the last aspect, inform the user with a flash message
|
// we just removed the last aspect, inform the user with a flash message
|
||||||
// that he is no longer sharing with that person
|
// that he is no longer sharing with that person
|
||||||
if( this.dropdown.find("li.selected").length === 0 ) {
|
if (this.$el.find("li.selected").length === 0) {
|
||||||
var msg = Diaspora.I18n.t("aspect_dropdown.stopped_sharing_with", { "name": this._name() });
|
var msg = Diaspora.I18n.t("aspect_dropdown.stopped_sharing_with", { "name": this._name() });
|
||||||
stopSharing = true;
|
stopSharing = true;
|
||||||
app.flashMessages.success(msg);
|
app.flashMessages.success(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
app.events.trigger("aspect_membership:destroy", {
|
app.events.trigger("aspect_membership:destroy", {
|
||||||
membership: { aspectId: aspectId, personId: personId },
|
membership: {aspectId: aspectId, personId: this._personId()},
|
||||||
stopSharing: stopSharing
|
stopSharing: stopSharing
|
||||||
});
|
});
|
||||||
|
app.events.trigger("aspect_membership:update");
|
||||||
this._done();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// cleanup tasks after aspect selection
|
// cleanup tasks after aspect selection
|
||||||
|
|
@ -160,11 +170,5 @@ app.views.AspectMembership = app.views.AspectsDropdown.extend({
|
||||||
this.list_item.removeClass('loading');
|
this.list_item.removeClass('loading');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// refresh the button text to reflect the current aspect selection status
|
|
||||||
updateSummary: function(target) {
|
|
||||||
this._toggleCheckbox(target);
|
|
||||||
this._updateButton("btn-success");
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
// @license-end
|
// @license-end
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,10 @@
|
||||||
app.views.Contact = app.views.Base.extend({
|
app.views.Contact = app.views.Base.extend({
|
||||||
templateName: 'contact',
|
templateName: 'contact',
|
||||||
|
|
||||||
|
subviews: {
|
||||||
|
".aspect_membership_dropdown": "AspectMembershipView"
|
||||||
|
},
|
||||||
|
|
||||||
events: {
|
events: {
|
||||||
"click .contact_add-to-aspect" : "addContactToAspect",
|
"click .contact_add-to-aspect" : "addContactToAspect",
|
||||||
"click .contact_remove-from-aspect" : "removeContactFromAspect"
|
"click .contact_remove-from-aspect" : "removeContactFromAspect"
|
||||||
|
|
@ -10,6 +14,12 @@ app.views.Contact = app.views.Base.extend({
|
||||||
|
|
||||||
tooltipSelector: '.contact_add-to-aspect, .contact_remove-from-aspect',
|
tooltipSelector: '.contact_add-to-aspect, .contact_remove-from-aspect',
|
||||||
|
|
||||||
|
initialize: function() {
|
||||||
|
this.AspectMembershipView = new app.views.AspectMembership(
|
||||||
|
{person: _.extend(this.model.get("person"), {contact: this.model})}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
presenter: function() {
|
presenter: function() {
|
||||||
return _.extend(this.defaultPresenter(), {
|
return _.extend(this.defaultPresenter(), {
|
||||||
person_id : this.model.get('person_id'),
|
person_id : this.model.get('person_id'),
|
||||||
|
|
@ -18,21 +28,6 @@ app.views.Contact = app.views.Base.extend({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
postRenderTemplate: function() {
|
|
||||||
var dropdownEl = this.$('.aspect_membership_dropdown.placeholder');
|
|
||||||
if( dropdownEl.length === 0 ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO render me client side!!!
|
|
||||||
var href = this.model.person.url() + '/aspect_membership_button?size=small';
|
|
||||||
|
|
||||||
$.get(href, function(resp) {
|
|
||||||
dropdownEl.html(resp);
|
|
||||||
new app.views.AspectMembership({el: $('.aspect_dropdown',dropdownEl)});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
addContactToAspect: function(){
|
addContactToAspect: function(){
|
||||||
var self = this;
|
var self = this;
|
||||||
// do we create the first aspect membership for this person?
|
// do we create the first aspect membership for this person?
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,16 @@
|
||||||
app.views.ProfileHeader = app.views.Base.extend({
|
app.views.ProfileHeader = app.views.Base.extend({
|
||||||
templateName: 'profile_header',
|
templateName: 'profile_header',
|
||||||
|
|
||||||
|
subviews: {
|
||||||
|
".aspect_membership_dropdown": "aspectMembershipView"
|
||||||
|
},
|
||||||
|
|
||||||
events: {
|
events: {
|
||||||
"click #mention_button": "showMentionModal",
|
"click #mention_button": "showMentionModal",
|
||||||
"click #message_button": "showMessageModal"
|
"click #message_button": "showMessageModal"
|
||||||
},
|
},
|
||||||
|
|
||||||
initialize: function(opts) {
|
initialize: function(opts) {
|
||||||
app.events.on('aspect:create', this.postRenderTemplate, this);
|
|
||||||
this.photos = _.has(opts, 'photos') ? opts.photos : null;
|
this.photos = _.has(opts, 'photos') ? opts.photos : null;
|
||||||
this.contacts = _.has(opts, 'contacts') ? opts.contacts : null;
|
this.contacts = _.has(opts, 'contacts') ? opts.contacts : null;
|
||||||
},
|
},
|
||||||
|
|
@ -29,6 +32,10 @@ app.views.ProfileHeader = app.views.Base.extend({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
aspectMembershipView: function() {
|
||||||
|
return new app.views.AspectMembership({person: this.model, dropdownMayCreateNewAspect: true});
|
||||||
|
},
|
||||||
|
|
||||||
_hasTags: function() {
|
_hasTags: function() {
|
||||||
return (this.model.get('profile')['tags'].length > 0);
|
return (this.model.get('profile')['tags'].length > 0);
|
||||||
},
|
},
|
||||||
|
|
@ -52,21 +59,6 @@ app.views.ProfileHeader = app.views.Base.extend({
|
||||||
showMessageModal: function(){
|
showMessageModal: function(){
|
||||||
app.helpers.showModal("#conversationModal");
|
app.helpers.showModal("#conversationModal");
|
||||||
},
|
},
|
||||||
|
|
||||||
postRenderTemplate: function() {
|
|
||||||
var dropdownEl = this.$('.aspect_membership_dropdown.placeholder');
|
|
||||||
if( dropdownEl.length === 0 ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO render me client side!!!
|
|
||||||
var href = this.model.url() + '/aspect_membership_button?create=true&size=normal';
|
|
||||||
|
|
||||||
$.get(href, function(resp) {
|
|
||||||
dropdownEl.html(resp);
|
|
||||||
new app.views.AspectMembership({el: $('.aspect_dropdown',dropdownEl)});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
// @license-end
|
// @license-end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -120,3 +120,21 @@ $default-border-radius: 3px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@mixin selectable-list() {
|
||||||
|
.glyphicon-ok,
|
||||||
|
.glyphicon-refresh {
|
||||||
|
display: none;
|
||||||
|
padding-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.selected {
|
||||||
|
.glyphicon-ok { display: inline-block;}
|
||||||
|
.glyphicon-refresh { display: none;}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.loading {
|
||||||
|
.glyphicon-refresh { display: inline-block;}
|
||||||
|
.glyphicon-ok { display: none;}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,14 @@
|
||||||
.aspect_dropdown {
|
.aspect_dropdown {
|
||||||
|
|
||||||
li {
|
li {
|
||||||
|
@include selectable-list;
|
||||||
|
|
||||||
.status_indicator {
|
.status_indicator {
|
||||||
width: 19px;
|
width: 19px;
|
||||||
height: 14px;
|
height: 14px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
.glyphicon-ok, .icon-refresh {
|
|
||||||
padding-right: 5px;
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
&.selected {
|
|
||||||
.glyphicon-ok { display: inline-block;}
|
|
||||||
.icon-refresh { display: none;}
|
|
||||||
}
|
|
||||||
&.loading {
|
|
||||||
.icon-refresh { display: inline-block;}
|
|
||||||
.glyphicon-ok { display: none;}
|
|
||||||
}
|
|
||||||
a {
|
a {
|
||||||
.text {
|
.text {
|
||||||
color: #333333;
|
color: #333333;
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<form>
|
<form>
|
||||||
<fieldset>
|
<fieldset>
|
||||||
{{#if addPersonId}}
|
{{#if personId}}
|
||||||
<input id="aspect_person_id" type="hidden" value="{{ personId }}">
|
<input id="aspect_person_id" type="hidden" value="{{ personId }}">
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
|
|
|
||||||
52
app/assets/templates/aspect_membership_dropdown_tpl.jst.hbs
Normal file
52
app/assets/templates/aspect_membership_dropdown_tpl.jst.hbs
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
<button class="btn dropdown-toggle {{extraButtonClass}}" data-toggle="dropdown" tabindex="0">
|
||||||
|
<span class="text">
|
||||||
|
{{#if allAspectsAreSelected }}
|
||||||
|
{{ t "aspect_dropdown.all_aspects" }}
|
||||||
|
{{else if onlyOneAspectIsSelected}}
|
||||||
|
{{ firstMembershipName }}
|
||||||
|
{{else if noAspectIsSelected}}
|
||||||
|
{{ t "aspect_dropdown.add_to_aspect"}}
|
||||||
|
{{else}}
|
||||||
|
{{ t "aspect_dropdown.toggle" count=aspectMembershipsLength }}
|
||||||
|
{{/if}}
|
||||||
|
</span>
|
||||||
|
<span class="caret" />
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<ul class="dropdown-menu aspect_membership pull-right" unselectable="on">
|
||||||
|
{{#each aspects}}
|
||||||
|
<li
|
||||||
|
{{#if membership}}
|
||||||
|
class="aspect_selector selected"
|
||||||
|
{{else}}
|
||||||
|
class="aspect_selector"
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
data-aspect_id="{{id}}"
|
||||||
|
{{#if membership}}
|
||||||
|
data-membership_id="{{membership.id}}"
|
||||||
|
{{/if}}
|
||||||
|
>
|
||||||
|
<a>
|
||||||
|
<span class="status_indicator">
|
||||||
|
<i class="glyphicon glyphicon-ok" />
|
||||||
|
<i class="glyphicon glyphicon-refresh" />
|
||||||
|
</span>
|
||||||
|
<span class="text">
|
||||||
|
{{name}}
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{{/each}}
|
||||||
|
{{#if dropdownMayCreateNewAspect}}
|
||||||
|
<li class="divider" />
|
||||||
|
<li class="newItem add_aspect">
|
||||||
|
<a data-target="#newAspectModal" data-toggle="modal" href="#">
|
||||||
|
{{ t "aspects.create.add_a_new_aspect" }}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{{/if}}
|
||||||
|
</ul>
|
||||||
|
{{#if dropdownMayCreateNewAspect}}
|
||||||
|
<div class="newAspectContainer"/>
|
||||||
|
{{/if}}
|
||||||
|
|
@ -14,10 +14,13 @@ class AspectsController < ApplicationController
|
||||||
aspecting_person_id = params[:person_id]
|
aspecting_person_id = params[:person_id]
|
||||||
|
|
||||||
if @aspect.save
|
if @aspect.save
|
||||||
|
result = {id: @aspect.id, name: @aspect.name}
|
||||||
if aspecting_person_id.present?
|
if aspecting_person_id.present?
|
||||||
connect_person_to_aspect(aspecting_person_id)
|
aspect_membership = connect_person_to_aspect(aspecting_person_id)
|
||||||
|
result[:aspect_membership] = AspectMembershipPresenter.new(aspect_membership).base_hash if aspect_membership
|
||||||
end
|
end
|
||||||
render json: {id: @aspect.id, name: @aspect.name}
|
|
||||||
|
render json: result
|
||||||
else
|
else
|
||||||
render nothing: true, status: 422
|
render nothing: true, status: 422
|
||||||
end
|
end
|
||||||
|
|
@ -96,9 +99,10 @@ class AspectsController < ApplicationController
|
||||||
def connect_person_to_aspect(aspecting_person_id)
|
def connect_person_to_aspect(aspecting_person_id)
|
||||||
@person = Person.find(aspecting_person_id)
|
@person = Person.find(aspecting_person_id)
|
||||||
if @contact = current_user.contact_for(@person)
|
if @contact = current_user.contact_for(@person)
|
||||||
@contact.aspects << @aspect
|
@contact.aspect_memberships.create(aspect: @aspect)
|
||||||
else
|
else
|
||||||
@contact = current_user.share_with(@person, @aspect)
|
@contact = current_user.share_with(@person, @aspect)
|
||||||
|
@contact.aspect_memberships.first
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -146,21 +146,6 @@ class PeopleController < ApplicationController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# shows the dropdown list of aspects the current user has set for the given person.
|
|
||||||
# renders "thats you" in case the current user views himself
|
|
||||||
def aspect_membership_dropdown
|
|
||||||
@person = Person.find_by_guid(params[:person_id])
|
|
||||||
|
|
||||||
# you are not a contact of yourself...
|
|
||||||
return render :text => I18n.t('people.person.thats_you') if @person == current_user.person
|
|
||||||
|
|
||||||
@contact = current_user.contact_for(@person) || Contact.new
|
|
||||||
@aspect = :profile if params[:create] # let aspect dropdown create new aspects
|
|
||||||
size = params[:size] || "small"
|
|
||||||
|
|
||||||
render :partial => 'aspect_membership_dropdown', :locals => {:contact => @contact, :person => @person, :hang => 'left', :size => size}
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def find_person
|
def find_person
|
||||||
|
|
|
||||||
|
|
@ -129,6 +129,7 @@ class UsersController < ApplicationController
|
||||||
@user = current_user
|
@user = current_user
|
||||||
@person = @user.person
|
@person = @user.person
|
||||||
@profile = @user.profile
|
@profile = @user.profile
|
||||||
|
gon.preloads[:inviter] = PersonPresenter.new(current_user.invited_by.try(:person), current_user).as_json
|
||||||
|
|
||||||
render "users/getting_started"
|
render "users/getting_started"
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
# the COPYRIGHT file.
|
# the COPYRIGHT file.
|
||||||
|
|
||||||
module AspectGlobalHelper
|
module AspectGlobalHelper
|
||||||
def aspect_membership_dropdown(contact, person, hang, aspect=nil, size="small")
|
def aspect_membership_dropdown(contact, person, hang)
|
||||||
aspect_membership_ids = {}
|
aspect_membership_ids = {}
|
||||||
|
|
||||||
selected_aspects = all_aspects.select{|aspect| contact.in_aspect?(aspect)}
|
selected_aspects = all_aspects.select{|aspect| contact.in_aspect?(aspect)}
|
||||||
|
|
@ -13,41 +13,15 @@ module AspectGlobalHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
button_class = selected_aspects.size > 0 ? "btn-success" : "btn-default"
|
button_class = selected_aspects.size > 0 ? "btn-success" : "btn-default"
|
||||||
button_class << case size
|
|
||||||
when "small"
|
|
||||||
" btn-small"
|
|
||||||
when "normal"
|
|
||||||
""
|
|
||||||
when "large"
|
|
||||||
" btn-large"
|
|
||||||
else
|
|
||||||
raise ArgumentError, "unknown size #{size}"
|
|
||||||
end
|
|
||||||
|
|
||||||
render "aspect_memberships/aspect_membership_dropdown",
|
render "aspect_memberships/aspect_membership_dropdown",
|
||||||
:selected_aspects => selected_aspects,
|
:selected_aspects => selected_aspects,
|
||||||
:aspect_membership_ids => aspect_membership_ids,
|
:aspect_membership_ids => aspect_membership_ids,
|
||||||
:person => person,
|
:person => person,
|
||||||
:hang => hang,
|
:hang => hang,
|
||||||
:dropdown_class => "aspect_membership",
|
|
||||||
:button_class => button_class
|
:button_class => button_class
|
||||||
end
|
end
|
||||||
|
|
||||||
def aspect_dropdown_list_item(aspect, am_id=nil)
|
|
||||||
klass = am_id.present? ? "selected" : ""
|
|
||||||
|
|
||||||
str = <<LISTITEM
|
|
||||||
<li data-aspect_id="#{aspect.id}" data-membership_id="#{am_id}" class="#{klass} aspect_selector" tabindex="0">
|
|
||||||
#{aspect.name}
|
|
||||||
</li>
|
|
||||||
LISTITEM
|
|
||||||
str.html_safe
|
|
||||||
end
|
|
||||||
|
|
||||||
def dropdown_may_create_new_aspect
|
|
||||||
@aspect == :profile || @aspect == :tag || @aspect == :notification || params[:action] == "getting_started"
|
|
||||||
end
|
|
||||||
|
|
||||||
def aspect_options_for_select(aspects)
|
def aspect_options_for_select(aspects)
|
||||||
options = {}
|
options = {}
|
||||||
aspects.each do |aspect|
|
aspects.each do |aspect|
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,12 @@ class ContactPresenter < BasePresenter
|
||||||
end
|
end
|
||||||
|
|
||||||
def full_hash_with_person
|
def full_hash_with_person
|
||||||
full_hash.merge(person: PersonPresenter.new(person, current_user).as_json)
|
full_hash.merge(person: person_without_contact)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def person_without_contact
|
||||||
|
PersonPresenter.new(person, current_user).as_json.except!(:contact)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ class PersonPresenter < BasePresenter
|
||||||
base_hash.merge(
|
base_hash.merge(
|
||||||
relationship: relationship,
|
relationship: relationship,
|
||||||
block: is_blocked? ? BlockPresenter.new(current_user_person_block).base_hash : false,
|
block: is_blocked? ? BlockPresenter.new(current_user_person_block).base_hash : false,
|
||||||
contact: (!own_profile? && has_contact?) ? {id: current_user_person_contact.id} : false,
|
contact: (!own_profile? && has_contact?) ? contact_hash : false,
|
||||||
is_own_profile: own_profile?,
|
is_own_profile: own_profile?,
|
||||||
show_profile_info: public_details? || own_profile? || person_is_following_current_user
|
show_profile_info: public_details? || own_profile? || person_is_following_current_user
|
||||||
)
|
)
|
||||||
|
|
@ -58,6 +58,10 @@ class PersonPresenter < BasePresenter
|
||||||
attrs
|
attrs
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def contact_hash
|
||||||
|
ContactPresenter.new(current_user_person_contact).full_hash
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def current_user_person_block
|
def current_user_person_block
|
||||||
|
|
|
||||||
|
|
@ -1,30 +1 @@
|
||||||
.btn-group.aspect_dropdown.aspect_membership_dropdown
|
.placeholder.aspect_membership_dropdown
|
||||||
%button.btn.dropdown-toggle{:class => button_class, "data-toggle" => "dropdown", :tabindex => '0'}
|
|
||||||
%span.text
|
|
||||||
- if selected_aspects.size == all_aspects.size
|
|
||||||
= t('all_aspects')
|
|
||||||
- elsif selected_aspects.size == 1
|
|
||||||
= selected_aspects.first.name
|
|
||||||
- else
|
|
||||||
= t('shared.aspect_dropdown.toggle', :count => selected_aspects.size)
|
|
||||||
%span.caret
|
|
||||||
|
|
||||||
%ul.dropdown-menu{:class => ["pull-#{hang}", defined?(dropdown_class) && dropdown_class], :unSelectable => 'on', 'data-person_id' => (person.id if defined?(person) && person), 'data-service_uid' => (service_uid if defined?(service_uid)), 'data-person-short-name' => (person.first_name if defined?(person) && person)}
|
|
||||||
- for aspect in all_aspects
|
|
||||||
%li.aspect_selector{ :class => ('selected' if aspect_membership_ids[aspect.id].present?), 'data-aspect_id' => aspect.id, 'data-membership_id' => aspect_membership_ids[aspect.id], :tabindex => '0' }
|
|
||||||
%a
|
|
||||||
%span.status_indicator
|
|
||||||
%i.glyphicon.glyphicon-ok
|
|
||||||
%i.icon-refresh
|
|
||||||
%span.text
|
|
||||||
= aspect.name
|
|
||||||
|
|
||||||
- if dropdown_may_create_new_aspect && defined?(person) && person
|
|
||||||
%li.divider
|
|
||||||
%li.newItem.add_aspect
|
|
||||||
%a{ href: "#", data: { toggle: "modal", target: "#newAspectModal" }}
|
|
||||||
= t("contacts.index.add_a_new_aspect")
|
|
||||||
|
|
||||||
- if dropdown_may_create_new_aspect && defined?(person) && person
|
|
||||||
.newAspectContainer
|
|
||||||
-# JS
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
= t('.invited_by')
|
= t('.invited_by')
|
||||||
.media
|
.media
|
||||||
.pull-right
|
.pull-right
|
||||||
= aspect_membership_dropdown(contact, inviter, false)
|
= render partial: "aspect_memberships/aspect_membership_dropdown", locals: {person: inviter}
|
||||||
.media-left
|
.media-left
|
||||||
= person_image_link(inviter, size: :thumb_small, class: "media-object")
|
= person_image_link(inviter, size: :thumb_small, class: "media-object")
|
||||||
.media-body
|
.media-body
|
||||||
|
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
= aspect_membership_dropdown(@contact, @person, 'right', nil, size)
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
- unless person == current_user.person
|
- unless person == current_user.person
|
||||||
- contact = current_user.contacts.find_by_person_id(person.id)
|
- contact = current_user.contacts.find_by_person_id(person.id)
|
||||||
- contact ||= Contact.new(:person => person)
|
- contact ||= Contact.new(:person => person)
|
||||||
= aspect_membership_dropdown(contact, person, 'right')
|
.aspect_membership_dropdown
|
||||||
-else
|
-else
|
||||||
%span.thats_you
|
%span.thats_you
|
||||||
= t('people.person.thats_you')
|
= t('people.person.thats_you')
|
||||||
|
|
|
||||||
|
|
@ -1024,7 +1024,6 @@ en:
|
||||||
mobile_row_checked: "%{name} (remove)"
|
mobile_row_checked: "%{name} (remove)"
|
||||||
mobile_row_unchecked: "%{name} (add)"
|
mobile_row_unchecked: "%{name} (add)"
|
||||||
toggle:
|
toggle:
|
||||||
zero: "Add contact"
|
|
||||||
one: "In %{count} aspect"
|
one: "In %{count} aspect"
|
||||||
other: "In %{count} aspects"
|
other: "In %{count} aspects"
|
||||||
publisher:
|
publisher:
|
||||||
|
|
|
||||||
|
|
@ -144,7 +144,6 @@ en:
|
||||||
error: "Couldn’t start sharing with <%= name %>. Are you ignoring them?"
|
error: "Couldn’t start sharing with <%= name %>. Are you ignoring them?"
|
||||||
error_remove: "Couldn’t remove <%= name %> from the aspect :("
|
error_remove: "Couldn’t remove <%= name %> from the aspect :("
|
||||||
toggle:
|
toggle:
|
||||||
zero: "Select aspects"
|
|
||||||
one: "In <%= count %> aspect"
|
one: "In <%= count %> aspect"
|
||||||
other: "In <%= count %> aspects"
|
other: "In <%= count %> aspects"
|
||||||
show_more: "Show more"
|
show_more: "Show more"
|
||||||
|
|
|
||||||
|
|
@ -169,7 +169,6 @@ Diaspora::Application.routes.draw do
|
||||||
resources :status_messages
|
resources :status_messages
|
||||||
resources :photos
|
resources :photos
|
||||||
get :contacts
|
get :contacts
|
||||||
get "aspect_membership_button" => :aspect_membership_dropdown, :as => "aspect_membership_button"
|
|
||||||
get :stream
|
get :stream
|
||||||
get :hovercard
|
get :hovercard
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ Feature: following and being followed
|
||||||
And I go to the edit profile page
|
And I go to the edit profile page
|
||||||
And I fill in the following:
|
And I fill in the following:
|
||||||
| profile_first_name | <script>alert(0)// |
|
| profile_first_name | <script>alert(0)// |
|
||||||
|
| profile_last_name ||
|
||||||
And I press "update_profile"
|
And I press "update_profile"
|
||||||
Then I should be on my edit profile page
|
Then I should be on my edit profile page
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,17 +20,4 @@ describe PeopleController, :type => :controller do
|
||||||
save_fixture(html_for("body"), "pending_external_people_search")
|
save_fixture(html_for("body"), "pending_external_people_search")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#aspect_membership_dropdown' do
|
|
||||||
before do
|
|
||||||
aspect = bob.aspects.create name: 'Testing'
|
|
||||||
bob.share_with alice.person, aspect
|
|
||||||
sign_in :user, bob
|
|
||||||
end
|
|
||||||
|
|
||||||
it "generates a jasmine fixture", :fixture => true do
|
|
||||||
get :aspect_membership_dropdown, :person_id => alice.person.guid
|
|
||||||
save_fixture(html_for("body"), "aspect_membership_dropdown")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
||||||
19
spec/controllers/jasmine_fixtures/users_spec.rb
Normal file
19
spec/controllers/jasmine_fixtures/users_spec.rb
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
require "spec_helper"
|
||||||
|
|
||||||
|
describe UsersController, type: :controller do
|
||||||
|
before do
|
||||||
|
sign_in :user, alice
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#getting_started" do
|
||||||
|
before do
|
||||||
|
alice.invited_by = bob
|
||||||
|
alice.save!
|
||||||
|
end
|
||||||
|
|
||||||
|
it "generates a jasmine fixture with no query", fixture: true do
|
||||||
|
get :getting_started
|
||||||
|
save_fixture(html_for("body"), "getting_started")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -5,6 +5,8 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
describe PeopleController, :type => :controller do
|
describe PeopleController, :type => :controller do
|
||||||
|
include_context :gon
|
||||||
|
|
||||||
before do
|
before do
|
||||||
@user = alice
|
@user = alice
|
||||||
@aspect = @user.aspects.first
|
@aspect = @user.aspects.first
|
||||||
|
|
@ -277,6 +279,11 @@ describe PeopleController, :type => :controller do
|
||||||
get :show, id: @person.to_param
|
get :show, id: @person.to_param
|
||||||
expect(response.body).to include(@person.profile.bio)
|
expect(response.body).to include(@person.profile.bio)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "preloads data using gon for the aspect memberships dropdown" do
|
||||||
|
get :show, id: @person.to_param
|
||||||
|
expect_gon_preloads_for_aspect_membership_dropdown(:person, true)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context "when the person is not a contact of the current user" do
|
context "when the person is not a contact of the current user" do
|
||||||
|
|
@ -298,6 +305,11 @@ describe PeopleController, :type => :controller do
|
||||||
get :show, id: @person.to_param
|
get :show, id: @person.to_param
|
||||||
expect(response.body).not_to include(@person.profile.bio)
|
expect(response.body).not_to include(@person.profile.bio)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "preloads data using gon for the aspect memberships dropdown" do
|
||||||
|
get :show, id: @person.to_param
|
||||||
|
expect_gon_preloads_for_aspect_membership_dropdown(:person, false)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context "when the user is following the person" do
|
context "when the user is following the person" do
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,8 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
describe UsersController, :type => :controller do
|
describe UsersController, :type => :controller do
|
||||||
|
include_context :gon
|
||||||
|
|
||||||
before do
|
before do
|
||||||
@user = alice
|
@user = alice
|
||||||
sign_in :user, @user
|
sign_in :user, @user
|
||||||
|
|
@ -319,5 +321,19 @@ describe UsersController, :type => :controller do
|
||||||
get :getting_started, :format => :mobile
|
get :getting_started, :format => :mobile
|
||||||
expect(response).to be_success
|
expect(response).to be_success
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "with inviter" do
|
||||||
|
[bob, eve].each do |inviter|
|
||||||
|
sharing = !alice.contact_for(inviter.person).nil?
|
||||||
|
|
||||||
|
context sharing ? "when sharing" : "when don't share" do
|
||||||
|
it "preloads data using gon for the aspect memberships dropdown" do
|
||||||
|
alice.invited_by = inviter
|
||||||
|
get :getting_started
|
||||||
|
expect_gon_preloads_for_aspect_membership_dropdown(:inviter, sharing)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
17
spec/javascripts/app/collections/aspect_memberships_spec.js
Normal file
17
spec/javascripts/app/collections/aspect_memberships_spec.js
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
describe("app.collections.AspectMemberships", function() {
|
||||||
|
beforeEach(function() {
|
||||||
|
this.models = [factory.aspectMembershipAttrs(), factory.aspectMembershipAttrs(), factory.aspectMembershipAttrs()];
|
||||||
|
this.collection = new app.collections.AspectMemberships(this.models);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("#findByAspectId", function() {
|
||||||
|
it("finds a model in collection", function() {
|
||||||
|
var model = this.collection.findByAspectId(this.models[1].aspect.id);
|
||||||
|
expect(model.get("id")).toEqual(this.models[1].id);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns undefined when nothing found", function() {
|
||||||
|
expect(this.collection.findByAspectId(factory.id.next())).toEqual(undefined);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -8,6 +8,13 @@ describe("app.models.Contact", function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("initialize", function() {
|
||||||
|
it("sets person object with contact reference", function() {
|
||||||
|
expect(this.contact.person.get("name")).toEqual("aaa");
|
||||||
|
expect(this.contact.person.contact).toEqual(this.contact);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe("inAspect", function(){
|
describe("inAspect", function(){
|
||||||
it("returns true if the contact has been added to the aspect", function(){
|
it("returns true if the contact has been added to the aspect", function(){
|
||||||
expect(this.contact.inAspect(this.aspect.id)).toBeTruthy();
|
expect(this.contact.inAspect(this.aspect.id)).toBeTruthy();
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,15 @@ describe("app.models.Person", function() {
|
||||||
this.blockedContact = factory.person({relationship: "blocked", block: {id: 1}});
|
this.blockedContact = factory.person({relationship: "blocked", block: {id: 1}});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("initialize", function() {
|
||||||
|
it("sets contact object with person reference", function() {
|
||||||
|
var contact = {id: factory.id.next()};
|
||||||
|
var person = factory.person({contact: contact});
|
||||||
|
expect(person.contact.get("id")).toEqual(contact.id);
|
||||||
|
expect(person.contact.person).toEqual(person);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
context("#isSharing", function() {
|
context("#isSharing", function() {
|
||||||
it("indicates if the person is sharing", function() {
|
it("indicates if the person is sharing", function() {
|
||||||
expect(this.mutualContact.isSharing()).toBeTruthy();
|
expect(this.mutualContact.isSharing()).toBeTruthy();
|
||||||
|
|
|
||||||
15
spec/javascripts/app/pages/getting_started_spec.js
Normal file
15
spec/javascripts/app/pages/getting_started_spec.js
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
describe("app.pages.GettingStarted", function() {
|
||||||
|
beforeEach(function() {
|
||||||
|
spec.loadFixture("getting_started");
|
||||||
|
app.aspects = new app.collections.Aspects([factory.aspect()]);
|
||||||
|
|
||||||
|
this.view = new app.pages.GettingStarted({
|
||||||
|
inviter: factory.person()
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("renders aspect membership dropdown", function() {
|
||||||
|
this.view.render();
|
||||||
|
expect($("ul.dropdown-menu.aspect_membership").length).toEqual(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -88,6 +88,13 @@ describe('app.Router', function () {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("gettingStarted", function() {
|
||||||
|
it("renders app.pages.GettingStarted", function() {
|
||||||
|
app.router.navigate("/getting_started", {trigger: true});
|
||||||
|
expect(app.page.$el.selector).toEqual("#hello-there");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe("_initializeStreamView", function() {
|
describe("_initializeStreamView", function() {
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
delete app.page;
|
delete app.page;
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ describe("app.views.AspectCreate", function() {
|
||||||
app.events.off("aspect:create");
|
app.events.off("aspect:create");
|
||||||
});
|
});
|
||||||
|
|
||||||
context("without a person id", function() {
|
context("without a person", function() {
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
this.view = new app.views.AspectCreate();
|
this.view = new app.views.AspectCreate();
|
||||||
});
|
});
|
||||||
|
|
@ -50,6 +50,7 @@ describe("app.views.AspectCreate", function() {
|
||||||
this.view.render();
|
this.view.render();
|
||||||
this.view.$el.append($("<div id='flash-container'/>"));
|
this.view.$el.append($("<div id='flash-container'/>"));
|
||||||
app.flashMessages = new app.views.FlashMessages({ el: this.view.$("#flash-container") });
|
app.flashMessages = new app.views.FlashMessages({ el: this.view.$("#flash-container") });
|
||||||
|
app.aspects = new app.collections.Aspects();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should send the correct name to the server", function() {
|
it("should send the correct name to the server", function() {
|
||||||
|
|
@ -134,9 +135,10 @@ describe("app.views.AspectCreate", function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
context("with a person id", function() {
|
context("with a person", function() {
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
this.view = new app.views.AspectCreate({personId: "42"});
|
var person = new app.models.Person({id: "42"});
|
||||||
|
this.view = new app.views.AspectCreate({person: person});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("#render", function() {
|
describe("#render", function() {
|
||||||
|
|
@ -161,6 +163,7 @@ describe("app.views.AspectCreate", function() {
|
||||||
describe("#createAspect", function() {
|
describe("#createAspect", function() {
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
this.view.render();
|
this.view.render();
|
||||||
|
app.aspects = new app.collections.Aspects();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should send the correct name to the server", function() {
|
it("should send the correct name to the server", function() {
|
||||||
|
|
@ -193,6 +196,36 @@ describe("app.views.AspectCreate", function() {
|
||||||
expect(obj.person_id).toBe("42");
|
expect(obj.person_id).toBe("42");
|
||||||
/* jshint camelcase: true */
|
/* jshint camelcase: true */
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should ensure that events order is fine", function() {
|
||||||
|
spyOn(this.view, "ensureEventsOrder").and.callThrough();
|
||||||
|
this.view.$(".modal").removeClass("fade");
|
||||||
|
this.view.$(".modal").modal("toggle");
|
||||||
|
this.view.createAspect();
|
||||||
|
jasmine.Ajax.requests.mostRecent().respondWith({
|
||||||
|
status: 200,
|
||||||
|
responseText: JSON.stringify({id: 1337, name: "new name"})
|
||||||
|
});
|
||||||
|
expect(this.view.ensureEventsOrder.calls.count()).toBe(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should ensure that events order is fine after failure", function() {
|
||||||
|
spyOn(this.view, "ensureEventsOrder").and.callThrough();
|
||||||
|
this.view.$(".modal").removeClass("fade");
|
||||||
|
this.view.$(".modal").modal("toggle");
|
||||||
|
this.view.createAspect();
|
||||||
|
jasmine.Ajax.requests.mostRecent().respondWith({status: 422});
|
||||||
|
expect(this.view.ensureEventsOrder.calls.count()).toBe(1);
|
||||||
|
|
||||||
|
this.view.$(".modal").removeClass("fade");
|
||||||
|
this.view.$(".modal").modal("toggle");
|
||||||
|
this.view.createAspect();
|
||||||
|
jasmine.Ajax.requests.mostRecent().respondWith({
|
||||||
|
status: 200,
|
||||||
|
responseText: JSON.stringify({id: 1337, name: "new name"})
|
||||||
|
});
|
||||||
|
expect(this.view.ensureEventsOrder.calls.count()).toBe(3);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -3,45 +3,53 @@ describe("app.views.AspectMembership", function(){
|
||||||
var resp_fail = {status: 400};
|
var resp_fail = {status: 400};
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
// mock a dummy aspect dropdown
|
var contact = factory.contact();
|
||||||
spec.loadFixture("aspect_membership_dropdown");
|
this.person = contact.person;
|
||||||
this.view = new app.views.AspectMembership({el: $('.aspect_membership_dropdown')});
|
this.personName = this.person.get("name");
|
||||||
this.view.$el.append($("<div id='flash-container'/>"));
|
var aspectAttrs = contact.aspectMemberships.at(0).get("aspect");
|
||||||
app.flashMessages = new app.views.FlashMessages({ el: this.view.$("#flash-container") });
|
app.aspects = new app.collections.Aspects([factory.aspect(aspectAttrs), factory.aspect()]);
|
||||||
this.personId = $(".dropdown-menu").data("person_id");
|
this.view = new app.views.AspectMembership({person: this.person});
|
||||||
this.personName = $(".dropdown-menu").data("person-short-name");
|
this.view.render();
|
||||||
|
spec.content().append($("<div id='flash-container'/>"));
|
||||||
|
app.flashMessages = new app.views.FlashMessages({el: spec.content().find("#flash-container")});
|
||||||
});
|
});
|
||||||
|
|
||||||
context('adding to aspects', function() {
|
context('adding to aspects', function() {
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
this.newAspect = $('li:not(.selected)');
|
this.newAspect = this.view.$("li:not(.selected)");
|
||||||
this.newAspectId = this.newAspect.data('aspect_id');
|
this.newAspectId = this.newAspect.data('aspect_id');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('marks the aspect as selected', function() {
|
it('marks the aspect as selected', function() {
|
||||||
this.newAspect.trigger('click');
|
this.newAspect.trigger('click');
|
||||||
jasmine.Ajax.requests.mostRecent().respondWith(success);
|
jasmine.Ajax.requests.mostRecent().respondWith({
|
||||||
|
status: 200,
|
||||||
|
responseText: JSON.stringify({
|
||||||
|
id: factory.id.next(),
|
||||||
|
aspect: app.aspects.at(1).attributes
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
expect(this.newAspect.attr('class')).toContain('selected');
|
expect(this.view.$("li[data-aspect_id=" + this.newAspectId + "]").attr("class")).toContain("selected");
|
||||||
});
|
});
|
||||||
|
|
||||||
it('displays flash message when added to first aspect', function() {
|
it('displays flash message when added to first aspect', function() {
|
||||||
spec.content().find('li').removeClass('selected');
|
this.view.$("li").removeClass("selected");
|
||||||
this.newAspect.trigger('click');
|
this.newAspect.trigger('click');
|
||||||
jasmine.Ajax.requests.mostRecent().respondWith(success);
|
jasmine.Ajax.requests.mostRecent().respondWith(success);
|
||||||
|
|
||||||
expect(this.view.$(".flash-message")).toBeSuccessFlashMessage(
|
expect(spec.content().find(".flash-message")).toBeSuccessFlashMessage(
|
||||||
Diaspora.I18n.t("aspect_dropdown.started_sharing_with", {name: this.personName})
|
Diaspora.I18n.t("aspect_dropdown.started_sharing_with", {name: this.personName})
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("triggers aspect_membership:create", function() {
|
it("triggers aspect_membership:create", function() {
|
||||||
spyOn(app.events, "trigger");
|
spyOn(app.events, "trigger");
|
||||||
spec.content().find("li").removeClass("selected");
|
this.view.$("li").removeClass("selected");
|
||||||
this.newAspect.trigger("click");
|
this.newAspect.trigger("click");
|
||||||
jasmine.Ajax.requests.mostRecent().respondWith(success);
|
jasmine.Ajax.requests.mostRecent().respondWith(success);
|
||||||
expect(app.events.trigger).toHaveBeenCalledWith("aspect_membership:create", {
|
expect(app.events.trigger).toHaveBeenCalledWith("aspect_membership:create", {
|
||||||
membership: {aspectId: this.newAspectId, personId: this.personId},
|
membership: {aspectId: this.newAspectId, personId: this.person.id},
|
||||||
startSharing: true
|
startSharing: true
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -50,7 +58,7 @@ describe("app.views.AspectMembership", function(){
|
||||||
this.newAspect.trigger('click');
|
this.newAspect.trigger('click');
|
||||||
jasmine.Ajax.requests.mostRecent().respondWith(resp_fail);
|
jasmine.Ajax.requests.mostRecent().respondWith(resp_fail);
|
||||||
|
|
||||||
expect(this.view.$(".flash-message")).toBeErrorFlashMessage(
|
expect(spec.content().find(".flash-message")).toBeErrorFlashMessage(
|
||||||
Diaspora.I18n.t("aspect_dropdown.error", {name: this.personName})
|
Diaspora.I18n.t("aspect_dropdown.error", {name: this.personName})
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
@ -58,34 +66,32 @@ describe("app.views.AspectMembership", function(){
|
||||||
|
|
||||||
context('removing from aspects', function(){
|
context('removing from aspects', function(){
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
this.oldAspect = $('li.selected').first();
|
this.oldAspect = this.view.$("li.selected").first();
|
||||||
this.oldMembershipId = this.oldAspect.data('membership_id');
|
this.oldAspectId = this.oldAspect.data("aspect_id");
|
||||||
});
|
});
|
||||||
|
|
||||||
it('marks the aspect as unselected', function(){
|
it('marks the aspect as unselected', function(){
|
||||||
this.oldAspect.trigger('click');
|
this.oldAspect.trigger('click');
|
||||||
jasmine.Ajax.requests.mostRecent().respondWith(success);
|
jasmine.Ajax.requests.mostRecent().respondWith(success);
|
||||||
|
|
||||||
expect(this.oldAspect.attr('class')).not.toContain('selected');
|
expect(this.view.$("li[data-aspect_id=" + this.oldAspectId + "]").attr("class")).not.toContain("selected");
|
||||||
});
|
});
|
||||||
|
|
||||||
it('displays a flash message when removed from last aspect', function() {
|
it('displays a flash message when removed from last aspect', function() {
|
||||||
spec.content().find('li.selected:last').removeClass('selected');
|
|
||||||
this.oldAspect.trigger('click');
|
this.oldAspect.trigger('click');
|
||||||
jasmine.Ajax.requests.mostRecent().respondWith(success);
|
jasmine.Ajax.requests.mostRecent().respondWith(success);
|
||||||
|
|
||||||
expect(this.view.$(".flash-message")).toBeSuccessFlashMessage(
|
expect(spec.content().find(".flash-message")).toBeSuccessFlashMessage(
|
||||||
Diaspora.I18n.t("aspect_dropdown.stopped_sharing_with", {name: this.personName})
|
Diaspora.I18n.t("aspect_dropdown.stopped_sharing_with", {name: this.personName})
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("triggers aspect_membership:destroy", function() {
|
it("triggers aspect_membership:destroy", function() {
|
||||||
spyOn(app.events, "trigger");
|
spyOn(app.events, "trigger");
|
||||||
spec.content().find("li.selected:last").removeClass("selected");
|
|
||||||
this.oldAspect.trigger("click");
|
this.oldAspect.trigger("click");
|
||||||
jasmine.Ajax.requests.mostRecent().respondWith(success);
|
jasmine.Ajax.requests.mostRecent().respondWith(success);
|
||||||
expect(app.events.trigger).toHaveBeenCalledWith("aspect_membership:destroy", {
|
expect(app.events.trigger).toHaveBeenCalledWith("aspect_membership:destroy", {
|
||||||
membership: {aspectId: this.oldAspect.data("aspect_id"), personId: this.personId},
|
membership: {aspectId: this.oldAspectId, personId: this.person.id},
|
||||||
stopSharing: true
|
stopSharing: true
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -94,29 +100,9 @@ describe("app.views.AspectMembership", function(){
|
||||||
this.oldAspect.trigger('click');
|
this.oldAspect.trigger('click');
|
||||||
jasmine.Ajax.requests.mostRecent().respondWith(resp_fail);
|
jasmine.Ajax.requests.mostRecent().respondWith(resp_fail);
|
||||||
|
|
||||||
expect(this.view.$(".flash-message")).toBeErrorFlashMessage(
|
expect(spec.content().find(".flash-message")).toBeErrorFlashMessage(
|
||||||
Diaspora.I18n.t("aspect_dropdown.error_remove", {name: this.personName})
|
Diaspora.I18n.t("aspect_dropdown.error_remove", {name: this.personName})
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
context('button summary text', function() {
|
|
||||||
beforeEach(function() {
|
|
||||||
this.Aspect = $('li:eq(0)');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('calls "_toggleCheckbox"', function() {
|
|
||||||
spyOn(this.view, "_toggleCheckbox");
|
|
||||||
this.view.updateSummary(this.Aspect);
|
|
||||||
|
|
||||||
expect(this.view._toggleCheckbox).toHaveBeenCalledWith(this.Aspect);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('calls "_updateButton"', function() {
|
|
||||||
spyOn(this.view, "_updateButton");
|
|
||||||
this.view.updateSummary(this.Aspect);
|
|
||||||
|
|
||||||
expect(this.view._updateButton).toHaveBeenCalledWith("btn-success");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,16 @@ var factory = {
|
||||||
return _.extend(defaultAttrs, overrides);
|
return _.extend(defaultAttrs, overrides);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
aspectMembershipAttrs: function(overrides) {
|
||||||
|
var id = this.id.next();
|
||||||
|
var defaultAttrs = {
|
||||||
|
"id": id,
|
||||||
|
"aspect": factory.aspectAttrs()
|
||||||
|
};
|
||||||
|
|
||||||
|
return _.extend(defaultAttrs, overrides);
|
||||||
|
},
|
||||||
|
|
||||||
comment : function(overrides) {
|
comment : function(overrides) {
|
||||||
var defaultAttrs = {
|
var defaultAttrs = {
|
||||||
"created_at" : "2012-01-04T00:55:30Z",
|
"created_at" : "2012-01-04T00:55:30Z",
|
||||||
|
|
@ -33,6 +43,18 @@ var factory = {
|
||||||
return new app.models.Comment(_.extend(defaultAttrs, overrides));
|
return new app.models.Comment(_.extend(defaultAttrs, overrides));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
contact: function(overrides) {
|
||||||
|
var person = factory.personAttrs();
|
||||||
|
var attrs = {
|
||||||
|
"id": this.id.next(),
|
||||||
|
"person_id": person.id,
|
||||||
|
"person": person,
|
||||||
|
"aspect_memberships": factory.aspectMembershipAttrs()
|
||||||
|
};
|
||||||
|
|
||||||
|
return new app.models.Contact(_.extend(attrs, overrides));
|
||||||
|
},
|
||||||
|
|
||||||
user : function(overrides) {
|
user : function(overrides) {
|
||||||
return new app.models.User(factory.userAttrs(overrides));
|
return new app.models.User(factory.userAttrs(overrides));
|
||||||
},
|
},
|
||||||
|
|
@ -189,6 +211,7 @@ var factory = {
|
||||||
aspectAttrs: function(overrides) {
|
aspectAttrs: function(overrides) {
|
||||||
var names = ['Work','School','Family','Friends','Just following','People','Interesting'];
|
var names = ['Work','School','Family','Friends','Just following','People','Interesting'];
|
||||||
var defaultAttrs = {
|
var defaultAttrs = {
|
||||||
|
id: this.id.next(),
|
||||||
name: names[Math.floor(Math.random()*names.length)]+' '+Math.floor(Math.random()*100),
|
name: names[Math.floor(Math.random()*names.length)]+' '+Math.floor(Math.random()*100),
|
||||||
selected: false
|
selected: false
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -25,5 +25,13 @@ describe ContactPresenter do
|
||||||
it "has relationship information" do
|
it "has relationship information" do
|
||||||
expect(@presenter.full_hash_with_person[:person][:relationship]).to be(:mutual)
|
expect(@presenter.full_hash_with_person[:person][:relationship]).to be(:mutual)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "doesn't have redundant contact object in person hash" do
|
||||||
|
expect(@presenter.full_hash_with_person[:person]).not_to have_key(:contact)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "has avatar links in person profile hash" do
|
||||||
|
expect(@presenter.full_hash_with_person[:person][:profile]).to have_key(:avatar)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
30
spec/support/gon.rb
Normal file
30
spec/support/gon.rb
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
shared_context :gon do
|
||||||
|
let(:gon) { RequestStore.store[:gon].gon }
|
||||||
|
end
|
||||||
|
|
||||||
|
module HelperMethods
|
||||||
|
def expect_aspects
|
||||||
|
expect(gon["user"].aspects).not_to be_nil
|
||||||
|
expect(gon["user"].aspects.length).not_to be_nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def expect_memberships(memberships)
|
||||||
|
expect(memberships).not_to be_nil
|
||||||
|
expect(memberships.length).not_to be_nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def expect_contact(preload_key)
|
||||||
|
expect(gon["preloads"][preload_key][:contact]).not_to be_falsy
|
||||||
|
expect_memberships(gon["preloads"][preload_key][:contact][:aspect_memberships])
|
||||||
|
end
|
||||||
|
|
||||||
|
def expect_gon_preloads_for_aspect_membership_dropdown(preload_key, sharing)
|
||||||
|
expect(gon["preloads"][preload_key]).not_to be_nil
|
||||||
|
if sharing
|
||||||
|
expect_contact(preload_key)
|
||||||
|
else
|
||||||
|
expect(gon["preloads"][preload_key][:contact]).to be_falsy
|
||||||
|
end
|
||||||
|
expect_aspects
|
||||||
|
end
|
||||||
|
end
|
||||||
Loading…
Reference in a new issue