cyclid-ui 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7c825bc53e4d80b21910dc57748dbc5fd875eb7f
4
- data.tar.gz: ea890e1cc6d3f8ec89652cec593e57555dbc25b2
3
+ metadata.gz: 149e04846774e4747d1536102a1c02ccce49fd55
4
+ data.tar.gz: a6f68dca217f538ba9d663f4e22a899c406c3ccb
5
5
  SHA512:
6
- metadata.gz: 43f2bbd8bad9a2e0b0e73a40202fce843c05b3179db44d3cb60aa487eff9e184236baeb1ad1af85dd375b92f603b519055cf2fb7e9197222bc93866457bac342
7
- data.tar.gz: b7c8add78e315865b33af006ff5e026ee93eb536be156bc7f277c654e9c770c740f6eb90c6d720800f050d582a0899b63d4039ff93942a37a43b541cd154c72e
6
+ metadata.gz: fe51e9570ecbbeb8b99157fe38075ca3dcf79fd6df17f2e65c7bb9118d310edca8cf674a0baea402decbc56f182a9b0da0f32132fd6e949e9d1714967db98649
7
+ data.tar.gz: 5cd1e04814d5be7d64cbd619df01cc2f73516702a93c6d3c54c94e3bab62efb628ab437ed6aab23404a187b9986b87f2435bbff9aa3650f24fc3ed728c661708
@@ -20,7 +20,7 @@ module Cyclid
20
20
  module UI
21
21
  # Cyclid UI configuration
22
22
  class Config
23
- attr_reader :memcached, :log, :server_api, :client_api
23
+ attr_reader :memcached, :log, :server_api, :client_api, :signup
24
24
 
25
25
  def initialize(path)
26
26
  # Try to load the configuration file. If it can't be loaded, we'll
@@ -56,6 +56,8 @@ module Cyclid
56
56
  @client_api = URI(api['client'])
57
57
  end
58
58
 
59
+ # URL of the signup link, if one is defined
60
+ @signup = manage['signup'] || nil
59
61
  rescue StandardError => ex
60
62
  abort "Failed to load configuration file #{path}: #{ex}"
61
63
  end
@@ -23,6 +23,7 @@ module Cyclid
23
23
  class Auth < Base
24
24
  get '/login' do
25
25
  @message = flash[:login_error]
26
+ @signup = Cyclid.config.signup
26
27
  mustache :login, layout: false
27
28
  end
28
29
 
@@ -58,6 +58,26 @@ module Cyclid
58
58
 
59
59
  mustache :job
60
60
  end
61
+
62
+ get '/:name/config' do
63
+ authenticate!
64
+
65
+ # Build breadcrumbs
66
+ name = params[:name]
67
+
68
+ @crumbs = []
69
+ @crumbs << { 'url' => "/#{name}", 'name' => name.capitalize }
70
+ @crumbs << { 'name' => 'Configuration' }
71
+
72
+ @organization = name
73
+ @linkback_url = "/#{name}"
74
+
75
+ api_server = Cyclid.config.client_api
76
+ @org_url = "#{api_server}/organizations/#{params[:name]}"
77
+ @current_user = current_user
78
+
79
+ mustache :config
80
+ end
61
81
  end
62
82
  end
63
83
  end
@@ -32,6 +32,8 @@ module Cyclid
32
32
  @user_url = "#{@api_url}/users/#{params[:username]}"
33
33
  @current_user = current_user
34
34
 
35
+ @organization = current_user.organizations.first
36
+
35
37
  mustache :user
36
38
  end
37
39
  end
@@ -0,0 +1,63 @@
1
+ <div class="alert alert-danger alert-dismissible hidden" role="alert" id="config_failure">
2
+ <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
3
+ <div id="error_message"></div>
4
+ </div>
5
+
6
+ <div class="container">
7
+
8
+ <div class="panel panel-default" id="config">
9
+ <div class="panel-heading">
10
+ <h3 class="panel-title"><span id="config_plugin_name" style="text-transform:capitalize;"></span></h3>
11
+ </div>
12
+
13
+ <div class="panel-body">
14
+
15
+ <div class="row">
16
+ <div class="col-md-2">
17
+ <ul class="list-group" id="plugin-list">
18
+ </ul>
19
+ </div>
20
+
21
+ <div class="col-md-10">
22
+ <div class="row">
23
+ <form id="config_form">
24
+ </form>
25
+ </div>
26
+ </div>
27
+ </div>
28
+
29
+ </div>
30
+
31
+ </div>
32
+ </div>
33
+
34
+ <!-- "success" modal -->
35
+ <div class="modal fade" id="config_success_modal">
36
+ <div class="modal-dialog">
37
+ <div class="modal-content">
38
+ <div class="modal-header">
39
+ <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
40
+ <h4 class="modal-title">Configuration saved</h4>
41
+ </div>
42
+
43
+ <div class="modal-body">
44
+ The configuration was successfully saved.
45
+ </div>
46
+
47
+ <div class="modal-footer">
48
+ <button type="button" class="btn btn-success" data-dismiss="modal">Okay</button>
49
+ </div>
50
+ </div>
51
+ </div>
52
+ </div>
53
+
54
+ <script type="text/javascript" src="/js/cyclid.js"></script>
55
+ <script type="text/javascript" src="/js/api.js"></script>
56
+ <script type="text/javascript" src="/js/config.js"></script>
57
+ <script>
58
+ var gblUsername = '{{username}}';
59
+ var gblOrgUrl = '{{org_url}}';
60
+ var url = `${gblOrgUrl}/configs`;
61
+
62
+ api_get(url, gblUsername, config_update_list, config_get_failed);
63
+ </script>
@@ -51,6 +51,11 @@
51
51
  </li>
52
52
  </ul>
53
53
 
54
+ <ul class="nav navbar-nav">
55
+ <li><a href="/{{organization}}">Jobs</a></li>
56
+ <li><a href="/{{organization}}/config">Configuration</a></li>
57
+ </ul>
58
+
54
59
  <ul class="nav navbar-nav navbar-right">
55
60
  <li class="dropdown">
56
61
  <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">{{username}}&nbsp;<span class="caret"></span></a>
@@ -51,6 +51,9 @@
51
51
  <input type="password" class="form-control" name="password" placeholder="Password">
52
52
  </div>
53
53
  <input type="submit" class="btn btn-default" value="Login">
54
+ {{#signup}}
55
+ <small><a class="btn btn-sm" style="float:right;" href="{{signup}}">Don't have an account? Create one now.</a></small>
56
+ {{/signup}}
54
57
  </form>
55
58
  </div>
56
59
  </div>
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+ # Copyright 2016 Liqwyd Ltd.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ module Cyclid
17
+ module UI
18
+ module Views
19
+ # Plugin config view
20
+ class Config < Layout
21
+ attr_reader :org_url
22
+ end
23
+ end
24
+ end
25
+ end
@@ -18,7 +18,11 @@ module Cyclid
18
18
  module Views
19
19
  # Login view. This is a non-Layout view.
20
20
  class Login < Mustache
21
- attr_reader :message
21
+ attr_reader :message, :signup
22
+
23
+ def title
24
+ @title || 'Cyclid'
25
+ end
22
26
  end
23
27
  end
24
28
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  module Cyclid
3
3
  module UI
4
- VERSION = '0.1.1'
4
+ VERSION = '0.2.0'
5
5
  end
6
6
  end
@@ -21,6 +21,7 @@ function api_put(url, data, username, success, error) {
21
21
  type: 'PUT',
22
22
  url: encodeURI(url),
23
23
  data: JSON.stringify(data),
24
+ dataType: 'text',
24
25
  contentType: 'application/json',
25
26
  crossDomain: true,
26
27
  beforeSend: function(xhr) {
@@ -0,0 +1,183 @@
1
+ /* Submit the current configuration data to the API */
2
+ function config_save(){
3
+ console.log('saving config...');
4
+
5
+ event.preventDefault();
6
+
7
+ var form_elements = new Array();
8
+ $('#config_form :input').each(
9
+ function(){
10
+ form_elements.push($(this));
11
+ }
12
+ );
13
+
14
+ var length = form_elements.length;
15
+ var config_data = new Object();
16
+ for(var i=0; i < length; i++){
17
+ var input = form_elements[i];
18
+ console.log(input);
19
+
20
+ if(input.attr('type') == 'text' || input.attr('type') == 'password') {
21
+ var name = input.attr('name');
22
+ var value = input.val();
23
+ var config_value = value == '' ? null : value;
24
+
25
+ console.log(`${name}=${config_value}`);
26
+ config_data[name] = config_value;
27
+ }
28
+ }
29
+ console.log(`configuration is ${JSON.stringify(config_data)}`);
30
+
31
+ /* Write the configuration data to the API */
32
+ var plugin_name = $('#config_form').data('plugin_name');
33
+ var plugin_type = $('#config_form').data('plugin_type');
34
+
35
+ var url = `${gblOrgUrl}/configs/${plugin_type}/${plugin_name}`;
36
+ api_put(url, config_data, gblUsername, config_set_success, config_set_failed);
37
+ }
38
+
39
+ /* Add a "string" schema element to the configuration data form */
40
+ function config_append_string(elem, schema, config){
41
+ var default_data = schema.default == null ? '' : schema.default;
42
+ var config_data = config == undefined ? default_data : config;
43
+ var row = `<div class="form-group"><label for="${schema.name}">${schema.description}</label><input type="text" class="form-control" name="${schema.name}" value="${config_data}"></div>`
44
+
45
+ elem.append(row);
46
+ }
47
+
48
+ /* Add a "password" schema element to the configuration data form */
49
+ function config_append_password(elem, schema, config){
50
+ var default_data = schema.default == null ? '' : schema.default;
51
+ var config_data = config == undefined ? default_data : config;
52
+ var row = `<div class="form-group"><label for="${schema.name}">${schema.description}</label><input type="password" class="form-control" name="${schema.name}" value="${config_data}"></div>`
53
+
54
+ elem.append(row);
55
+ }
56
+
57
+ /* Add a button as a link to a URL to the configuration data form */
58
+ function config_append_link(elem, schema, url){
59
+ var row = `<div class="form-group"><a href="${url}" id="${schema.name}" class="btn btn-default" role="button">${schema.description}</a></div>`
60
+
61
+ elem.append(row);
62
+ }
63
+
64
+ /* Add a "link-relative" (I.e. a link relative to the plugin API) schema element to the configuration data form */
65
+ function config_append_link_relative(elem, schema, config){
66
+ var plugin_name = $('#config_form').data('plugin_name');
67
+ var url = `${gblOrgUrl}/plugins/${plugin_name}${schema.default}`;
68
+
69
+ config_append_link(elem, schema, url);
70
+ }
71
+
72
+ /* Add a "link-absolute" (I.e. a link to a fully qualified URL) schema element to the configuration data form */
73
+ function config_append_link_absolute(elem, schema, config){
74
+ config_append_link(elem, schema, config);
75
+ }
76
+
77
+ function config_update_plugin(data) {
78
+ console.log(JSON.stringify(data));
79
+
80
+ var schema = data.schema;
81
+ var config = data.config;
82
+ var form = $('#config_form');
83
+
84
+ /* Clear any existing form elements */
85
+ form.empty();
86
+
87
+ /* Walk the schema and insert each element */
88
+ var length = schema.length;
89
+ for(var i=0; i < length; i++){
90
+ var item_schema = schema[i];
91
+ var item_config = config[item_schema.name];
92
+
93
+ switch(item_schema.type){
94
+ case 'string': {
95
+ console.log(`${item_schema.name} is a string`);
96
+ config_append_string(form, item_schema, item_config);
97
+ break;
98
+ }
99
+ case 'password': {
100
+ console.log(`${item_schema.name} is a password`);
101
+ config_append_password(form, item_schema, item_config);
102
+ break;
103
+ }
104
+ case 'integer': {
105
+ console.log(`${item_schema.name} is an integer`);
106
+ config_append_string(form, item_schema, item_config);
107
+ break;
108
+ }
109
+ case 'hash-list': {
110
+ console.log(`${item_schema.name} is a hash-list`);
111
+ break;
112
+ }
113
+ case 'link-relative': {
114
+ console.log(`${item_schema.name} is a link-relative`);
115
+ config_append_link_relative(form, item_schema, item_config);
116
+ break;
117
+ }
118
+ default: {
119
+ console.log(`don't know what ${item_schema.name} is`);
120
+ break;
121
+ }
122
+ }
123
+ }
124
+
125
+ /* Add the "Save" button */
126
+ form.append('<input type="submit" class="btn btn-primary" onclick="config_save()" value="Save">');
127
+ }
128
+
129
+ function config_select(plugin_type, plugin_name) {
130
+ console.log(`select ${plugin_type}/${plugin_name}`);
131
+
132
+ var form = $('#config_form');
133
+ form.data('plugin_type', plugin_type);
134
+ form.data('plugin_name', plugin_name);
135
+
136
+ $('#config_plugin_name').html(plugin_name)
137
+
138
+ var url = `${gblOrgUrl}/configs/${plugin_type}/${plugin_name}`;
139
+ api_get(url, gblUsername, config_update_plugin, config_get_failed);
140
+ }
141
+
142
+ function config_show_failure(failure_message){
143
+ $('#config_failure > #error_message').html(failure_message);
144
+ $('#config_failure').removeClass('hidden');
145
+ }
146
+
147
+ function config_get_failed(xhr) {
148
+ var failure_message = `<p>
149
+ <h2>Failed to retrieve configuration data</h2><br>
150
+ <strong>${xhr.status}:</strong> ${xhr.responseText}
151
+ </p>`
152
+ config_show_failure(failure_message);
153
+ }
154
+
155
+ function config_set_failed(xhr) {
156
+ var failure_message = `<p>
157
+ <h2>Failed to save configuration data</h2><br>
158
+ <strong>${xhr.status}:</strong> ${xhr.responseText}
159
+ </p>`
160
+ config_show_failure(failure_message);
161
+ }
162
+
163
+ function config_set_success(xhr){
164
+ $('#config_success_modal').modal();
165
+ }
166
+
167
+ function config_update_list(data) {
168
+ console.log(JSON.stringify(data));
169
+
170
+ var length = data.length;
171
+ for(var i=0; i < length; i++ ){
172
+ var plugin = data[i];
173
+ var type = plugin.type
174
+ var name = plugin.name
175
+
176
+ var item = `<a href="#" class="list-group-item list-group-item-action" style="text-transform:capitalize;" onclick="config_select('${type}', '${name}')">${name}</a>`
177
+ $('#plugin-list').append(item);
178
+ }
179
+
180
+ // Select the first item in the list
181
+ plugin = data[0];
182
+ config_select(plugin.type, plugin.name);
183
+ }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cyclid-ui
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kristian Van Der Vliet
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-10-05 00:00:00.000000000 Z
11
+ date: 2016-10-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: require_all
@@ -212,6 +212,7 @@ files:
212
212
  - app/cyclid_ui/helpers.rb
213
213
  - app/cyclid_ui/memcache.rb
214
214
  - app/cyclid_ui/models/user.rb
215
+ - app/cyclid_ui/templates/config.mustache
215
216
  - app/cyclid_ui/templates/footer.mustache
216
217
  - app/cyclid_ui/templates/job.mustache
217
218
  - app/cyclid_ui/templates/job_info.mustache
@@ -219,6 +220,7 @@ files:
219
220
  - app/cyclid_ui/templates/login.mustache
220
221
  - app/cyclid_ui/templates/organization.mustache
221
222
  - app/cyclid_ui/templates/user.mustache
223
+ - app/cyclid_ui/views/config.rb
222
224
  - app/cyclid_ui/views/job.rb
223
225
  - app/cyclid_ui/views/layout.rb
224
226
  - app/cyclid_ui/views/login.rb
@@ -235,6 +237,7 @@ files:
235
237
  - public/images/favicon64.png
236
238
  - public/images/favicon96.png
237
239
  - public/js/api.js
240
+ - public/js/config.js
238
241
  - public/js/cyclid.js
239
242
  - public/js/job.js
240
243
  - public/js/organization.js