diff options
-rw-r--r-- | data/stuff/js/util.js | 12 | ||||
-rw-r--r-- | data/stuff/test.js | 4 | ||||
-rw-r--r-- | data/stuff/test/auth.js | 95 | ||||
-rw-r--r-- | src/guff/api/content-type.cr | 2 | ||||
-rw-r--r-- | src/guff/api/methods.cr | 8 | ||||
-rw-r--r-- | src/guff/api/test.cr | 38 | ||||
-rw-r--r-- | src/guff/handlers/api.cr | 4 | ||||
-rw-r--r-- | src/guff/page-features.cr | 8 | ||||
-rw-r--r-- | src/guff/views/ecrs/test/auth.ecr | 26 | ||||
-rw-r--r-- | src/guff/views/html/test/auth.cr | 43 |
10 files changed, 189 insertions, 51 deletions
diff --git a/data/stuff/js/util.js b/data/stuff/js/util.js new file mode 100644 index 0000000..a6826db --- /dev/null +++ b/data/stuff/js/util.js @@ -0,0 +1,12 @@ +jQuery(function($) { + "use strict"; + + window.send = function(fn, args) { + return $.ajax({ + url: "/api/" + fn, + method: 'POST', + dataType: 'json', + data: args, + }); + }; +}); diff --git a/data/stuff/test.js b/data/stuff/test.js deleted file mode 100644 index 461b854..0000000 --- a/data/stuff/test.js +++ /dev/null @@ -1,4 +0,0 @@ - -function test() { - return true; -} diff --git a/data/stuff/test/auth.js b/data/stuff/test/auth.js new file mode 100644 index 0000000..103be82 --- /dev/null +++ b/data/stuff/test/auth.js @@ -0,0 +1,95 @@ +jQuery(function($) { + "use strict"; + var TEMPLATES = new LuigiTemplate.Cache({ + user: [ + "<a ", + "href='#' ", + "class='list-group-item %{css|h}' ", + "title='Set user to \"%{name|h}.\"' ", + "data-user_id='%{id|h}' ", + ">", + "<i class='fa fa-fw fa-spinner fa-spin hidden loading'></i>", + "<i class='fa fa-fw fa-user loading'></i>", + + " ", + + "%{name|h}", + "</a>", + ], + + loading: [ + "<span class='list-group-item disabled'>", + "<i class='fa fa-spinner fa-spin'></i>", + " ", + "Loading...", + "</span>", + ], + + error: [ + "<span class='list-group-item list-group-item-danger disabled'>", + "<i class='fa fa-exclamation-triangle'></i>", + " ", + "Error: %{responseText|h}", + "</span>", + ], + }); + + function reload() { + var btn = $('#reload'), + list = $('#users'); + + // show loading + btn.toggleClass('disabled').find('.loading').toggleClass('hidden'); + list.html(TEMPLATES.run('loading')); + + send('test/get_users').always(function() { + btn.toggleClass('disabled').find('.loading').toggleClass('hidden'); + list.html(''); + }).fail(function(r) { + console.log('get_users failed: ' + r.responseText); + list.html(TEMPLATES.run('error', r)); + }).done(function(r) { + list.html($.map(r.users, function(row) { + return TEMPLATES.run('user', $.extend({}, row, { + css: row.active ? 'active' : '', + })); + }).join('')); + }); + + // stop event + return false; + } + + $('#users').on('click', 'a.list-group-item', function() { + var me = $(this); + + // update highlight + var last = $('#users .active').removeClass('active'); + me.addClass('active'); + + // show spinner + me.addClass('disabled').find('.loading').toggleClass('hidden'); + + send('test/set_user', { + user_id: me.data('user_id'), + }).always(function() { + // hide spinner + me.removeClass('disabled').find('.loading').toggleClass('hidden'); + }).fail(function(r) { + alert('Error ' + r.responseText); + // restore old highlight + me.removeClass('active'); + last.addClass('active'); + }).done(function(r) { + // do nothing + }); + + // stop event + return false; + }); + + $('#reload').click(reload); + + // load users + reload(); +}); diff --git a/src/guff/api/content-type.cr b/src/guff/api/content-type.cr index 589e6b0..648ee3a 100644 --- a/src/guff/api/content-type.cr +++ b/src/guff/api/content-type.cr @@ -1,6 +1,6 @@ module Guff::API::ContentType CONTENT_TYPES = { - "development": "text/html; charset=utf-8", + "development": "text/json; charset=utf-8", "production": "application/json; charset=utf8", } diff --git a/src/guff/api/methods.cr b/src/guff/api/methods.cr index 9b35596..0247460 100644 --- a/src/guff/api/methods.cr +++ b/src/guff/api/methods.cr @@ -350,6 +350,14 @@ module Guff "error": { text: "Test error response", }, + + "get_users": { + text: "Get mock list of users", + }, + + "set_user": { + text: "Set mock user", + }, } } diff --git a/src/guff/api/test.cr b/src/guff/api/test.cr index 7549c11..44b5e10 100644 --- a/src/guff/api/test.cr +++ b/src/guff/api/test.cr @@ -17,6 +17,44 @@ module Guff [{foo: "bar"}, {foo: "asdf"}].to_json end + MOCK_USERS = { + "users": [{ + "id": "0", + "name": "Guest", + "active": true, + }, { + "id": "1", + "name": "Admin", + "active": false, + }, { + "id": "2", + "name": "Test User 1", + "active": false, + }, { + "id": "2", + "name": "Test User 2", + "active": false, + }, { + "id": "3", + "name": "Test User<<<<>>>>>&&&&&&2", + "active": false, + }] + } + + private def do_test_get_users( + context : HTTP::Server::Context, + args : Hash(String, String) + ) + MOCK_USERS + end + + private def do_test_set_user( + context : HTTP::Server::Context, + args : Hash(String, String) + ) + { ok: true } + end + private def do_test_error( context : HTTP::Server::Context, args : Hash(String, String) diff --git a/src/guff/handlers/api.cr b/src/guff/handlers/api.cr index c6f78d7..eab0383 100644 --- a/src/guff/handlers/api.cr +++ b/src/guff/handlers/api.cr @@ -127,6 +127,8 @@ class Guff::Handlers::APIHandler < Guff::Handler version, get_posts, error, + get_users, + set_user, ], }) rescue e @@ -139,7 +141,7 @@ class Guff::Handlers::APIHandler < Guff::Handler end # send body - context.response.puts json + context.response << json end private def do_api_docs(context : HTTP::Server::Context) diff --git a/src/guff/page-features.cr b/src/guff/page-features.cr index 887197e..5b0c107 100644 --- a/src/guff/page-features.cr +++ b/src/guff/page-features.cr @@ -34,6 +34,14 @@ module Guff::PageFeatures # TODO metas: [] of Hash(String, String), }, + + "guff/util": { + deps: %w{jquery luigi-template}, + + scripts: %w{ + /guff-stuff/js/util.js + }, + }, } def self.add(key : String, page) diff --git a/src/guff/views/ecrs/test/auth.ecr b/src/guff/views/ecrs/test/auth.ecr index 4c032ec..c28f178 100644 --- a/src/guff/views/ecrs/test/auth.ecr +++ b/src/guff/views/ecrs/test/auth.ecr @@ -20,13 +20,31 @@ <div class='panel-heading'> <b> <i class='fa fa-users'></i> - Auth Test + Users </b> + + <a + href='#' + id='reload' + class='btn btn-default btn-xs pull-right' + title='Reload users.' + > + <span class='loading'> + <i class='fa fa-refresh'></i> + </span> + + <span class='loading hidden'> + <i class='fa fa-spinner fa-spin'></i> + </span> + </a><!-- #reload --> </div><!-- panel-heading --> - <div class='list-group'><%= - users - %></div><!-- list-group --> + <div id='users' class='list-group'> + <span class='list-group-item disabled'> + <i class='fa fa-spinner fa-spin'></i> + Loading... + </span><!-- list-group-item --> + </div><!-- list-group --> </div><!-- panel --> </div><!-- col-md-8 --> </div><!-- container --> diff --git a/src/guff/views/html/test/auth.cr b/src/guff/views/html/test/auth.cr index b21ebf6..9f5d1ad 100644 --- a/src/guff/views/html/test/auth.cr +++ b/src/guff/views/html/test/auth.cr @@ -3,38 +3,7 @@ require "../page" class Guff::TestAuthHTMLView TITLE = "Guff Auth Test" - FEATURES = %w{bootstrap font-awesome} - - TEMPLATES = TemplateCache.new({ - user: "<a - href='#' - class='list-group-item %{css}' - title='Set user to \"%{name}.\"' - data-user_id='%{id}' - >%{name}</a>" - }) - - MOCK_USERS = [{ - "id": "0", - "name": "Guest", - "active": "1", - }, { - "id": "1", - "name": "Admin", - "active": "0", - }, { - "id": "2", - "name": "Test User 1", - "active": "0", - }, { - "id": "2", - "name": "Test User 2", - "active": "0", - }, { - "id": "3", - "name": "Test User<<<<>>>>>&&&&&&2", - "active": "0", - }] + FEATURES = %w{bootstrap font-awesome guff/util} def self.run(models, context : HTTP::Server::Context) new(models).run(context) @@ -46,19 +15,11 @@ class Guff::TestAuthHTMLView def run(context) page = PageHTMLView.new(TITLE, self.to_s) page.add_features(FEATURES) + page.scripts << "/guff-stuff/test/auth.js" context.response.content_type = page.content_type context.response.puts page end - def users - MOCK_USERS.map { |row| - TEMPLATES[:user].run(row.merge({ - "name": h(row["name"]), - "css": (row["active"] == "1") ? "active" : "", - })) - }.join("") - end - def h(s : String) HTML.escape(s || "") end |