Skip to content

Commit

Permalink
Merge pull request #964 from amosfolz/issue-#867
Browse files Browse the repository at this point in the history
Allow null group assignment for users (Issue #867)
  • Loading branch information
lcharette authored Jul 12, 2019
2 parents 0e3734b + 71b2cd1 commit 161ee0f
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 41 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php

/*
* UserFrosting (http://www.userfrosting.com)
*
* @link https://github.com/userfrosting/UserFrosting
* @copyright Copyright (c) 2019 Alexander Weissman
* @license https://github.com/userfrosting/UserFrosting/blob/master/LICENSE.md (MIT License)
*/

namespace UserFrosting\Sprinkle\Account\Database\Migrations\v430;

use Illuminate\Database\Schema\Blueprint;
use UserFrosting\Sprinkle\Core\Database\Migration;

/**
* Groups table migration
* Changes `group_id` column properties to allow user to be created without a group.
* Version 4.3.0.
*
* See https://laravel.com/docs/5.4/migrations#tables
*
* @author Amos Folz
*/
class UpdateUsersTable extends Migration
{
/**
* {@inheritdoc}
*/
public static $dependencies = [
'\UserFrosting\Sprinkle\Account\Database\Migrations\v400\GroupsTable',
'\UserFrosting\Sprinkle\Account\Database\Migrations\v400\UsersTable',
'\UserFrosting\Sprinkle\Account\Database\Migrations\v420\AddingForeignKeys',
];

/**
* {@inheritdoc}
*/
public function up()
{
if ($this->schema->hasTable('users')) {
$this->schema->table('users', function (Blueprint $table) {
$table->unsignedInteger('group_id')->default(null)->comment('The id of the user group.')->nullable()->change();
});
}
}

/**
* {@inheritdoc}
*/
public function down()
{
$this->schema->table('users', function (Blueprint $table) {
$table->unsignedInteger('group_id')->default(1)->comment('The id of the user group.')->change();
});
}
}
82 changes: 42 additions & 40 deletions app/sprinkles/admin/assets/userfrosting/js/widgets/users.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* Set up the form in a modal after being successfully attached to the body.
*/
function attachUserForm() {
$("body").on('renderSuccess.ufModal', function (data) {
$("body").on('renderSuccess.ufModal', function(data) {
var modal = $(this).ufModal('getModal');
var form = modal.find('.js-form');

Expand All @@ -15,6 +15,8 @@ function attachUserForm() {
width: '100%'
});



// Set up the form for submission
form.ufForm({
validator: page.validators
Expand Down Expand Up @@ -42,14 +44,14 @@ function toggleChangePasswordMode(el, userName, changePasswordMode) {
if (validator) {
//Iterate through named elements inside of the form, and mark them as error free
el.find("input[type='password']").each(function() {
validator.successList.push(this); //mark as error free
validator.successList.push(this); //mark as error free
});
validator.resetForm();//remove error class on name elements and clear history
validator.reset();//remove all error and success data
validator.resetForm(); //remove error class on name elements and clear history
validator.reset(); //remove all error and success data
}
el.find("input[type='password']").closest('.form-group')
.removeClass('has-error has-success');
el.find('.form-control-feedback').each(function () {
.removeClass('has-error has-success');
el.find('.form-control-feedback').each(function() {
$(this).remove();
});
} else {
Expand All @@ -66,7 +68,7 @@ function toggleChangePasswordMode(el, userName, changePasswordMode) {
* Update user field(s)
*/
function updateUser(userName, fieldName, fieldValue) {
var data = {
var data = {
'value': fieldValue
};

Expand All @@ -92,19 +94,19 @@ function updateUser(userName, fieldName, fieldValue) {
return $.parseJSON(result);
}
} catch (e) {
// statements to handle any exceptions
console.log("Warning: Could not parse expected JSON response.");
return {};
// statements to handle any exceptions
console.log("Warning: Could not parse expected JSON response.");
return {};
}
}
}
}).fail(function (jqXHR) {
}).fail(function(jqXHR) {
// Error messages
if (debugAjax && jqXHR.responseText) {
document.write(jqXHR.responseText);
document.close();
} else {
console.log("Error (" + jqXHR.status + "): " + jqXHR.responseText );
console.log("Error (" + jqXHR.status + "): " + jqXHR.responseText);

// Display errors on failure
// TODO: ufAlerts widget should have a 'destroy' method
Expand All @@ -113,12 +115,12 @@ function updateUser(userName, fieldName, fieldValue) {
} else {
$("#alerts-page").ufAlerts('clear');
}

$("#alerts-page").ufAlerts('fetch').ufAlerts('render');
}

return jqXHR;
}).done(function (response) {
}).done(function(response) {
window.location.reload();
});
}
Expand All @@ -128,8 +130,8 @@ function updateUser(userName, fieldName, fieldValue) {
* @param {module:jQuery} el jQuery wrapped element to target.
* @param {{delete_redirect: string}} options Options used to modify behaviour of button actions.
*/
function bindUserButtons(el, options) {
if (!options) options = {};
function bindUserButtons(el, options) {
if (!options) options = {};

/**
* Buttons that launch a modal dialog
Expand Down Expand Up @@ -162,38 +164,38 @@ function updateUser(userName, fieldName, fieldValue) {
msgTarget: $("#alerts-page")
});

$("body").on('renderSuccess.ufModal', function (data) {
$("body").on('renderSuccess.ufModal', function(data) {
var modal = $(this).ufModal('getModal');
var form = modal.find('.js-form');

// Set up collection widget
var roleWidget = modal.find('.js-form-roles');
roleWidget.ufCollection({
dropdown : {
dropdown: {
ajax: {
url : site.uri.public + '/api/roles'
url: site.uri.public + '/api/roles'
},
placeholder : "Select a role"
placeholder: "Select a role"
},
dropdownTemplate: modal.find('#user-roles-select-option').html(),
rowTemplate : modal.find('#user-roles-row').html()
rowTemplate: modal.find('#user-roles-row').html()
});

// Get current roles and add to widget
$.getJSON(site.uri.public + '/api/users/u/' + userName + '/roles')
.done(function (data) {
$.each(data.rows, function (idx, role) {
role.text = role.name;
roleWidget.ufCollection('addRow', role);
.done(function(data) {
$.each(data.rows, function(idx, role) {
role.text = role.name;
roleWidget.ufCollection('addRow', role);
});
});
});

// Set up form for submission
form.ufForm()
.on("submitSuccess.ufForm", function() {
// Reload page on success
window.location.reload();
});
.on("submitSuccess.ufForm", function() {
// Reload page on success
window.location.reload();
});
});
});

Expand All @@ -210,7 +212,7 @@ function updateUser(userName, fieldName, fieldValue) {
msgTarget: $("#alerts-page")
});

$("body").on('renderSuccess.ufModal', function () {
$("body").on('renderSuccess.ufModal', function() {
var modal = $(this).ufModal('getModal');
var form = modal.find('.js-form');

Expand Down Expand Up @@ -246,16 +248,16 @@ function updateUser(userName, fieldName, fieldValue) {
msgTarget: $("#alerts-page")
});

$("body").on('renderSuccess.ufModal', function () {
$("body").on('renderSuccess.ufModal', function() {
var modal = $(this).ufModal('getModal');
var form = modal.find('.js-form');

form.ufForm()
.on("submitSuccess.ufForm", function() {
// Navigate or reload page on success
if (options.delete_redirect) window.location.href = options.delete_redirect;
else window.location.reload();
});
.on("submitSuccess.ufForm", function() {
// Navigate or reload page on success
if (options.delete_redirect) window.location.href = options.delete_redirect;
else window.location.reload();
});
});
});

Expand All @@ -269,12 +271,12 @@ function updateUser(userName, fieldName, fieldValue) {
updateUser(btn.data('user_name'), 'flag_verified', '1');
});

el.find('.js-user-enable').click(function () {
el.find('.js-user-enable').click(function() {
var btn = $(this);
updateUser(btn.data('user_name'), 'flag_enabled', '1');
});

el.find('.js-user-disable').click(function () {
el.find('.js-user-disable').click(function() {
var btn = $(this);
updateUser(btn.data('user_name'), 'flag_enabled', '0');
});
Expand All @@ -292,4 +294,4 @@ function bindUserCreationButton(el) {

attachUserForm();
});
};
};
1 change: 1 addition & 0 deletions app/sprinkles/admin/locale/en_US/messages.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
'MANAGE' => 'Manage group',
'NAME' => 'Group name',
'NAME_EXPLAIN' => 'Please enter a name for the group',
'NONE' => 'No group',
'NOT_EMPTY' => "You can't do that because there are still users associated with the group <strong>{{name}}</strong>.",
'PAGE_DESCRIPTION' => 'A listing of the groups for your site. Provides management tools for editing and deleting groups.',
'SUMMARY' => 'Group Summary',
Expand Down
4 changes: 4 additions & 0 deletions app/sprinkles/admin/src/Controller/UserController.php
Original file line number Diff line number Diff line change
Expand Up @@ -1219,6 +1219,10 @@ public function updateInfo(Request $request, Response $response, $args)
return $response->withJson([], 400);
}

if (isset($data['group_id']) && $data['group_id'] == 0) {
$data['group_id'] = null;
}

// Begin transaction - DB will be rolled back if an exception occurs
Capsule::transaction(function () use ($data, $user, $currentUser) {
// Update the user and generate success messages
Expand Down
2 changes: 2 additions & 0 deletions app/sprinkles/admin/templates/forms/user.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
<input type="text" class="form-control" name="theme" value="{{user.group.name}}" disabled>
{% else %}
<select id="input-group" class="form-control js-select2" name="group_id">
<option value="0">{{translate('GROUP.NONE')}}</option>
<option disabled="disabled">-----</option>
{% for group in groups %}
<option value="{{group.id}}" {% if (group.id == user.group_id) %}selected{% endif %}>{{group.name}}</option>
{% endfor %}
Expand Down
2 changes: 1 addition & 1 deletion app/sprinkles/admin/templates/pages/user.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@
<i class="fa fa-fw fa-bolt fa-lg text-yellow" title="{{translate('UNACTIVATED')}}"></i>
{% endif %}
</div>
<h4 class="text-muted text-center">{{user.user_name}}{% if 'group' not in fields.hidden %} • {{user.group.name}}{% endif %}</h4>
<h4 class="text-muted text-center">{{user.user_name}}{% if 'group' not in fields.hidden and user.group.name is not null %} • {{user.group.name}}{% endif %}</h4>

{% if 'email' not in fields.hidden %}
<hr>
Expand Down

0 comments on commit 161ee0f

Please sign in to comment.