Merge pull request #2973 from FinnStutzenstein/Dialogs
Dialogs for some views
This commit is contained in:
commit
6bad8e8cc6
@ -48,6 +48,8 @@ Core:
|
||||
- Added success/error symbol to config to show if saving was successful.
|
||||
- Added UTF-8 byte order mark for every CSV export.
|
||||
- Moved full-text search to client-side (removed the server-side search engine Whoosh).
|
||||
- Better dialog handling. Show dialog just in forground without changing the state url.
|
||||
Added new dialog for profile, change password, tag and category update view.
|
||||
|
||||
Motions:
|
||||
- Added adjustable line numbering mode (outside, inside, none) for each
|
||||
|
@ -81,6 +81,7 @@ angular.module('OpenSlidesApp.agenda.site', [
|
||||
'$filter',
|
||||
'$http',
|
||||
'$state',
|
||||
'$injector',
|
||||
'DS',
|
||||
'operator',
|
||||
'ngDialog',
|
||||
@ -96,9 +97,9 @@ angular.module('OpenSlidesApp.agenda.site', [
|
||||
'osTableFilter',
|
||||
'AgendaCsvExport',
|
||||
'PdfCreate',
|
||||
function($scope, $filter, $http, $state, DS, operator, ngDialog, Agenda, TopicForm, AgendaTree, Projector,
|
||||
ProjectionDefault, AgendaContentProvider, PdfMakeDocumentProvider, gettextCatalog, gettext, osTableFilter,
|
||||
AgendaCsvExport, PdfCreate) {
|
||||
function($scope, $filter, $http, $state, $injector, DS, operator, ngDialog, Agenda, TopicForm,
|
||||
AgendaTree, Projector, ProjectionDefault, AgendaContentProvider, PdfMakeDocumentProvider,
|
||||
gettextCatalog, gettext, osTableFilter, AgendaCsvExport, PdfCreate) {
|
||||
// Bind agenda tree to the scope
|
||||
$scope.$watch(function () {
|
||||
return Agenda.lastModified();
|
||||
@ -268,13 +269,22 @@ angular.module('OpenSlidesApp.agenda.site', [
|
||||
return false;
|
||||
}
|
||||
};
|
||||
$scope.getUpdateStatePrefix = function (item) {
|
||||
$scope.getDetailStatePrefix = function (item) {
|
||||
var prefix = item.content_object.collection.replace('/','.');
|
||||
// Hotfix for Issue 2566.
|
||||
// The changes could be reverted if Issue 2480 is closed.
|
||||
prefix = prefix.replace('motion-block', 'motionBlock');
|
||||
return prefix;
|
||||
};
|
||||
$scope.edit = function (item) {
|
||||
var formName = item.content_object.collection.split('/')[1];
|
||||
// Hotfix for Issue 2566.
|
||||
// The changes could be reverted if Issue 2480 is closed.
|
||||
formName = formName.replace('motion-block', 'motionBlock');
|
||||
formName = formName.charAt(0).toUpperCase() + formName.slice(1) + 'Form';
|
||||
var form = $injector.get(formName);
|
||||
ngDialog.open(form.getDialog({id: item.content_object.id}));
|
||||
};
|
||||
// export
|
||||
$scope.pdfExport = function () {
|
||||
var filename = gettextCatalog.getString('Agenda') + '.pdf';
|
||||
|
@ -271,7 +271,7 @@
|
||||
<div>
|
||||
<!-- ID and title -->
|
||||
<div>
|
||||
<a class="title" ui-sref="{{ getUpdateStatePrefix(item) }}.detail({id: item.content_object.id})" ng-show="isAllowedToSeeOpenLink(item)">
|
||||
<a class="title" ui-sref="{{ getDetailStatePrefix(item) }}.detail({id: item.content_object.id})" ng-show="isAllowedToSeeOpenLink(item)">
|
||||
{{ item.getListViewTitle() }}
|
||||
</a>
|
||||
<span class="title" ng-hide="isAllowedToSeeOpenLink(item)">
|
||||
@ -283,8 +283,7 @@
|
||||
<small>
|
||||
<a ui-sref="agenda.item.detail({id: item.id})" translate>List of speakers</a>
|
||||
<span os-perms="agenda.can_manage"> ·
|
||||
<a ui-sref="{{ getUpdateStatePrefix(item) }}.detail.update({id: item.content_object.id})"
|
||||
translate>Edit</a> ·
|
||||
<a href="" ng-click="edit(item)" translate>Edit</a> ·
|
||||
<a href="" class="text-danger"
|
||||
ng-bootbox-confirm="{{ 'Are you sure you want to delete this entry?' | translate }}<br>
|
||||
<b>{{ item.getTitle() }}</b>"
|
||||
|
@ -682,8 +682,9 @@ angular.module('OpenSlidesApp.core', [
|
||||
.factory('Projector', [
|
||||
'DS',
|
||||
'$http',
|
||||
'$injector',
|
||||
'Config',
|
||||
function(DS, $http, Config) {
|
||||
function(DS, $http, $injector, Config) {
|
||||
return DS.defineResource({
|
||||
name: 'core/projector',
|
||||
onConflict: 'replace',
|
||||
@ -701,13 +702,13 @@ angular.module('OpenSlidesApp.core', [
|
||||
{"action": action, "direction": direction}
|
||||
);
|
||||
},
|
||||
getStateForCurrentSlide: function () {
|
||||
getFormOrStateForCurrentSlide: function () {
|
||||
var return_dict;
|
||||
angular.forEach(this.elements, function(value, key) {
|
||||
if (value.name == 'agenda/list-of-speakers') {
|
||||
return_dict = {
|
||||
'state': 'agenda.item.detail',
|
||||
'param': {id: value.id}
|
||||
state: 'agenda.item.detail',
|
||||
id: value.id,
|
||||
};
|
||||
} else if (
|
||||
value.name != 'agenda/item-list' &&
|
||||
@ -715,9 +716,14 @@ angular.module('OpenSlidesApp.core', [
|
||||
value.name != 'core/countdown' &&
|
||||
value.name != 'core/projector-message' &&
|
||||
value.name != 'agenda/current-list-of-speakers' ) {
|
||||
var formName = value.name.split('/')[1];
|
||||
// Hotfix for Issue 2566.
|
||||
// The changes could be reverted if Issue 2480 is closed.
|
||||
formName = formName.replace('motion-block', 'motionBlock');
|
||||
formName = formName.charAt(0).toUpperCase() + formName.slice(1) + 'Form';
|
||||
return_dict = {
|
||||
'state': value.name.replace('/', '.')+'.detail.update',
|
||||
'param': {id: value.id}
|
||||
form: $injector.get(formName),
|
||||
id: value.id
|
||||
};
|
||||
}
|
||||
});
|
||||
|
@ -370,25 +370,7 @@ angular.module('OpenSlidesApp.core.site', [
|
||||
basePerm: 'core.can_manage_tags',
|
||||
},
|
||||
})
|
||||
.state('core.tag.list', {})
|
||||
.state('core.tag.create', {})
|
||||
.state('core.tag.detail', {
|
||||
resolve: {
|
||||
tagId: ['$stateParams', function($stateParams) {
|
||||
return $stateParams.id;
|
||||
}],
|
||||
}
|
||||
})
|
||||
.state('core.tag.detail.update', {
|
||||
resolve: {
|
||||
tagId: ['$stateParams', function($stateParams) {
|
||||
return $stateParams.id;
|
||||
}],
|
||||
},
|
||||
views: {
|
||||
'@core.tag': {}
|
||||
}
|
||||
});
|
||||
.state('core.tag.list', {});
|
||||
|
||||
$locationProvider.html5Mode(true);
|
||||
}
|
||||
@ -438,6 +420,38 @@ angular.module('OpenSlidesApp.core.site', [
|
||||
}
|
||||
])
|
||||
|
||||
.factory('TagForm', [
|
||||
'gettextCatalog',
|
||||
function (gettextCatalog) {
|
||||
return {
|
||||
getDialog: function (tag) {
|
||||
return {
|
||||
template: 'static/templates/core/tag-form.html',
|
||||
controller: (tag) ? 'TagUpdateCtrl' : 'TagCreateCtrl',
|
||||
className: 'ngdialog-theme-default wide-form',
|
||||
closeByEscape: false,
|
||||
closeByDocument: false,
|
||||
resolve: {
|
||||
tagId: function () {return tag ? tag.id : void 0;},
|
||||
},
|
||||
};
|
||||
},
|
||||
getFormFields: function() {
|
||||
return [
|
||||
{
|
||||
key: 'name',
|
||||
type: 'input',
|
||||
templateOptions: {
|
||||
label: gettextCatalog.getString('Name'),
|
||||
required: true
|
||||
}
|
||||
},
|
||||
];
|
||||
},
|
||||
};
|
||||
}
|
||||
])
|
||||
|
||||
/* This factory handles the filtering of the OS-data-tables. It contains
|
||||
* all logic needed for the table header filtering. Things to configure:
|
||||
* - multiselectFilters: A dict associating the filter name to a list (empty per default). E.g.
|
||||
@ -615,6 +629,11 @@ angular.module('OpenSlidesApp.core.site', [
|
||||
extends: 'textarea',
|
||||
templateUrl: 'static/templates/core/editor.html',
|
||||
});
|
||||
formlyConfig.setType({
|
||||
name: 'password',
|
||||
extends: 'input',
|
||||
templateUrl: 'static/templates/core/password.html',
|
||||
});
|
||||
formlyConfig.setType({
|
||||
name: 'select-single',
|
||||
extends: 'select',
|
||||
@ -1122,9 +1141,13 @@ angular.module('OpenSlidesApp.core.site', [
|
||||
};
|
||||
|
||||
$scope.editCurrentSlide = function (projector) {
|
||||
var state = projector.getStateForCurrentSlide();
|
||||
if (state) {
|
||||
$state.go(state.state, state.param);
|
||||
var data = projector.getFormOrStateForCurrentSlide();
|
||||
if (data) {
|
||||
if (data.form) {
|
||||
ngDialog.open(data.form.getDialog({id: data.id}));
|
||||
} else {
|
||||
$state.go(data.state, {id: data.id});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -1227,13 +1250,14 @@ angular.module('OpenSlidesApp.core.site', [
|
||||
.controller('ManageProjectorsCtrl', [
|
||||
'$scope',
|
||||
'$http',
|
||||
'$state',
|
||||
'$timeout',
|
||||
'Projector',
|
||||
'ProjectionDefault',
|
||||
'Config',
|
||||
'ProjectorMessage',
|
||||
function ($scope, $http, $state, $timeout, Projector, ProjectionDefault, Config, ProjectorMessage) {
|
||||
'ngDialog',
|
||||
function ($scope, $http, $timeout, Projector, ProjectionDefault, Config,
|
||||
ProjectorMessage, ngDialog) {
|
||||
ProjectionDefault.bindAll({}, $scope, 'projectiondefaults');
|
||||
|
||||
// watch for changes in projector_broadcast
|
||||
@ -1316,9 +1340,13 @@ angular.module('OpenSlidesApp.core.site', [
|
||||
}
|
||||
};
|
||||
$scope.editCurrentSlide = function (projector) {
|
||||
var state = projector.getStateForCurrentSlide();
|
||||
if (state) {
|
||||
$state.go(state.state, state.param);
|
||||
var data = projector.getFormOrStateForCurrentSlide();
|
||||
if (data) {
|
||||
if (data.form) {
|
||||
ngDialog.open(data.form.getDialog({id: data.id}));
|
||||
} else {
|
||||
$state.go(data.state, {id: data.id});
|
||||
}
|
||||
}
|
||||
};
|
||||
$scope.editName = function (projector) {
|
||||
@ -1378,8 +1406,12 @@ angular.module('OpenSlidesApp.core.site', [
|
||||
.controller('TagListCtrl', [
|
||||
'$scope',
|
||||
'Tag',
|
||||
function($scope, Tag) {
|
||||
'ngDialog',
|
||||
'TagForm',
|
||||
'gettext',
|
||||
function($scope, Tag, ngDialog, TagForm, gettext) {
|
||||
Tag.bindAll({}, $scope, 'tags');
|
||||
$scope.alert = {};
|
||||
|
||||
// setup table sorting
|
||||
$scope.sortColumn = 'name';
|
||||
@ -1391,40 +1423,48 @@ angular.module('OpenSlidesApp.core.site', [
|
||||
}
|
||||
$scope.sortColumn = column;
|
||||
};
|
||||
|
||||
// save changed tag
|
||||
$scope.save = function (tag) {
|
||||
Tag.save(tag);
|
||||
};
|
||||
$scope.delete = function (tag) {
|
||||
Tag.destroy(tag.id).then(
|
||||
function(success) {
|
||||
//TODO: success message
|
||||
$scope.alert = {
|
||||
type: 'success',
|
||||
msg: gettext('The delete was successful.'),
|
||||
show: true,
|
||||
};
|
||||
}, function (error) {
|
||||
var message = '';
|
||||
for (var e in error.data) {
|
||||
message += e + ': ' + error.data[e] + ' ';
|
||||
}
|
||||
$scope.alert = {type: 'danger', msg: message, show: true};
|
||||
}
|
||||
);
|
||||
};
|
||||
}
|
||||
])
|
||||
|
||||
.controller('TagDetailCtrl', [
|
||||
'$scope',
|
||||
'Tag',
|
||||
'tagId',
|
||||
function($scope, Tag, tagId) {
|
||||
Tag.bindOne(tagId, $scope, 'tag');
|
||||
$scope.editOrCreate = function (tag) {
|
||||
ngDialog.open(TagForm.getDialog(tag));
|
||||
};
|
||||
}
|
||||
])
|
||||
|
||||
.controller('TagCreateCtrl', [
|
||||
'$scope',
|
||||
'$state',
|
||||
'Tag',
|
||||
function($scope, $state, Tag) {
|
||||
$scope.tag = {};
|
||||
'TagForm',
|
||||
function($scope, Tag, TagForm) {
|
||||
$scope.model = {};
|
||||
$scope.alert = {};
|
||||
$scope.formFields = TagForm.getFormFields();
|
||||
$scope.save = function (tag) {
|
||||
Tag.create(tag).then(
|
||||
function (success) {
|
||||
$state.go('core.tag.list');
|
||||
$scope.closeThisDialog();
|
||||
},
|
||||
function (error) {
|
||||
var message = '';
|
||||
for (var e in error.data) {
|
||||
message += e + ': ' + error.data[e] + ' ';
|
||||
}
|
||||
$scope.alert = {type: 'danger', msg: message, show: true};
|
||||
}
|
||||
);
|
||||
};
|
||||
@ -1433,17 +1473,27 @@ angular.module('OpenSlidesApp.core.site', [
|
||||
|
||||
.controller('TagUpdateCtrl', [
|
||||
'$scope',
|
||||
'$state',
|
||||
'Tag',
|
||||
'tagId',
|
||||
function($scope, $state, Tag, tagId) {
|
||||
$scope.tag = Tag.get(tagId);
|
||||
'TagForm',
|
||||
function($scope, Tag, tagId, TagForm) {
|
||||
$scope.model = angular.copy(Tag.get(tagId));
|
||||
$scope.alert = {};
|
||||
$scope.formFields = TagForm.getFormFields();
|
||||
$scope.save = function (tag) {
|
||||
Tag.save(tag).then(
|
||||
function(success) {
|
||||
$state.go('core.tag.list');
|
||||
Tag.inject(tag);
|
||||
Tag.save(tag).then(function(success) {
|
||||
$scope.closeThisDialog();
|
||||
}, function (error) {
|
||||
// save error: revert all changes by restore
|
||||
// the original object
|
||||
Tag.refresh(tag);
|
||||
var message = '';
|
||||
for (var e in error.data) {
|
||||
message += e + ': ' + error.data[e] + ' ';
|
||||
}
|
||||
);
|
||||
$scope.alert = {type: 'danger', msg: message, show: true};
|
||||
});
|
||||
};
|
||||
}
|
||||
])
|
||||
@ -1493,12 +1543,15 @@ angular.module('OpenSlidesApp.core.site', [
|
||||
// increment unread messages counter for each new message
|
||||
$scope.$watch('chatmessages', function (newVal, oldVal) {
|
||||
// add new message id if there is really a new message which is not yet tracked
|
||||
if (oldVal.length > 0) {
|
||||
if (oldVal.length > 0 && newVal.length > 0) {
|
||||
if ((oldVal[oldVal.length-1].id != newVal[newVal.length-1].id) &&
|
||||
($.inArray(newVal[newVal.length-1].id, NewChatMessages) == -1)) {
|
||||
NewChatMessages.push(newVal[newVal.length-1].id);
|
||||
$scope.unreadMessages = NewChatMessages.length;
|
||||
}
|
||||
} else if (newVal.length === 0) {
|
||||
NewChatMessages = [];
|
||||
$scope.unreadMessages = 0;
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -133,7 +133,7 @@
|
||||
<div class="nobr">
|
||||
<!-- edit -->
|
||||
<a ng-click="editCurrentSlide(projector)"
|
||||
ng-disabled="!projector.getStateForCurrentSlide()"
|
||||
ng-disabled="!projector.getFormOrStateForCurrentSlide()"
|
||||
class="btn btn-default btn-sm"
|
||||
title="{{ 'Edit current slide' | translate}}">
|
||||
<i class="fa fa-pencil"></i>
|
||||
|
1
openslides/core/static/templates/core/password.html
Normal file
1
openslides/core/static/templates/core/password.html
Normal file
@ -0,0 +1 @@
|
||||
<input type="password" ng-model="model[options.key]" class="form-control">
|
@ -86,7 +86,7 @@
|
||||
<div os-perms="core.can_manage_projector" class="nobr">
|
||||
<!-- edit -->
|
||||
<a ng-click="editCurrentSlide(active_projector)"
|
||||
ng-disabled="!active_projector.getStateForCurrentSlide()"
|
||||
ng-disabled="!active_projector.getFormOrStateForCurrentSlide()"
|
||||
class="btn btn-default btn-sm"
|
||||
title="{{ 'Edit current slide' | translate}}">
|
||||
<i class="fa fa-pencil"></i>
|
||||
|
@ -1,14 +0,0 @@
|
||||
<div class="header">
|
||||
<div class="title">
|
||||
<div class="submenu">
|
||||
<a ui-sref="core.tag.list" class="btn btn-sm btn-default">
|
||||
<i class="fa fa-angle-double-left fa-lg"></i>
|
||||
<translate>Back to overview</translate>
|
||||
</a>
|
||||
</div>
|
||||
<h1>{{ tag.name }}</h1>
|
||||
<h2 translate>Tag</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="details"></div>
|
@ -1,28 +1,17 @@
|
||||
<div class="header">
|
||||
<div class="title">
|
||||
<div class="submenu">
|
||||
<a ui-sref="core.tag.list" class="btn btn-sm btn-default">
|
||||
<i class="fa fa-angle-double-left fa-lg"></i>
|
||||
<translate>Back to overview</translate>
|
||||
</a>
|
||||
</div>
|
||||
<h1 ng-if="tag.id" translate>Edit tag</h1>
|
||||
<h1 ng-if="!tag.id" translate>New tag</h1>
|
||||
</div>
|
||||
<h1 ng-if="model.id" translate>Edit tag</h1>
|
||||
<h1 ng-if="!model.id" translate>New tag</h1>
|
||||
|
||||
<div uib-alert ng-show="alert.show" ng-class="'alert-' + (alert.type || 'warning')" close="alert={}">
|
||||
{{ alert.msg }}
|
||||
</div>
|
||||
|
||||
<div class="details">
|
||||
<form name="tagForm">
|
||||
<div class="form-group">
|
||||
<label for="inputName" translate>Name</label>
|
||||
<input type="text" ng-model="tag.name" class="form-control" name="inputName" required>
|
||||
</div>
|
||||
|
||||
<button type="submit" ng-click="save(tag)" class="btn btn-primary" translate>
|
||||
<form name="userForm" ng-submit="save(model)">
|
||||
<formly-form model="model" fields="formFields">
|
||||
<button type="submit" ng-disabled="userForm.$invalid" class="btn btn-primary" translate>
|
||||
Save
|
||||
</button>
|
||||
<button ui-sref="core.tag.list" class="btn btn-default" translate>
|
||||
<button ng-click="closeThisDialog()" class="btn btn-default" translate>
|
||||
Cancel
|
||||
</button>
|
||||
</formly-form>
|
||||
</form>
|
||||
</div>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<i class="fa fa-angle-double-left fa-lg"></i>
|
||||
<translate>Back to overview</translate>
|
||||
</a>
|
||||
<a ui-sref="core.tag.create" os-perms="core.can_manage_tags" class="btn btn-primary btn-sm">
|
||||
<a href="" ng-click="editOrCreate()" os-perms="core.can_manage_tags" class="btn btn-primary btn-sm">
|
||||
<i class="fa fa-plus fa-lg"></i>
|
||||
<translate>New</translate>
|
||||
</a>
|
||||
@ -16,7 +16,11 @@
|
||||
|
||||
<div class="details">
|
||||
<div class="row form-group">
|
||||
<div class="col-sm-8"></div>
|
||||
<div class="col-sm-8">
|
||||
<div uib-alert ng-show="alert.show" ng-class="'alert-' + (alert.type || 'warning')" close="alert={}">
|
||||
{{ alert.msg }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
<input type="text" ng-model="filter.search" class="form-control"
|
||||
placeholder="{{ 'Filter' | translate}}">
|
||||
@ -37,7 +41,7 @@
|
||||
<td ng-mouseover="tag.hover=true" ng-mouseleave="tag.hover=false">
|
||||
<strong>{{ tag.name }}</strong>
|
||||
<div class="hoverActions" ng-class="{'hiddenDiv': !tag.hover}">
|
||||
<a ui-sref="core.tag.detail.update({id: tag.id })" translate>Edit</a> ·
|
||||
<a href="" ng-click="editOrCreate(tag)" translate>Edit</a> ·
|
||||
<a href="" class="text-danger"
|
||||
ng-bootbox-confirm="{{ 'Are you sure you want to delete this entry?' | translate }}<br>
|
||||
<b>{{ tag.name }}</b>"
|
||||
|
@ -91,12 +91,13 @@
|
||||
</a>
|
||||
<ul class="dropdown-menu pull-right" uib-dropdown-menu aria-labelledby="user-settings-dropdown">
|
||||
<li>
|
||||
<a ui-sref="users.user.detail.profile({ id: operator.user.id })">
|
||||
<!--<a ui-sref="users.user.detail.profile({ id: operator.user.id })">-->
|
||||
<a href="" ng-click="editProfile()">
|
||||
<i class="fa fa-cog"></i>
|
||||
<translate>Edit profile</translate>
|
||||
</a>
|
||||
<li>
|
||||
<a ui-sref="users.user.detail.password({ id: operator.user.id })">
|
||||
<a href="" ng-click="changePassword()">
|
||||
<i class="fa fa-key"></i>
|
||||
<translate>Change password</translate>
|
||||
</a>
|
||||
|
@ -153,7 +153,7 @@ angular.module('OpenSlidesApp.motions.motionBlock', [])
|
||||
$scope.defaultProjectorId = projectiondefault.projector_id;
|
||||
}
|
||||
});
|
||||
$scope.openDialog = function (topic) {
|
||||
$scope.openDialog = function (motionBlock) {
|
||||
ngDialog.open(MotionBlockForm.getDialog(motionBlock));
|
||||
};
|
||||
$scope.followRecommendations = function () {
|
||||
|
@ -103,19 +103,6 @@ angular.module('OpenSlidesApp.motions.site', [
|
||||
},
|
||||
})
|
||||
.state('motions.category.list', {})
|
||||
.state('motions.category.create', {})
|
||||
.state('motions.category.detail', {
|
||||
resolve: {
|
||||
categoryId: ['$stateParams', function($stateParams) {
|
||||
return $stateParams.id;
|
||||
}]
|
||||
}
|
||||
})
|
||||
.state('motions.category.detail.update', {
|
||||
views: {
|
||||
'@motions.category': {}
|
||||
}
|
||||
})
|
||||
.state('motions.category.sort', {
|
||||
url: '/sort/{id}',
|
||||
controller: 'CategorySortCtrl',
|
||||
@ -524,6 +511,45 @@ angular.module('OpenSlidesApp.motions.site', [
|
||||
}
|
||||
])
|
||||
|
||||
.factory('CategoryForm', [
|
||||
'gettextCatalog',
|
||||
function (gettextCatalog) {
|
||||
return {
|
||||
getDialog: function (category) {
|
||||
return {
|
||||
template: 'static/templates/motions/category-form.html',
|
||||
controller: category ? 'CategoryUpdateCtrl' : 'CategoryCreateCtrl',
|
||||
className: 'ngdialog-theme-default wide-form',
|
||||
closeByEscape: false,
|
||||
closeByDocument: false,
|
||||
resolve: {
|
||||
categoryId: function () {return category ? category.id : void 0;},
|
||||
},
|
||||
};
|
||||
|
||||
},
|
||||
getFormFields: function () {
|
||||
return [
|
||||
{
|
||||
key: 'prefix',
|
||||
type: 'input',
|
||||
templateOptions: {
|
||||
label: gettextCatalog.getString('Prefix')
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'name',
|
||||
type: 'input',
|
||||
templateOptions: {
|
||||
label: gettextCatalog.getString('Name')
|
||||
},
|
||||
}
|
||||
];
|
||||
},
|
||||
};
|
||||
}
|
||||
])
|
||||
|
||||
// Provide generic motionpoll form fields for poll update view
|
||||
.factory('MotionPollForm', [
|
||||
'gettextCatalog',
|
||||
@ -1780,7 +1806,9 @@ angular.module('OpenSlidesApp.motions.site', [
|
||||
.controller('CategoryListCtrl', [
|
||||
'$scope',
|
||||
'Category',
|
||||
function($scope, Category) {
|
||||
'ngDialog',
|
||||
'CategoryForm',
|
||||
function($scope, Category, ngDialog, CategoryForm) {
|
||||
Category.bindAll({}, $scope, 'categories');
|
||||
|
||||
// setup table sorting
|
||||
@ -1798,28 +1826,31 @@ angular.module('OpenSlidesApp.motions.site', [
|
||||
$scope.delete = function (category) {
|
||||
Category.destroy(category.id);
|
||||
};
|
||||
}
|
||||
])
|
||||
|
||||
.controller('CategoryDetailCtrl', [
|
||||
'$scope',
|
||||
'Category',
|
||||
'categoryId',
|
||||
function($scope, Category, categoryId) {
|
||||
Category.bindOne(categoryId, $scope, 'category');
|
||||
$scope.editOrCreate = function (category) {
|
||||
ngDialog.open(CategoryForm.getDialog(category));
|
||||
};
|
||||
}
|
||||
])
|
||||
|
||||
.controller('CategoryCreateCtrl', [
|
||||
'$scope',
|
||||
'$state',
|
||||
'Category',
|
||||
function($scope, $state, Category) {
|
||||
$scope.category = {};
|
||||
'CategoryForm',
|
||||
function($scope, Category, CategoryForm) {
|
||||
$scope.model = {};
|
||||
$scope.alert = {};
|
||||
$scope.formFields = CategoryForm.getFormFields();
|
||||
$scope.save = function (category) {
|
||||
Category.create(category).then(
|
||||
function(success) {
|
||||
$state.go('motions.category.list');
|
||||
$scope.closeThisDialog();
|
||||
},
|
||||
function (error) {
|
||||
var message = '';
|
||||
for (var e in error.data) {
|
||||
message += e + ': ' + error.data[e] + ' ';
|
||||
}
|
||||
$scope.alert = {type: 'danger', msg: message, show: true};
|
||||
}
|
||||
);
|
||||
};
|
||||
@ -1828,15 +1859,28 @@ angular.module('OpenSlidesApp.motions.site', [
|
||||
|
||||
.controller('CategoryUpdateCtrl', [
|
||||
'$scope',
|
||||
'$state',
|
||||
'Category',
|
||||
'categoryId',
|
||||
function($scope, $state, Category, categoryId) {
|
||||
$scope.category = Category.get(categoryId);
|
||||
'CategoryForm',
|
||||
function($scope, Category, categoryId, CategoryForm) {
|
||||
$scope.alert = {};
|
||||
$scope.model = angular.copy(Category.get(categoryId));
|
||||
$scope.formFields = CategoryForm.getFormFields();
|
||||
$scope.save = function (category) {
|
||||
Category.inject(category);
|
||||
Category.save(category).then(
|
||||
function(success) {
|
||||
$state.go('motions.category.list');
|
||||
$scope.closeThisDialog();
|
||||
},
|
||||
function (error) {
|
||||
// save error: revert all changes by restore
|
||||
// (refresh) original category object from server
|
||||
Category.refresh(category);
|
||||
var message = '';
|
||||
for (var e in error.data) {
|
||||
message += e + ': ' + error.data[e] + ' ';
|
||||
}
|
||||
$scope.alert = {type: 'danger', msg: message, show: true};
|
||||
}
|
||||
);
|
||||
};
|
||||
|
@ -1,17 +0,0 @@
|
||||
<div class="header">
|
||||
<div class="title">
|
||||
<div class="submenu">
|
||||
<a ui-sref="motions.category.list" class="btn btn-sm btn-default">
|
||||
<i class="fa fa-angle-double-left fa-lg"></i>
|
||||
<translate>Back to overview</translate>
|
||||
</a>
|
||||
</div>
|
||||
<h1>{{ category.name }}</h1>
|
||||
<h2 translate>Category</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="details">
|
||||
<strong translate>Prefix:</strong>
|
||||
{{ category.prefix }}
|
||||
</div>
|
@ -1,32 +1,17 @@
|
||||
<div class="header">
|
||||
<div class="title">
|
||||
<div class="submenu">
|
||||
<a ui-sref="motions.category.list" class="btn btn-sm btn-default">
|
||||
<i class="fa fa-angle-double-left fa-lg"></i>
|
||||
<translate>Back to overview</translate>
|
||||
</a>
|
||||
</div>
|
||||
<h1 ng-if="category.id" translate>Edit category</h1>
|
||||
<h1 ng-if="!category.id" translate>New category</h1>
|
||||
</div>
|
||||
<h1 ng-if="model.id" translate>Edit category</h1>
|
||||
<h1 ng-if="!model.id" translate>New category</h1>
|
||||
|
||||
<div uib-alert ng-show="alert.show" ng-class="'alert-' + (alert.type || 'warning')" close="alert={}">
|
||||
{{ alert.msg }}
|
||||
</div>
|
||||
|
||||
<div class="details">
|
||||
<form name="groupForm">
|
||||
<div class="form-group">
|
||||
<label for="inputPrefix" translate>Prefix</label>
|
||||
<input type="text" ng-model="category.prefix" class="form-control" name="inputPrefix">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="inputName" translate>Name</label>
|
||||
<input type="text" ng-model="category.name" class="form-control" name="inputName" ng-required="true">
|
||||
</div>
|
||||
|
||||
<button type="submit" ng-click="save(category)" class="btn btn-primary" translate>
|
||||
<form name="categoryForm" ng-submit="save(model)">
|
||||
<formly-form model="model" fields="formFields">
|
||||
<button type="submit" ng-disabled="categoryForm.$invalid" class="btn btn-primary" translate>
|
||||
Save
|
||||
</button>
|
||||
<button ui-sref="motions.category.list" class="btn btn-default" translate>
|
||||
<button ng-click="closeThisDialog()" class="btn btn-default" translate>
|
||||
Cancel
|
||||
</button>
|
||||
</formly-form>
|
||||
</form>
|
||||
</div>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<i class="fa fa-angle-double-left fa-lg"></i>
|
||||
<translate>Back to overview</translate>
|
||||
</a>
|
||||
<a ui-sref="motions.category.create" os-perms="motions.can_manage" class="btn btn-primary btn-sm">
|
||||
<a href="" os-perms="motions.can_manage" class="btn btn-primary btn-sm" ng-click="editOrCreate()">
|
||||
<i class="fa fa-plus fa-lg"></i>
|
||||
<translate>New</translate>
|
||||
</a>
|
||||
@ -43,7 +43,7 @@
|
||||
<!-- sort -->
|
||||
<a ui-sref="motions.category.sort({ id: category.id })" translate>Sort</a> |
|
||||
<!-- edit -->
|
||||
<a ui-sref="motions.category.detail.update({id: category.id })" translate>Edit</a> |
|
||||
<a href="" ng-click="editOrCreate(category)" translate>Edit</a> |
|
||||
<!-- delete -->
|
||||
<a href="" class="text-danger"
|
||||
ng-bootbox-confirm="{{ 'Are you sure you want to delete this entry?' | translate }}<br>
|
||||
|
@ -1,9 +1,9 @@
|
||||
<h1 ng-if="model.id" translate>Edit change recommendation</h1>
|
||||
<h1 ng-if="!model.id" translate>New change recommendation</h1>
|
||||
|
||||
<uib-alert ng-show="alert.show" type="{{ alert.type }}" ng-click="alert={}" close="alert={}">
|
||||
<div uib-alert ng-show="alert.show" ng-class="'alert-' + (alert.type || 'warning')" close="alert={}">
|
||||
{{ alert.msg }}
|
||||
</uib-alert>
|
||||
</div>
|
||||
|
||||
<form name="changeRecommendationForm" ng-submit="save(model)">
|
||||
<formly-form model="model" fields="formFields">
|
||||
|
@ -1,7 +1,7 @@
|
||||
<h1 ng-if="model.id" translate>Edit motion block</h1>
|
||||
<h1 ng-if="!model.id" translate>New motion block</h1>
|
||||
|
||||
<div uib-alert ng-show="alert.show" ng-class="'alert-' + (alert.type || 'warning')" ng-click="alert={}" close="alert={}">
|
||||
<div uib-alert ng-show="alert.show" ng-class="'alert-' + (alert.type || 'warning')" close="alert={}">
|
||||
{{ alert.msg }}
|
||||
</div>
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
<h1 ng-if="!model.id && !parent" translate>New motion</h1>
|
||||
<h1 ng-if="parent"><translate>New amendment of motion</translate> {{ parent.identifier || parent.getTitle() }}</h1>
|
||||
|
||||
<div uib-alert ng-show="alert.show" ng-class="'alert-' + (alert.type || 'warning')" ng-click="alert={}" close="alert={}">
|
||||
<div uib-alert ng-show="alert.show" ng-class="'alert-' + (alert.type || 'warning')" close="alert={}">
|
||||
{{ alert.msg }}
|
||||
</div>
|
||||
|
||||
|
@ -10,9 +10,9 @@ class UserAccessPermissions(BaseAccessPermissions):
|
||||
"""
|
||||
def check_permissions(self, user):
|
||||
"""
|
||||
Returns True if the user has read access model instances.
|
||||
Every user has read access for their model instnces.
|
||||
"""
|
||||
return has_perm(user, 'users.can_see_name')
|
||||
return True
|
||||
|
||||
def get_serializer_class(self, user=None):
|
||||
"""
|
||||
|
@ -62,40 +62,6 @@ angular.module('OpenSlidesApp.users.site', [
|
||||
}]
|
||||
}
|
||||
})
|
||||
// Redirects to user detail view and opens user edit form dialog, uses edit url.
|
||||
// Used by $state.go(..) from core/site.js only (for edit current slide button).
|
||||
// (from users list controller use UserForm factory instead to open dialog in front of
|
||||
// current view without redirect)
|
||||
.state('users.user.detail.update', {
|
||||
onEnter: ['$stateParams', '$state', 'ngDialog',
|
||||
function($stateParams, $state, ngDialog) {
|
||||
ngDialog.open({
|
||||
template: 'static/templates/users/user-form.html',
|
||||
controller: 'UserUpdateCtrl',
|
||||
className: 'ngdialog-theme-default wide-form',
|
||||
closeByEscape: false,
|
||||
closeByDocument: false,
|
||||
resolve: {
|
||||
userId: function() {return $stateParams.id;}
|
||||
}
|
||||
});
|
||||
}
|
||||
]
|
||||
})
|
||||
.state('users.user.detail.profile', {
|
||||
views: {
|
||||
'@users.user': {},
|
||||
},
|
||||
url: '/profile',
|
||||
controller: 'UserProfileCtrl',
|
||||
})
|
||||
.state('users.user.detail.password', {
|
||||
views: {
|
||||
'@users.user': {},
|
||||
},
|
||||
url: '/password',
|
||||
controller: 'UserPasswordCtrl',
|
||||
})
|
||||
.state('users.user.change-password', {
|
||||
url: '/change-password/{id}',
|
||||
controller: 'UserChangePasswordCtrl',
|
||||
@ -417,6 +383,146 @@ angular.module('OpenSlidesApp.users.site', [
|
||||
}
|
||||
])
|
||||
|
||||
.factory('UserProfileForm', [
|
||||
'gettextCatalog',
|
||||
'Editor',
|
||||
'Mediafile',
|
||||
function (gettextCatalog, Editor, Mediafile) {
|
||||
return {
|
||||
// ngDialog for user form
|
||||
getDialog: function (user) {
|
||||
return {
|
||||
template: 'static/templates/users/profile-password-form.html',
|
||||
controller: 'UserProfileCtrl',
|
||||
className: 'ngdialog-theme-default wide-form',
|
||||
closeByEscape: false,
|
||||
closeByDocument: false,
|
||||
};
|
||||
},
|
||||
// angular-formly fields for user form
|
||||
getFormFields: function (hideOnCreateForm) {
|
||||
var images = Mediafile.getAllImages();
|
||||
return [
|
||||
{
|
||||
key: 'username',
|
||||
type: 'input',
|
||||
templateOptions: {
|
||||
label: gettextCatalog.getString('Username'),
|
||||
required: true
|
||||
},
|
||||
},
|
||||
{
|
||||
className: "row",
|
||||
fieldGroup: [
|
||||
{
|
||||
key: 'title',
|
||||
type: 'input',
|
||||
className: "col-xs-2 no-padding-left",
|
||||
templateOptions: {
|
||||
label: gettextCatalog.getString('Title')
|
||||
}
|
||||
},
|
||||
{
|
||||
key: 'first_name',
|
||||
type: 'input',
|
||||
className: "col-xs-5 no-padding",
|
||||
templateOptions: {
|
||||
label: gettextCatalog.getString('Given name')
|
||||
}
|
||||
},
|
||||
{
|
||||
key: 'last_name',
|
||||
type: 'input',
|
||||
className: "col-xs-5 no-padding-right",
|
||||
templateOptions: {
|
||||
label: gettextCatalog.getString('Surname')
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
className: "row",
|
||||
fieldGroup: [
|
||||
{
|
||||
key: 'structure_level',
|
||||
type: 'input',
|
||||
className: "col-xs-9 no-padding-left",
|
||||
templateOptions: {
|
||||
label: gettextCatalog.getString('Structure level'),
|
||||
}
|
||||
},
|
||||
{ key: 'number',
|
||||
type: 'input',
|
||||
className: "col-xs-3 no-padding-left no-padding-right",
|
||||
templateOptions: {
|
||||
label:gettextCatalog.getString('Participant number')
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
key: 'about_me',
|
||||
type: 'editor',
|
||||
templateOptions: {
|
||||
label: gettextCatalog.getString('About me'),
|
||||
},
|
||||
data: {
|
||||
ckeditorOptions: Editor.getOptions(images)
|
||||
},
|
||||
}
|
||||
];
|
||||
}
|
||||
};
|
||||
}
|
||||
])
|
||||
|
||||
.factory('UserPasswordForm', [
|
||||
'gettextCatalog',
|
||||
function (gettextCatalog) {
|
||||
return {
|
||||
// ngDialog for user form
|
||||
getDialog: function (user) {
|
||||
return {
|
||||
template: 'static/templates/users/profile-password-form.html',
|
||||
controller: 'UserPasswordCtrl',
|
||||
className: 'ngdialog-theme-default wide-form',
|
||||
closeByEscape: false,
|
||||
closeByDocument: false,
|
||||
};
|
||||
},
|
||||
// angular-formly fields for user form
|
||||
getFormFields: function (hideOnCreateForm) {
|
||||
return [
|
||||
{
|
||||
key: 'oldPassword',
|
||||
type: 'password',
|
||||
templateOptions: {
|
||||
label: gettextCatalog.getString('Old password'),
|
||||
required: true
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'newPassword',
|
||||
type: 'password',
|
||||
templateOptions: {
|
||||
label: gettextCatalog.getString('New password'),
|
||||
required: true
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'newPassword2',
|
||||
type: 'password',
|
||||
templateOptions: {
|
||||
label: gettextCatalog.getString('Confirm new password'),
|
||||
required: true
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
};
|
||||
}
|
||||
])
|
||||
|
||||
.controller('UserListCtrl', [
|
||||
'$scope',
|
||||
'$state',
|
||||
@ -761,20 +867,30 @@ angular.module('OpenSlidesApp.users.site', [
|
||||
|
||||
.controller('UserProfileCtrl', [
|
||||
'$scope',
|
||||
'$state',
|
||||
'Editor',
|
||||
'User',
|
||||
'userId',
|
||||
function($scope, $state, Editor, User, userId) {
|
||||
$scope.user = angular.copy(User.get(userId));
|
||||
$scope.ckeditorOptions = Editor.getOptions();
|
||||
'operator',
|
||||
'UserProfileForm',
|
||||
'gettext',
|
||||
function($scope, Editor, User, operator, UserProfileForm, gettext) {
|
||||
$scope.model = angular.copy(operator.user);
|
||||
$scope.title = gettext('Edit profile');
|
||||
$scope.formFields = UserProfileForm.getFormFields();
|
||||
$scope.save = function (user) {
|
||||
User.inject(user);
|
||||
User.save(user).then(
|
||||
function(success) {
|
||||
$state.go('users.user.list');
|
||||
$scope.closeThisDialog();
|
||||
},
|
||||
function(error) {
|
||||
$scope.formError = error;
|
||||
// save error: revert all changes by restore
|
||||
// (refresh) original user object from server
|
||||
User.refresh(user);
|
||||
var message = '';
|
||||
for (var e in error.data) {
|
||||
message += e + ': ' + error.data[e] + ' ';
|
||||
}
|
||||
$scope.alert = {type: 'danger', msg: message, show: true};
|
||||
}
|
||||
);
|
||||
};
|
||||
@ -818,24 +934,38 @@ angular.module('OpenSlidesApp.users.site', [
|
||||
'$scope',
|
||||
'$state',
|
||||
'$http',
|
||||
function($scope, $state, $http) {
|
||||
$scope.save = function () {
|
||||
if ($scope.newPassword != $scope.newPassword2) {
|
||||
$scope.newPassword = $scope.newPassword2 = '';
|
||||
$scope.formError = 'Password confirmation does not match.';
|
||||
'gettext',
|
||||
'UserPasswordForm',
|
||||
function($scope, $state, $http, gettext, UserPasswordForm) {
|
||||
$scope.title = 'Change password';
|
||||
$scope.alert = {};
|
||||
$scope.model = {};
|
||||
$scope.formFields = UserPasswordForm.getFormFields();
|
||||
$scope.save = function (data) {
|
||||
if (data.newPassword != data.newPassword2) {
|
||||
data.newPassword = data.newPassword2 = '';
|
||||
$scope.alert = {
|
||||
type: 'danger',
|
||||
msg: gettext('Password confirmation does not match.'),
|
||||
show: true,
|
||||
};
|
||||
} else {
|
||||
$http.post(
|
||||
'/users/setpassword/',
|
||||
{'old_password': $scope.oldPassword, 'new_password': $scope.newPassword}
|
||||
{'old_password': data.oldPassword, 'new_password': data.newPassword}
|
||||
).then(
|
||||
function (response) {
|
||||
// Success.
|
||||
$state.go('users.user.list');
|
||||
function (success) {
|
||||
$scope.closeThisDialog();
|
||||
},
|
||||
function (response) {
|
||||
function (error) {
|
||||
// Error, e. g. wrong old password.
|
||||
$scope.oldPassword = $scope.newPassword = $scope.newPassword2 = '';
|
||||
$scope.formError = response.data.detail;
|
||||
$scope.model = {};
|
||||
|
||||
var message = '';
|
||||
for (var e in error.data) {
|
||||
message += e + ': ' + error.data[e] + ' ';
|
||||
}
|
||||
$scope.alert = {type: 'danger', msg: message, show: true};
|
||||
}
|
||||
);
|
||||
}
|
||||
@ -1342,13 +1472,21 @@ angular.module('OpenSlidesApp.users.site', [
|
||||
'User',
|
||||
'operator',
|
||||
'ngDialog',
|
||||
function($scope, $http, DS, User, operator, ngDialog) {
|
||||
'UserProfileForm',
|
||||
'UserPasswordForm',
|
||||
function($scope, $http, DS, User, operator, ngDialog, UserProfileForm, UserPasswordForm) {
|
||||
$scope.logout = function () {
|
||||
$http.post('/users/logout/').then(function (response) {
|
||||
operator.setUser(null);
|
||||
window.location.reload();
|
||||
});
|
||||
};
|
||||
$scope.editProfile = function () {
|
||||
ngDialog.open(UserProfileForm.getDialog());
|
||||
};
|
||||
$scope.changePassword = function () {
|
||||
ngDialog.open(UserPasswordForm.getDialog());
|
||||
};
|
||||
}
|
||||
])
|
||||
|
||||
|
@ -0,0 +1,16 @@
|
||||
<h1>{{ title | translate }}</h1>
|
||||
|
||||
<div uib-alert ng-show="alert.show" ng-class="'alert-' + (alert.type || 'warning')" close="alert={}">
|
||||
{{ alert.msg }}
|
||||
</div>
|
||||
|
||||
<form name="profileForm" ng-submit="save(model)">
|
||||
<formly-form model="model" fields="formFields">
|
||||
<button type="submit" ng-disabled="profileForm.$invalid" class="btn btn-primary" translate>
|
||||
Save
|
||||
</button>
|
||||
<button ng-click="closeThisDialog()" class="btn btn-default" translate>
|
||||
Cancel
|
||||
</button>
|
||||
</formly-form>
|
||||
</form>
|
@ -1,43 +0,0 @@
|
||||
<div class="header">
|
||||
<div class="title">
|
||||
<h1 translate>Change password</h1>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="details">
|
||||
<p ng-if='formError' class="text-danger">
|
||||
<strong>{{ formError }}</strong>
|
||||
</p>
|
||||
<form name="userForm" >
|
||||
<div class="form-group">
|
||||
<label for="inputOldPassword" translate>Old password</label>
|
||||
<input type="password"
|
||||
ng-model="oldPassword"
|
||||
class="form-control"
|
||||
name="inputOldPassword"
|
||||
required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="inputNewPassword" translate>New password</label>
|
||||
<input type="password"
|
||||
ng-model="newPassword"
|
||||
class="form-control"
|
||||
name="inputNewPassword"
|
||||
required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="inputNewPassword2" translate>Confirm new password</label>
|
||||
<input type="password"
|
||||
ng-model="newPassword2"
|
||||
class="form-control"
|
||||
name="inputNewPassword2"
|
||||
required>
|
||||
</div>
|
||||
<button type="submit" ng-click="save()" class="btn btn-primary" translate>
|
||||
Save
|
||||
</button>
|
||||
<button ui-sref="users.user.list" class="btn btn-default" translate>
|
||||
Cancel
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
@ -1,50 +0,0 @@
|
||||
<div class="header">
|
||||
<div class="title">
|
||||
<h1 translate>Edit profile</h1>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="details">
|
||||
<p ng-if='formError' class="text-danger">
|
||||
<strong>{{ formError }}</strong>
|
||||
</p>
|
||||
<form name="userForm" >
|
||||
<div class="form-group">
|
||||
<label for="inputUsername" translate>Username</label>
|
||||
<input type="text"
|
||||
ng-model="user.username"
|
||||
class="form-control"
|
||||
name="inputUsername"
|
||||
required>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<div class="col-xs-2">
|
||||
<label for="inputTitle" translate-comment="academic degree" translate>Title</label>
|
||||
<input type="text" ng-model="user.title" class="form-control" name="inputTitle">
|
||||
</div>
|
||||
<div class="col-xs-5">
|
||||
<label for="inputFirstName" translate>Given name</label>
|
||||
<input type="text" ng-model="user.first_name" class="form-control" name="inputFirstName">
|
||||
</div>
|
||||
<div class="col-xs-5">
|
||||
<label for="inputLastName" translate>Surname</label>
|
||||
<input type="text" ng-model="user.last_name" class="form-control" name="inputLastName">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="inputStructureLevel" translate>Structure level</label>
|
||||
<input type="text" ng-model="user.structure_level" class="form-control" name="inputStructureLevel">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="textAbout" translate>About me</label>
|
||||
<textarea ng-model="user.about_me" class="form-control" name="textAbout" />
|
||||
</div>
|
||||
|
||||
<button type="submit" ng-click="save(user)" class="btn btn-primary" translate>
|
||||
Save
|
||||
</button>
|
||||
<button ui-sref="users.user.list" class="btn btn-default" translate>
|
||||
Cancel
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
@ -1,7 +1,7 @@
|
||||
<h1 ng-if="model.id" translate>Edit participant</h1>
|
||||
<h1 ng-if="!model.id" translate>New participant</h1>
|
||||
|
||||
<div uib-alert ng-show="alert.show" ng-class="'alert-' + (alert.type || 'warning')" ng-click="alert={}" close="alert={}">
|
||||
<div uib-alert ng-show="alert.show" ng-class="'alert-' + (alert.type || 'warning')" close="alert={}">
|
||||
{{ alert.msg }}
|
||||
</div>
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
from django.contrib.auth import login as auth_login
|
||||
from django.contrib.auth import logout as auth_logout
|
||||
from django.contrib.auth import update_session_auth_hash
|
||||
from django.contrib.auth.forms import AuthenticationForm
|
||||
from django.utils.encoding import force_text
|
||||
from django.utils.translation import ugettext as _
|
||||
@ -39,8 +40,10 @@ class UserViewSet(ModelViewSet):
|
||||
"""
|
||||
if self.action in ('list', 'retrieve'):
|
||||
result = self.get_access_permissions().check_permissions(self.request.user)
|
||||
elif self.action in ('metadata', 'update', 'partial_update'):
|
||||
elif self.action == 'metadata':
|
||||
result = has_perm(self.request.user, 'users.can_see_name')
|
||||
elif self.action in ('update', 'partial_update'):
|
||||
result = self.request.user.is_authenticated()
|
||||
elif self.action in ('create', 'destroy', 'reset_password'):
|
||||
result = (has_perm(self.request.user, 'users.can_see_name') and
|
||||
has_perm(self.request.user, 'users.can_see_extra_data') and
|
||||
@ -264,6 +267,7 @@ class SetPasswordView(APIView):
|
||||
if user.check_password(request.data['old_password']):
|
||||
user.set_password(request.data['new_password'])
|
||||
user.save()
|
||||
update_session_auth_hash(request, user)
|
||||
else:
|
||||
raise ValidationError({'detail': _('Old password does not match.')})
|
||||
return super().post(request, *args, **kwargs)
|
||||
|
Loading…
Reference in New Issue
Block a user