Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion app/core/models/courseModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ define(function(require) {
},

isEditable: function () {
return this.get('_isShared') || this.get('createdBy') == Origin.sessionModel.get('id');
var access = this.get('_access') || {};
var meId = Origin.sessionModel.get('id');
return access.public || (access.users || []).includes(meId) || this.get('createdBy') == meId;
}
});

Expand Down
3 changes: 2 additions & 1 deletion app/modules/projects/views/projectView.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ define(function(require) {

deleteProjectPrompt: function(event) {
event && event.preventDefault();
var isShared = this.model.get('_isShared') || (this.model.get('_shareWithUsers') && this.model.get('_shareWithUsers').length > 0);
var access = this.model.get('_access') || {};
var isShared = access.public || (access.users && access.users.length > 0);
Origin.Notify.confirm({
type: 'warning',
title: Origin.l10n.t(`${isShared ? 'app.deletesharedproject' : 'app.deleteproject'}`),
Expand Down
14 changes: 13 additions & 1 deletion app/modules/scaffold/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ define([
'core/origin',
'core/helpers',
'./backboneFormsOverrides',
'./views/scaffoldAccessView',
'./views/scaffoldAssetItemView',
'./views/scaffoldAssetView',
'./views/scaffoldCodeEditorView',
Expand All @@ -12,7 +13,7 @@ define([
'./views/scaffoldListView',
'./views/scaffoldTagsView',
'./views/scaffoldUsersView'
], function(Origin, Helpers, Overrides, ScaffoldAssetItemView, ScaffoldAssetView, ScaffoldCodeEditorView, ScaffoldColourPickerView, ScaffoldDisplayTitleView, ScaffoldFileView, ScaffoldItemsModalView, ScaffoldListView, ScaffoldTagsView, ScaffoldUsersView) {
], function(Origin, Helpers, Overrides, ScaffoldAccessView, ScaffoldAssetItemView, ScaffoldAssetView, ScaffoldCodeEditorView, ScaffoldColourPickerView, ScaffoldDisplayTitleView, ScaffoldFileView, ScaffoldItemsModalView, ScaffoldListView, ScaffoldTagsView, ScaffoldUsersView) {

var Scaffold = {};
var alternativeModel;
Expand Down Expand Up @@ -45,6 +46,15 @@ define([
if (editor) {
return editor;
}
var adaptType = item._adapt && item._adapt.inputType;
adaptType = typeof adaptType === 'string' ? adaptType : adaptType && adaptType.type;

if (adaptType) {
if (Backbone.Form.editors[adaptType]) {
return adaptType;
}
console.warn('Scaffold: no editor registered for _adapt.inputType "' + adaptType + '", falling back to the primitive type editor');
}
switch (item.type) {
case 'array':
return 'List';
Expand Down Expand Up @@ -138,10 +148,12 @@ define([
'_hasPreview',
'_id',
'_isSelected',
'_isShared',
'_latestTrackingId',
'_layout',
'_menu',
'_parentId',
'_shareWithUsers',
'_sortOrder',
'_supportedLayout',
'_theme',
Expand Down
7 changes: 6 additions & 1 deletion app/modules/scaffold/lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@
"properties": "Properties",
"settings": "Settings",
"extensions": "Extensions",
"colourPickerCancel": "Cancel selection"
"colourPickerCancel": "Cancel selection",
"access": {
"onlyme": "Only me",
"specific": "Specific people",
"anyone": "Anyone"
}
}
}
22 changes: 22 additions & 0 deletions app/modules/scaffold/less/access.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
.field[data-type="Access"] {
.scaffold-access-tiers {
display: flex;
flex-direction: column;
gap: 5px;
}
.scaffold-access-option {
display: flex;
align-items: center;
cursor: pointer;

input { margin-right: 8px; }
}
.scaffold-access-people {
margin-top: 10px;

.option {
.name { font-weight: @font-weight-bold; }
.email { margin-left: 5px; }
}
}
}
155 changes: 155 additions & 0 deletions app/modules/scaffold/views/scaffoldAccessView.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
define([ 'core/origin' ], function(Origin) {
var TIERS = [ 'onlyme', 'specific', 'anyone' ];

var ScaffoldAccessView = Backbone.Form.editors.Base.extend({
tagName: 'div',
className: 'scaffold-access',
events: {
'change .scaffold-access-tier': function(event) {
this.setTier(event.target.value);
this.trigger('change', this);
},
'focus': function() { this.trigger('focus', this); },
'blur': function() { this.trigger('blur', this); }
},

render: function() {
this.deriveFromValue(this.value);
this.$el.html(this.template());
this.$people = this.$el.find('.scaffold-access-users');
this.fetchUsers(this.initSelectize);
this.togglePeople();
return this;
},

template: function() {
var tier = this.tier;
var radios = TIERS.map(function(name) {
return '<label class="scaffold-access-option">' +
'<input type="radio" class="scaffold-access-tier" name="' + this.id + '-tier"' +
' value="' + name + '"' + (name === tier ? ' checked' : '') + '>' +
'<span>' + Origin.l10n.t('app.scaffold.access.' + name) + '</span>' +
'</label>';
}, this).join('');
return '<div class="scaffold-access-tiers">' + radios + '</div>' +
'<div class="scaffold-access-people">' +
'<input class="scaffold-access-users">' +
'</div>';
},

renderItem: function(item, escape) {
return Handlebars.templates.scaffoldUsersOption({
name: item.firstName && item.lastName ? escape(item.firstName + ' ' + item.lastName) : false,
email: escape(item.email),
disabled: item.disabled
});
},

fetchUsers: function(callback) {
$.get('api/users')
.done(callback.bind(this))
.fail(error => Origin.Notify.alert({ type: 'error', text: error }));
},

initSelectize: function(users) {
this.$people.val(this.users.join(','));

var meId = Origin.sessionModel.get('id');

users.forEach(function(user) {
if(user._id === meId) user.disabled = true;
});

this.$people.selectize({
labelField: 'email',
valueField: '_id',
options: users,
searchField: [ 'email', 'firstName', 'lastName' ],
render: {
item: this.renderItem,
option: this.renderItem
},
onChange: () => this.trigger('change', this),
onItemRemove: function(value) {
if(value !== Origin.sessionModel.get('id')) {
return;
}
Origin.Notify.alert({
type: 'warning',
text: Origin.l10n.t('app.stopsharingwithyourself')
});
this.addItem(value, true);
this.close();
}
});
},

deriveFromValue: function(value) {
var access = value || {};
this.originalAccess = _.extend({}, access);

var isPublic = access.public;
if(isPublic === undefined) isPublic = this.model.get('_isShared') || false;

var users = access.users;
if(users === undefined) users = this.model.get('_shareWithUsers');
this.users = (users || []).slice();

this.tier = isPublic ? 'anyone' : (this.users.length ? 'specific' : 'onlyme');
},

setTier: function(tier) {
this.tier = tier;
this.togglePeople();
},

togglePeople: function() {
this.$el.find('.scaffold-access-people').toggle(this.tier === 'specific');
},

selectedUsers: function() {
var selectize = this.$people && this.$people[0] && this.$people[0].selectize;
if(selectize) return selectize.getValue();
return this.users;
},

getValue: function() {
var access = _.omit(this.originalAccess || {}, 'public', 'users');
switch(this.tier) {
case 'anyone':
access.public = true;
break;
case 'specific':
access.public = false;
access.users = this.selectedUsers();
break;
default:
access.public = false;
}
return access;
},

setValue: function(value) {
this.deriveFromValue(value);
if(!this.$people) return;
this.$el.find('.scaffold-access-tier[value="' + this.tier + '"]').prop('checked', true);
var selectize = this.$people[0] && this.$people[0].selectize;
if(selectize) selectize.setValue(this.users, true);
this.togglePeople();
},

focus: function() {
if(!this.hasFocus) this.$el.find('input').first().focus();
},

blur: function() {
if(this.hasFocus) this.$el.find('input').first().blur();
}
});

Origin.on('origin:dataReady', function() {
Origin.scaffold.addCustomField('Access', ScaffoldAccessView);
});

return ScaffoldAccessView;
});
Loading