aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/assets/js/admin/dialogs/user-edit.js63
-rw-r--r--data/assets/js/admin/tabs/users.js7
-rw-r--r--src/guff.cr46
-rw-r--r--src/views/admin-page.ecr87
4 files changed, 171 insertions, 32 deletions
diff --git a/data/assets/js/admin/dialogs/user-edit.js b/data/assets/js/admin/dialogs/user-edit.js
index 2e43d42..fed9364 100644
--- a/data/assets/js/admin/dialogs/user-edit.js
+++ b/data/assets/js/admin/dialogs/user-edit.js
@@ -2,14 +2,40 @@ jQuery(function($) {
"use strict";
$('#user-edit-dialog').on('show.bs.modal', function() {
- var row = $(this).data('row');
-
- $.each({
- name: 'user_name',
- email: 'email',
- role: 'role_name',
- }, function(id, col) {
- $('#user-edit-' + id).val(row[col]);
+ var me = $(this);
+
+ $(this).find('.modal-body').addClass('hidden');
+ $(this).find('.modal-body.loading-text').removeClass('hidden');
+
+ send('user/get', {
+ user_id: me.data('user_id'),
+ }).always(function() {
+ $(this).find('.modal-body.loading-text').addClass('hidden');
+ }).fail(function(r) {
+ var error = r.responseText;
+
+ try {
+ // try to extract error message from json response
+ var data = $.parseJSON(r.responseText);
+ if ('error' in data)
+ error = data.error;
+ } catch (e) {}
+
+ me.find('.modal-body.loading-error').removeClass('hidden')
+ .find('.error-text').text(error);
+ }).done(function(r) {
+ $.each({
+ name: 'name',
+ email: 'email',
+ role: 'role',
+ }, function(id, col) {
+ $('#user-edit-' + id).val(r[col]);
+ });
+
+ $('#user-edit-password').val('');
+ $('#user-edit-active').val((r.is_active == '1') ? 'active' : 'inactive');
+
+ me.find('.modal-body.loading-done').removeClass('hidden');
});
});
@@ -34,8 +60,7 @@ jQuery(function($) {
});
$('#user-edit-confirm').click(function() {
- var me = $(this),
- user_id = $('#user-edit-dialog').data('row').user_id;
+ var me = $(this);
if (me.hasClass('disabled'))
return false;
@@ -43,18 +68,28 @@ jQuery(function($) {
// toggle loading
me.toggleClass('disabled').find('.loading').toggleClass('hidden');
- send('test/edit_user', {
- user_id: user_id,
+ send('user/set', {
+ user_id: $('#user-edit-dialog').data('user_id'),
name: $('#user-edit-name').val(),
email: $('#user-edit-email').val(),
+ password: $('#user-edit-password').val(),
role: $('#user-edit-role').val(),
+ active: ($('#user-edit-active').val() == 'active') ? 't' : 'f',
}).always(function() {
// toggle loading
me.toggleClass('disabled').find('.loading').toggleClass('hidden');
}).fail(function(r) {
- alert('Error ' + r.responseText);
+ var error = r.responseText;
+
+ try {
+ // try to extract error message from json response
+ var data = $.parseJSON(r.responseText);
+ if ('error' in data)
+ error = data.error;
+ } catch (e) {}
+
+ alert('Error: ' + error);
}).done(function(r) {
- console.log(r);
$('#users-reload').click();
$('#user-edit-dialog').modal('hide');
});
diff --git a/data/assets/js/admin/tabs/users.js b/data/assets/js/admin/tabs/users.js
index b74b8a1..2fff893 100644
--- a/data/assets/js/admin/tabs/users.js
+++ b/data/assets/js/admin/tabs/users.js
@@ -10,7 +10,7 @@ jQuery(function($) {
"data-user_id='%{user_id|h}' ",
"data-q='%{q|h}' ",
">",
- "<i class='fa fa-fw fa-user'></i>",
+ "<i class='fa fa-fw %{icon|h}'></i>",
" ",
"%{name|h} (%{email|h})",
@@ -89,8 +89,11 @@ jQuery(function($) {
}));
}).done(function(r) {
list.html($.map(r, function(row) {
+ var active = (row.is_active == '1');
+
return TEMPLATES.run('user', $.extend({}, row, {
- css: (row.is_active == '1') ? '' : 'list-group-item-danger',
+ icon: active ? 'fa-user' : 'fa-user-times',
+ css: active ? '' : 'list-group-item-danger',
q: [row.user_id, row.user_name, row.email, row.role_name].join(' ').toLowerCase(),
badge_css: ROLE_BADGE_CSS[row.role],
}));
diff --git a/src/guff.cr b/src/guff.cr
index 6b842f8..5524aca 100644
--- a/src/guff.cr
+++ b/src/guff.cr
@@ -533,7 +533,7 @@ module Guff
# add search filter
filters << "a.post_id IN (
SELECT rowid
- FROM posts_fts
+ FROM posts_fts
WHERE posts_fts MATCH ?
)"
@@ -1051,6 +1051,21 @@ module Guff
ORDER BY LOWER(a.name)
",
+
+ get: "
+ SELECT a.user_id,
+ a.name,
+ a.email,
+ a.is_active,
+ b.role,
+ b.name AS role_name
+
+ FROM users a
+ JOIN roles b
+ ON (b.role_id = a.role_id)
+
+ WHERE a.user_id = ?
+ ",
}
def login(
@@ -1151,6 +1166,16 @@ module Guff
rows
end
+
+ def get(user_id : Int64)
+ row = @context.dbs.ro.row(SQL[:get], [user_id.to_s])
+ raise "unknown user: #{user_id}" unless row
+
+ row.reduce({} of String => String) do |r, k, v|
+ r[k] = v.to_s
+ r
+ end
+ end
end
# TODO: handle session expiration
@@ -1686,12 +1711,17 @@ module Guff
{ "user_id": user_id }
end
+ def do_user_get(params : HTTP::Params)
+ @context.models.user.get(params["user_id"].to_i64)
+ end
+
+
def do_user_set(params : HTTP::Params)
@context.models.user.set(
user_id: params["user_id"].to_i64,
name: params["name"]?,
email: params["email"]?,
- password: params["password"]?,
+ password: (params["password"]? && params["password"].size > 0) ? params["password"] : nil,
active: params["active"]? ? (params["active"] == "t") : nil,
role: params["role"]?,
)
@@ -1747,7 +1777,7 @@ module Guff
def self.icon(id : String?)
if id && id.size > 0
ICON_TEMPLATE % [HTML.escape(id.not_nil!)]
- else
+ else
""
end
end
@@ -1795,7 +1825,7 @@ module Guff
String.build do |io|
@items.each do |item|
io << ItemView.new(
- context: @context,
+ context: @context,
active: @default == item[:id]?,
item: item
).to_s
@@ -1848,7 +1878,7 @@ module Guff
)
Dropdown::MenuView.new(
context: @context,
- id: id,
+ id: id,
name: name,
text: text,
icon: icon,
@@ -2016,7 +2046,7 @@ module Guff
private def authors_menu_items
@context.models.user.get_users.map do |row|
- {
+ {
id: row["user_id"],
name: row["name"],
text: "Show author \"%s\"." % [row["name"]],
@@ -2026,7 +2056,7 @@ module Guff
private def sites_menu_items
@context.models.site.get_sites.map do |row|
- {
+ {
id: row["site_id"],
name: row["name"],
text: "Show site \"%s\"." % [row["name"]],
@@ -2036,7 +2066,7 @@ module Guff
private def states_menu_items
@context.models.state.get_states.map do |row|
- {
+ {
id: row["state"],
name: row["name"],
icon: row["icon"],
diff --git a/src/views/admin-page.ecr b/src/views/admin-page.ecr
index 89a75d0..f82d06c 100644
--- a/src/views/admin-page.ecr
+++ b/src/views/admin-page.ecr
@@ -631,7 +631,12 @@
class='form-control'
title='Enter name of user.'
placeholder='John Doe'
+ aria-describedby='user-edit-name-help'
/>
+
+ <p id='user-edit-name-help' class='help-block'>
+ Name of this user.
+ </p>
</div><!-- form-group -->
<div class='form-group'>
@@ -645,22 +650,88 @@
class='form-control'
title='Enter user email.'
placeholder='johndoe@example.com'
+ aria-describedby='user-edit-email-help'
/>
+
+ <p id='user-edit-email-help' class='help-block'>
+ Email address for this user.
+ </p>
</div><!-- form-group -->
<div class='form-group'>
- <label for='user-edit-role'>
- Role
+ <label for='user-edit-password'>
+ Password
</label>
- <select
- id='user-edit-role'
+ <input
+ type='password'
+ id='user-edit-password'
class='form-control'
- title='Choose role of user.'
- ><%=
- role_options
- %></select>
+ title='Enter user password.'
+ aria-describedby='user-edit-password-help'
+ />
+
+ <p id='user-edit-password-help' class='help-block'>
+ Password for this user.
+ </p>
</div><!-- form-group -->
+
+ <div class='row'>
+ <div class='col-md-6'>
+ <div class='form-group'>
+ <label for='user-edit-role'>
+ Role
+ </label>
+
+ <select
+ id='user-edit-role'
+ class='form-control'
+ title='Choose role of user.'
+ aria-describedby='user-edit-role-help'
+ ><%=
+ role_options
+ %></select>
+
+ <p id='user-edit-role-help' class='help-block'>
+ User role.
+ </p>
+ </div><!-- form-group -->
+ </div><!-- col-md-6 -->
+
+ <div class='col-md-6'>
+ <div class='form-group'>
+ <label for='user-edit-active'>
+ Active
+ </label>
+
+ <select
+ id='user-edit-active'
+ class='form-control'
+ title='Choose active state of user.'
+ aria-describedby='user-edit-active-help'
+ >
+ <option
+ value='inactive'
+ selected='selected'
+ title='Inactive: user cannot log in.'
+ >
+ Inactive
+ </option>
+
+ <option
+ value='active'
+ title='Active: user can log in.'
+ >
+ Active
+ </option>
+ </select>
+
+ <p id='user-edit-active-help' class='help-block'>
+ Is this user active?
+ </p>
+ </div><!-- form-group -->
+ </div><!-- col-md-6 -->
+ </div><!-- row -->
</div><!-- modal-body -->
<div class='modal-footer'>