surikat 0.3.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -1
  3. data/.idea/workspace.xml +186 -81
  4. data/README.md +1 -1
  5. data/exe/surikat +2 -1
  6. data/frontend-demo/LICENSE +21 -0
  7. data/frontend-demo/README.md +89 -0
  8. data/frontend-demo/aaa.html +153 -0
  9. data/frontend-demo/aaa.js +115 -0
  10. data/frontend-demo/authors.js +159 -0
  11. data/frontend-demo/books.html +138 -0
  12. data/frontend-demo/books.js +201 -0
  13. data/frontend-demo/gulpfile.js +42 -0
  14. data/frontend-demo/index.html +137 -0
  15. data/frontend-demo/package-lock.json +4757 -0
  16. data/frontend-demo/package.json +36 -0
  17. data/frontend-demo/vendor/bootstrap/css/bootstrap.css +8981 -0
  18. data/frontend-demo/vendor/bootstrap/css/bootstrap.css.map +1 -0
  19. data/frontend-demo/vendor/bootstrap/css/bootstrap.min.css +7 -0
  20. data/frontend-demo/vendor/bootstrap/css/bootstrap.min.css.map +1 -0
  21. data/frontend-demo/vendor/bootstrap/js/bootstrap.bundle.js +6444 -0
  22. data/frontend-demo/vendor/bootstrap/js/bootstrap.bundle.js.map +1 -0
  23. data/frontend-demo/vendor/bootstrap/js/bootstrap.bundle.min.js +7 -0
  24. data/frontend-demo/vendor/bootstrap/js/bootstrap.bundle.min.js.map +1 -0
  25. data/frontend-demo/vendor/bootstrap/js/bootstrap.js +3927 -0
  26. data/frontend-demo/vendor/bootstrap/js/bootstrap.js.map +1 -0
  27. data/frontend-demo/vendor/bootstrap/js/bootstrap.min.js +7 -0
  28. data/frontend-demo/vendor/bootstrap/js/bootstrap.min.js.map +1 -0
  29. data/frontend-demo/vendor/graphql.min.js +1 -0
  30. data/frontend-demo/vendor/jquery/jquery.js +10364 -0
  31. data/frontend-demo/vendor/jquery/jquery.min.js +2 -0
  32. data/frontend-demo/vendor/jquery/jquery.min.map +1 -0
  33. data/frontend-demo/vendor/jquery/jquery.slim.js +8269 -0
  34. data/frontend-demo/vendor/jquery/jquery.slim.min.js +2 -0
  35. data/frontend-demo/vendor/jquery/jquery.slim.min.map +1 -0
  36. data/frontend-demo/vendor/notify.min.js +1 -0
  37. data/lib/surikat.rb +16 -11
  38. data/lib/surikat/templates/aaa_queries.rb.tmpl +5 -3
  39. data/lib/surikat/templates/config.ru.tmpl +5 -0
  40. data/lib/surikat/version.rb +1 -1
  41. metadata +33 -2
@@ -0,0 +1,138 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+
6
+ <meta charset="utf-8">
7
+ <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
8
+ <meta name="description" content="">
9
+ <meta name="author" content="">
10
+
11
+ <title>Surikat Demo</title>
12
+
13
+ <!-- Bootstrap core CSS -->
14
+ <link href="vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet">
15
+
16
+ <!-- Custom styles for this template -->
17
+ <style>
18
+ body {
19
+ padding-top: 54px;
20
+ }
21
+
22
+ @media (min-width: 992px) {
23
+ body {
24
+ padding-top: 56px;
25
+ }
26
+ }
27
+
28
+ </style>
29
+
30
+ </head>
31
+
32
+ <body>
33
+
34
+ <!-- Navigation -->
35
+ <nav class="navbar navbar-expand-lg navbar-dark bg-dark fixed-top">
36
+ <div class="container">
37
+ <a class="navbar-brand" href="https://github.com/alxx/surikat">
38
+ <img src="https://camo.githubusercontent.com/b17e471f697a115ac68f565e637602328c402478/68747470733a2f2f692e696d6775722e636f6d2f4f6c43557733382e706e67"
39
+ width="26" height="40" alt="">
40
+ Surikat Demo
41
+ </a>
42
+ <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarResponsive"
43
+ aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation">
44
+ <span class="navbar-toggler-icon"></span>
45
+ </button>
46
+ <div class="collapse navbar-collapse" id="navbarResponsive">
47
+ <ul class="navbar-nav ml-auto">
48
+ <li class="nav-item">
49
+ <a class="nav-link" href="index.html">Authors</a>
50
+ </li>
51
+ <li class="nav-item active">
52
+ <a class="nav-link" href="books.html">Books</a>
53
+ <span class="sr-only">(current)</span>
54
+ </li>
55
+ <li class="nav-item">
56
+ <a class="nav-link" href="aaa.html">AAA</a>
57
+ </li>
58
+ </ul>
59
+ </div>
60
+ </div>
61
+ </nav>
62
+
63
+ <!-- Page Content -->
64
+ <div class="container">
65
+ <div class="row">
66
+ <div class="col-lg-12 text-center">
67
+ <h1 class="mt-5">Books</h1>
68
+
69
+ <form>
70
+
71
+ <div class="input-group mb-3">
72
+ <div class="input-group-prepend">
73
+ <label class="input-group-text" for="author_id">Author</label>
74
+ </div>
75
+ <select class="custom-select" id="author_id">
76
+ </select>
77
+ </div>
78
+
79
+ <input type="hidden" id="book_id" value="">
80
+
81
+ <div class="input-group mb-3">
82
+ <div class="input-group-prepend">
83
+ <label class="input-group-text">Book title</label>
84
+ </div>
85
+ <input type="text" class="form-control" placeholder="Enter a title" id="title">
86
+ </div>
87
+
88
+ <button type="submit" class="btn btn-primary" id="btnSubmit" disabled="disabled">Submit</button>
89
+ <button type="button" class="btn btn-danger" id="btnDelete" disabled="disabled">Delete</button>
90
+ </form>
91
+
92
+
93
+ <table style="margin-top: 50px;" class="table table-hover" id="all">
94
+ <thead>
95
+ <tr>
96
+ <th scope="col">ID</th>
97
+ <th scope="col">Title</th>
98
+ <th scope="col">Created at</th>
99
+ <th scope="col">Updated at</th>
100
+ </tr>
101
+ </thead>
102
+ <tbody></tbody>
103
+ </table>
104
+ </div>
105
+ </div>
106
+ </div>
107
+
108
+ <!-- Bootstrap core JavaScript -->
109
+ <script src="vendor/jquery/jquery.min.js"></script>
110
+ <script src="vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
111
+
112
+ <!-- GraphQL Plugin -->
113
+ <script src="vendor/graphql.min.js"></script>
114
+
115
+ <!-- Notifications -->
116
+ <script src="vendor/notify.min.js"></script>
117
+
118
+ <!-- App -->
119
+ <script src="books.js"></script>
120
+
121
+ <script language="JavaScript">
122
+ $(document).ready(function () {
123
+
124
+ $('input[type="text"]').keyup(function () {
125
+ if ($(this).val() != '') {
126
+ $(':input[type="submit"]').prop('disabled', false);
127
+ } else {
128
+ $(':input[type="submit"]').prop('disabled', true);
129
+ }
130
+ });
131
+
132
+ run();
133
+ })
134
+ </script>
135
+
136
+ </body>
137
+
138
+ </html>
@@ -0,0 +1,201 @@
1
+ var graph = graphql("http://localhost:3000/", {});
2
+
3
+ var author_id;
4
+
5
+ $(document).on("click", '#all tbody tr', function (tr) {
6
+ var id = $(tr.target.parentNode).data('id');
7
+ setBook(id);
8
+ });
9
+
10
+ $("#btnDelete").click(function (el) {
11
+ el.preventDefault();
12
+
13
+ var id = $('#book_id').val();
14
+
15
+ $(this).attr('disabled', true);
16
+ $("#btnSubmit").attr('disabled', true);
17
+ deleteBook(id);
18
+ });
19
+
20
+ $("#btnSubmit").click(function (el) {
21
+ el.preventDefault();
22
+
23
+ $(this).attr('disabled', true);
24
+ $("#btnDelete").attr('disabled', true);
25
+
26
+ var id = $('#book_id').val();
27
+ var title = $('#title').val();
28
+
29
+ if (id == null || id == "") {
30
+ console.log('save book');
31
+ saveBook(title);
32
+ } else {
33
+ console.log('update book');
34
+ updateBook(id, title);
35
+ }
36
+ });
37
+
38
+ function setBook(id) {
39
+ var q = `{Book(id: ${id}) {title}}`;
40
+ console.log(`loading book ${id}...`);
41
+
42
+ graph.query.run(q).then(function (r) {
43
+ book = r.Book;
44
+ console.log(book);
45
+ $("#book_id").val(id);
46
+ $("#title").val(book.title);
47
+
48
+ $("#btnSubmit").removeAttr('disabled');
49
+ $("#btnDelete").removeAttr('disabled');
50
+ }).catch(function (error) {
51
+ alert(JSON.stringify(error))
52
+ })
53
+ }
54
+
55
+ function saveBook(title) {
56
+ var q = `mutation Book($book: BookInput) {Book(book: $book) {id}}`;
57
+ var vars = {book: {title: title, author_id: author_id}};
58
+ console.log('creating book...');
59
+
60
+ var create = graph(q);
61
+
62
+ create(vars).then(function (r) {
63
+ book = r.Book;
64
+ $.notify(`Book created with id ${book.id}`, {position: "top center", autoHideDelay: 3000});
65
+
66
+ $("#book_id").val(book.id);
67
+
68
+ $("#btnSubmit").removeAttr('disabled');
69
+ $("#btnDelete").removeAttr('disabled');
70
+
71
+ bookList();
72
+ }).catch(function (error) {
73
+ alert(JSON.stringify(error))
74
+ })
75
+ }
76
+
77
+ function updateBook(id, title) {
78
+ var q = `mutation UpdateBook($book: BookInput) {UpdateBook(book: $book) {id}}`;
79
+ var vars = {book: {id: id, title: title}};
80
+ console.log(`updating book ${id}...`);
81
+
82
+ var update = graph(q);
83
+
84
+ update(vars).then(function (r) {
85
+ book = r.UpdateBook;
86
+ $.notify(`Book updated`, {position: "top center", autoHideDelay: 3000});
87
+
88
+ $("#btnSubmit").removeAttr('disabled');
89
+ $("#btnDelete").removeAttr('disabled');
90
+
91
+ bookList();
92
+ }).catch(function (error) {
93
+ alert(JSON.stringify(error))
94
+ })
95
+ }
96
+
97
+ function deleteBook(id) {
98
+ var q = `mutation DeleteBook($id: ID) {DeleteBook(id: $id)}`;
99
+ var vars = {id: id};
100
+ console.log(`deleting book ${id}...`);
101
+
102
+ var del = graph(q);
103
+
104
+ del(vars).then(function (r) {
105
+ $.notify(`Book ${id} deleted.`, {position: "top center", autoHideDelay: 3000});
106
+
107
+ $('#book_id').val(null);
108
+ $('#title').val(null);
109
+
110
+ bookList();
111
+ }).catch(function (error) {
112
+ alert(JSON.stringify(error))
113
+ })
114
+ }
115
+
116
+ function bookList() {
117
+ if (author_id == null) { return }
118
+
119
+ $("#all > tbody").html("");
120
+
121
+ var q = `{
122
+ Books(q: "author_id_eq=${author_id}") {
123
+ id
124
+ title
125
+ created_at
126
+ updated_at
127
+ }
128
+ }`;
129
+
130
+ console.log(`loading books for author ${author_id}...`);
131
+
132
+ graph.query.run(q).then(function (all) {
133
+ all.Books.forEach(function (r) {
134
+ $('#all tbody').append(`<tr data-id="${r.id}"><th scope="row">${r.id}</th>
135
+ <td>${r.title}</td>
136
+ <td>${r.created_at}</td>
137
+ <td>${r.updated_at}</td></tr>`);
138
+ });
139
+
140
+ }).catch(function (error) {
141
+ alert(JSON.stringify(error));
142
+ })
143
+ }
144
+
145
+ function populateAuthors() {
146
+ $("#author_id").html("");
147
+
148
+ var q = `{
149
+ Authors {
150
+ id
151
+ name
152
+ }
153
+ }`;
154
+
155
+ console.log('loading authors...');
156
+
157
+ graph.query.run(q).then(function (all) {
158
+ all.Authors.forEach(function (r) {
159
+ var selected = (r.id == author_id ? 'selected="selected"' : '');
160
+ $('#author_id').append(`<option ${selected} value="${r.id}">${r.name}</option>`)
161
+ });
162
+
163
+ bookList();
164
+ }).catch(function (error) {
165
+ alert(JSON.stringify(error));
166
+ })
167
+ }
168
+
169
+ function parseParams() {
170
+ var query = location.search.split('?')[1];
171
+
172
+ var re = /([^&=]+)=?([^&]*)/g;
173
+ var decodeRE = /\+/g;
174
+ var decode = function (str) {return decodeURIComponent( str.replace(decodeRE, " ") );};
175
+ var params = {}, e;
176
+ while ( e = re.exec(query) ) {
177
+ var k = decode( e[1] ), v = decode( e[2] );
178
+ if (k.substring(k.length - 2) === '[]') {
179
+ k = k.substring(0, k.length - 2);
180
+ (params[k] || (params[k] = [])).push(v);
181
+ }
182
+ else params[k] = v;
183
+ }
184
+ return params;
185
+ }
186
+
187
+ function run() {
188
+ console.log('starting...');
189
+
190
+ var params = parseParams();
191
+ author_id = params.author_id || 1;
192
+
193
+ $('#author_id').change(function () {
194
+ author_id = $(this).val();
195
+ console.log('changed author to', author_id);
196
+
197
+ bookList();
198
+ });
199
+
200
+ populateAuthors();
201
+ }
@@ -0,0 +1,42 @@
1
+ var gulp = require('gulp');
2
+ var browserSync = require('browser-sync').create();
3
+ var pkg = require('./package.json');
4
+
5
+ // Copy third party libraries from /node_modules into /vendor
6
+ gulp.task('vendor', function() {
7
+
8
+ // Bootstrap
9
+ gulp.src([
10
+ './node_modules/bootstrap/dist/**/*',
11
+ '!./node_modules/bootstrap/dist/css/bootstrap-grid*',
12
+ '!./node_modules/bootstrap/dist/css/bootstrap-reboot*'
13
+ ])
14
+ .pipe(gulp.dest('./vendor/bootstrap'))
15
+
16
+ // jQuery
17
+ gulp.src([
18
+ './node_modules/jquery/dist/*',
19
+ '!./node_modules/jquery/dist/core.js'
20
+ ])
21
+ .pipe(gulp.dest('./vendor/jquery'))
22
+
23
+ })
24
+
25
+ // Default task
26
+ gulp.task('default', ['vendor']);
27
+
28
+ // Configure the browserSync task
29
+ gulp.task('browserSync', function() {
30
+ browserSync.init({
31
+ server: {
32
+ baseDir: "./"
33
+ }
34
+ });
35
+ });
36
+
37
+ // Dev task
38
+ gulp.task('dev', ['browserSync'], function() {
39
+ gulp.watch('./css/*.css', browserSync.reload);
40
+ gulp.watch('./*.html', browserSync.reload);
41
+ gulp.watch('./*.js', browserSync.reload);
42
+ });
@@ -0,0 +1,137 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+
6
+ <meta charset="utf-8">
7
+ <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
8
+ <meta name="description" content="">
9
+ <meta name="author" content="">
10
+
11
+ <title>Surikat Demo</title>
12
+
13
+ <!-- Bootstrap core CSS -->
14
+ <link href="vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet">
15
+
16
+ <!-- Custom styles for this template -->
17
+ <style>
18
+ body {
19
+ padding-top: 54px;
20
+ }
21
+
22
+ @media (min-width: 992px) {
23
+ body {
24
+ padding-top: 56px;
25
+ }
26
+ }
27
+
28
+ </style>
29
+
30
+ </head>
31
+
32
+ <body>
33
+
34
+ <!-- Navigation -->
35
+ <nav class="navbar navbar-expand-lg navbar-dark bg-dark fixed-top">
36
+ <div class="container">
37
+ <a class="navbar-brand" href="https://github.com/alxx/surikat">
38
+ <img src="https://camo.githubusercontent.com/b17e471f697a115ac68f565e637602328c402478/68747470733a2f2f692e696d6775722e636f6d2f4f6c43557733382e706e67"
39
+ width="26" height="40" alt="">
40
+ Surikat Demo
41
+ </a>
42
+ <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarResponsive"
43
+ aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation">
44
+ <span class="navbar-toggler-icon"></span>
45
+ </button>
46
+ <div class="collapse navbar-collapse" id="navbarResponsive">
47
+ <ul class="navbar-nav ml-auto">
48
+ <li class="nav-item active">
49
+ <a class="nav-link" href="index.html">Authors
50
+ <span class="sr-only">(current)</span>
51
+ </a>
52
+ </li>
53
+ <li class="nav-item">
54
+ <a class="nav-link" href="books.html">Books</a>
55
+ </li>
56
+ <li class="nav-item">
57
+ <a class="nav-link" href="aaa.html">AAA</a>
58
+ </li>
59
+ </ul>
60
+ </div>
61
+ </div>
62
+ </nav>
63
+
64
+ <!-- Page Content -->
65
+ <div class="container">
66
+ <div class="row">
67
+ <div class="col-lg-12 text-center">
68
+ <h1 class="mt-5">Authors</h1>
69
+
70
+ <form>
71
+ <input type="hidden" id="author_id" value="">
72
+ <div class="input-group mb-3">
73
+ <div class="input-group-prepend">
74
+ <label class="input-group-text" for="author_id">Author name</label>
75
+ </div>
76
+ <input type="text" class="form-control" placeholder="Enter a name" id="name">
77
+ </div>
78
+ <div class="input-group">
79
+ <div class="input-group-prepend">
80
+ <label class="input-group-text">Year of birth</label>
81
+ </div>
82
+ <input type="text" class="form-control" placeholder="Enter a number" id="yob">
83
+ </div>
84
+
85
+ <button type="submit" class="btn btn-primary" id="btnSubmit" disabled="disabled">Submit</button>
86
+ <button type="button" class="btn btn-danger" id="btnDelete" disabled="disabled">Delete</button>
87
+ </form>
88
+
89
+
90
+ <table style="margin-top: 50px;" class="table table-hover" id="all">
91
+ <thead>
92
+ <tr>
93
+ <th scope="col">ID</th>
94
+ <th scope="col">Author name</th>
95
+ <th scope="col">Year of birth</th>
96
+ <th scope="col">Created at</th>
97
+ <th scope="col">Updated at</th>
98
+ <th scope="col">Book count</th>
99
+ </tr>
100
+ </thead>
101
+ <tbody></tbody>
102
+ </table>
103
+ </div>
104
+ </div>
105
+ </div>
106
+
107
+ <!-- Bootstrap core JavaScript -->
108
+ <script src="vendor/jquery/jquery.min.js"></script>
109
+ <script src="vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
110
+
111
+ <!-- GraphQL Plugin -->
112
+ <script src="vendor/graphql.min.js"></script>
113
+
114
+ <!-- Notifications -->
115
+ <script src="vendor/notify.min.js"></script>
116
+
117
+ <!-- App -->
118
+ <script src="authors.js"></script>
119
+
120
+ <script language="JavaScript">
121
+ $(document).ready(function () {
122
+
123
+ $('input[type="text"]').keyup(function () {
124
+ if ($(this).val() != '') {
125
+ $(':input[type="submit"]').prop('disabled', false);
126
+ } else {
127
+ $(':input[type="submit"]').prop('disabled', true);
128
+ }
129
+ });
130
+
131
+ authorList();
132
+ })
133
+ </script>
134
+
135
+ </body>
136
+
137
+ </html>