// @import "bootstrap/type.less";
// @import "bootstrap/code.less";
// @import "bootstrap/grid.less";
-// @import "bootstrap/tables.less";
+@import "bootstrap/tables.less";
@import "bootstrap/forms.less";
// @import "bootstrap/buttons.less";
@import "main/comment_form.less";
@import "main/story.less";
@import "main/site-header.less";
-@import "admin/admin-bar.less";
\ No newline at end of file
+@import "admin/admin-bar.less";
+@import "main/app.less";
\ No newline at end of file
--- /dev/null
+// LESS for app
+
+.app-frame {
+ margin: 6px;
+}
my $admin = $r->under('/admin');
$admin->get('/css')->to('admin-css#edit');
$admin->get('/story/edit')->to('admin-story#edit');
- $admin->get('/sidebar')->to('admin-sidebar#list');
- $admin->get('/sidebar/edit')->to('admin-sidebar#edit');
+ $admin->get('/sidebar')->to('admin-sidebar#index');
$admin->post('/sidebar/update')->to('admin-sidebar#update');
+ $admin->get('/sidebar/list')->to('admin-sidebar#list');
# API
my $api = $r->under('/api/v1');
package Newslash::Web::Controller::Admin::Sidebar;
use Mojo::Base 'Mojolicious::Controller';
+sub index {
+ my $c = shift;
+ $c->render;
+}
+
sub list {
my $c = shift;
my $sidebar = $c->app->model('sidebar');
else {
my $rs = $sidebar->create_table;
if (!$rs) {
- $c->rendered(500);
+ $c->render(json => {message => "table creation failed", error => 1});
return;
}
$message = "table not exists, so create table.";
}
- $c->render(sidebar_items => $sidebar_items, message => $message);
+ $c->render(json => {message => $message, items => $sidebar_items});
+ return;
}
sub update {
--- /dev/null
+/* sidebar_editor.js */
+const editor = {};
+var vm;
+
+editor.run = function run (params) {
+ const data = {
+ message: "",
+ sidebarItems: [],
+ };
+ const computed = {};
+ const methods = {};
+ const getUrl = "/admin/sidebar/list";
+ vm = new Vue({el: params.el,
+ data: data,
+ computed: computed,
+ methods: methods,
+ created: function () {
+ this.$http.get(getUrl).then(
+ (resp) => { // success
+ this.sidebarItems = resp.body.items;
+ this.message = resp.body.message;
+ },
+ (resp) => { // fail
+ this.sidebarItems = [];
+ this.message = resp.body.message || "failed to get items";
+ }
+ );
+ },
+ });
+};
--- /dev/null
+# -*-Perl-*-
+# basic simple and non-destructive tests
+use Mojo::Base -strict;
+use Mojo::Date;
+use Mojo::Util qw(dumper);
+
+use Test::More;
+use Test::Mojo;
+
+my $t = Test::Mojo->new('Newslash::Web');
+
+$t->get_ok('/admin/sidebar')->status_is(200);
+$t->get_ok('/admin/sidebar/list')->status_is(200);
+
+SKIP: {
+ skip "mode is 'test'", 1 if ($t->app->mode ne 'test');
+
+ subtest 'sidebar post' => sub {
+ my $t_str = localtime;
+ my $test_data = {
+ name => "test sidebar @ $t_str",
+ model => 'stories',
+ query_params => 'foo',
+ template => 'foobar',
+ };
+
+ $t->post_ok('/admin/sidebar/update' => {Accept => '*/*'} => json => $test_data)
+ ->status_is(200)
+ ->json_has('/id');
+
+ my $id = $t->tx->res->json->{id};
+ diag(dumper($t->tx->res->json)) if !$id;
+
+ $test_data = {
+ id => $id,
+ name => 'new test sidebar @ t_str',
+ model => 'stories',
+ query_params => 'foo',
+ template => 'foobar',
+ };
+
+ if ($id) {
+ $t->post_ok('/admin/sidebar/update' => {Accept => '*/*'} => json => $test_data)
+ ->status_is(200)
+ ->json_has('/id');
+
+ $id = $t->tx->res->json->{id};
+ diag(dumper($t->tx->res->json)) if !$id;
+ }
+ };
+}
+
+done_testing();
$t->get_ok('/admin/css')->status_is(200);
-$t->get_ok('/admin/sidebar')->status_is(200);
-
-subtest 'sidebar post' => sub {
- my $t_str = localtime;
- my $test_data = {
- name => "test sidebar @ $t_str",
- model => 'stories',
- query_params => 'foo',
- template => 'foobar',
- };
-
- $t->post_ok('/admin/sidebar/update' => {Accept => '*/*'} => json => $test_data)
- ->status_is(200)
- ->json_has('/id');
-
- my $id = $t->tx->res->json->{id};
- diag(dumper($t->tx->res->json)) if !$id;
-
- $test_data = {
- id => $id,
- name => 'new test sidebar @ t_str',
- model => 'stories',
- query_params => 'foo',
- template => 'foobar',
- };
-
- if ($id) {
- $t->post_ok('/admin/sidebar/update' => {Accept => '*/*'} => json => $test_data)
- ->status_is(200)
- ->json_has('/id');
-
- $id = $t->tx->res->json->{id};
- diag(dumper($t->tx->res->json)) if !$id;
- }
-};
-
SKIP: {
skip "mode is 'test'", 5 if ($t->app->mode eq 'test');
--- /dev/null
+[% WRAPPER common/layout vue=1 %]
+
+<script type="text/x-template" id="sidebar-item-editor">
+</script>
+
+<div class="app-frame" id="sidebar-manager">
+ <h3>Sidebar items</h3>
+ <div v-text="message">
+ </div>
+ <form class="items">
+ <table class="table table-hover">
+ <thead>
+ <tr>
+ <th></th><th>ID</th><th>name</th><th>model</th><th>query_param</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr v-for="item in sidebarItems">
+ <td><input type="checkbox" value="" /></td>
+ <td v-text="item.id"></td>
+ <td v-text="item.name"></td>
+ <td v-text="item.model"></td>
+ <td v-text="item.query_param"></td>
+ </tr>
+ </tbody>
+ </table>
+ <div class="actions">
+ <button class="btn btn-default" type="button">New</button>
+ <button class="btn btn-default" type="button">Delete</button>
+ </div>
+ </form>
+</div>
+
+<script src="/js/sidebar_editor.js" ></script>
+<script>
+ $(document).ready(function () {
+ editor.run({ el: '#sidebar-manager' });
+ });
+</script>
+
+[% END %]