├── .editorconfig
├── .gitignore
├── LICENSE
├── README.md
├── gulpfile.js
├── index.html
├── package.json
├── scripts
├── app.cjsx
├── components
│ ├── Config.cjsx
│ ├── Context.cjsx
│ ├── Contexts.cjsx
│ ├── CreateContext.cjsx
│ ├── Jar.cjsx
│ ├── JarLoad.cjsx
│ ├── Jars.cjsx
│ ├── Job.cjsx
│ ├── JobResult.cjsx
│ ├── JobSubmit.cjsx
│ ├── Jobs.cjsx
│ └── Main.cjsx
├── events
│ ├── click-job.coffee
│ ├── context-loaded.coffee
│ ├── context-removed.coffee
│ └── jar-loaded.coffee
└── services
│ ├── api.coffee
│ ├── binary-send.coffee
│ ├── pretty-print.coffee
│ └── time.coffee
└── styles
├── _colors.sass
└── main.sass
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig helps developers define and maintain consistent
2 | # coding styles between different editors and IDEs
3 | # editorconfig.org
4 |
5 | root = true
6 |
7 |
8 | [*]
9 |
10 | # Change these settings to your own preference
11 | indent_style = space
12 | indent_size = 2
13 |
14 | # We recommend you to keep these unchanged
15 | end_of_line = lf
16 | charset = utf-8
17 | trim_trailing_whitespace = true
18 | insert_final_newline = true
19 |
20 | [*.md]
21 | trim_trailing_whitespace = false
22 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .tmp
3 | .idea
4 | dist
5 | node_modules
6 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 |
2 | Apache License
3 | Version 2.0, January 2004
4 | http://www.apache.org/licenses/
5 |
6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7 |
8 | 1. Definitions.
9 |
10 | "License" shall mean the terms and conditions for use, reproduction,
11 | and distribution as defined by Sections 1 through 9 of this document.
12 |
13 | "Licensor" shall mean the copyright owner or entity authorized by
14 | the copyright owner that is granting the License.
15 |
16 | "Legal Entity" shall mean the union of the acting entity and all
17 | other entities that control, are controlled by, or are under common
18 | control with that entity. For the purposes of this definition,
19 | "control" means (i) the power, direct or indirect, to cause the
20 | direction or management of such entity, whether by contract or
21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
22 | outstanding shares, or (iii) beneficial ownership of such entity.
23 |
24 | "You" (or "Your") shall mean an individual or Legal Entity
25 | exercising permissions granted by this License.
26 |
27 | "Source" form shall mean the preferred form for making modifications,
28 | including but not limited to software source code, documentation
29 | source, and configuration files.
30 |
31 | "Object" form shall mean any form resulting from mechanical
32 | transformation or translation of a Source form, including but
33 | not limited to compiled object code, generated documentation,
34 | and conversions to other media types.
35 |
36 | "Work" shall mean the work of authorship, whether in Source or
37 | Object form, made available under the License, as indicated by a
38 | copyright notice that is included in or attached to the work
39 | (an example is provided in the Appendix below).
40 |
41 | "Derivative Works" shall mean any work, whether in Source or Object
42 | form, that is based on (or derived from) the Work and for which the
43 | editorial revisions, annotations, elaborations, or other modifications
44 | represent, as a whole, an original work of authorship. For the purposes
45 | of this License, Derivative Works shall not include works that remain
46 | separable from, or merely link (or bind by name) to the interfaces of,
47 | the Work and Derivative Works thereof.
48 |
49 | "Contribution" shall mean any work of authorship, including
50 | the original version of the Work and any modifications or additions
51 | to that Work or Derivative Works thereof, that is intentionally
52 | submitted to Licensor for inclusion in the Work by the copyright owner
53 | or by an individual or Legal Entity authorized to submit on behalf of
54 | the copyright owner. For the purposes of this definition, "submitted"
55 | means any form of electronic, verbal, or written communication sent
56 | to the Licensor or its representatives, including but not limited to
57 | communication on electronic mailing lists, source code control systems,
58 | and issue tracking systems that are managed by, or on behalf of, the
59 | Licensor for the purpose of discussing and improving the Work, but
60 | excluding communication that is conspicuously marked or otherwise
61 | designated in writing by the copyright owner as "Not a Contribution."
62 |
63 | "Contributor" shall mean Licensor and any individual or Legal Entity
64 | on behalf of whom a Contribution has been received by Licensor and
65 | subsequently incorporated within the Work.
66 |
67 | 2. Grant of Copyright License. Subject to the terms and conditions of
68 | this License, each Contributor hereby grants to You a perpetual,
69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70 | copyright license to reproduce, prepare Derivative Works of,
71 | publicly display, publicly perform, sublicense, and distribute the
72 | Work and such Derivative Works in Source or Object form.
73 |
74 | 3. Grant of Patent License. Subject to the terms and conditions of
75 | this License, each Contributor hereby grants to You a perpetual,
76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77 | (except as stated in this section) patent license to make, have made,
78 | use, offer to sell, sell, import, and otherwise transfer the Work,
79 | where such license applies only to those patent claims licensable
80 | by such Contributor that are necessarily infringed by their
81 | Contribution(s) alone or by combination of their Contribution(s)
82 | with the Work to which such Contribution(s) was submitted. If You
83 | institute patent litigation against any entity (including a
84 | cross-claim or counterclaim in a lawsuit) alleging that the Work
85 | or a Contribution incorporated within the Work constitutes direct
86 | or contributory patent infringement, then any patent licenses
87 | granted to You under this License for that Work shall terminate
88 | as of the date such litigation is filed.
89 |
90 | 4. Redistribution. You may reproduce and distribute copies of the
91 | Work or Derivative Works thereof in any medium, with or without
92 | modifications, and in Source or Object form, provided that You
93 | meet the following conditions:
94 |
95 | (a) You must give any other recipients of the Work or
96 | Derivative Works a copy of this License; and
97 |
98 | (b) You must cause any modified files to carry prominent notices
99 | stating that You changed the files; and
100 |
101 | (c) You must retain, in the Source form of any Derivative Works
102 | that You distribute, all copyright, patent, trademark, and
103 | attribution notices from the Source form of the Work,
104 | excluding those notices that do not pertain to any part of
105 | the Derivative Works; and
106 |
107 | (d) If the Work includes a "NOTICE" text file as part of its
108 | distribution, then any Derivative Works that You distribute must
109 | include a readable copy of the attribution notices contained
110 | within such NOTICE file, excluding those notices that do not
111 | pertain to any part of the Derivative Works, in at least one
112 | of the following places: within a NOTICE text file distributed
113 | as part of the Derivative Works; within the Source form or
114 | documentation, if provided along with the Derivative Works; or,
115 | within a display generated by the Derivative Works, if and
116 | wherever such third-party notices normally appear. The contents
117 | of the NOTICE file are for informational purposes only and
118 | do not modify the License. You may add Your own attribution
119 | notices within Derivative Works that You distribute, alongside
120 | or as an addendum to the NOTICE text from the Work, provided
121 | that such additional attribution notices cannot be construed
122 | as modifying the License.
123 |
124 | You may add Your own copyright statement to Your modifications and
125 | may provide additional or different license terms and conditions
126 | for use, reproduction, or distribution of Your modifications, or
127 | for any such Derivative Works as a whole, provided Your use,
128 | reproduction, and distribution of the Work otherwise complies with
129 | the conditions stated in this License.
130 |
131 | 5. Submission of Contributions. Unless You explicitly state otherwise,
132 | any Contribution intentionally submitted for inclusion in the Work
133 | by You to the Licensor shall be under the terms and conditions of
134 | this License, without any additional terms or conditions.
135 | Notwithstanding the above, nothing herein shall supersede or modify
136 | the terms of any separate license agreement you may have executed
137 | with Licensor regarding such Contributions.
138 |
139 | 6. Trademarks. This License does not grant permission to use the trade
140 | names, trademarks, service marks, or product names of the Licensor,
141 | except as required for reasonable and customary use in describing the
142 | origin of the Work and reproducing the content of the NOTICE file.
143 |
144 | 7. Disclaimer of Warranty. Unless required by applicable law or
145 | agreed to in writing, Licensor provides the Work (and each
146 | Contributor provides its Contributions) on an "AS IS" BASIS,
147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148 | implied, including, without limitation, any warranties or conditions
149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150 | PARTICULAR PURPOSE. You are solely responsible for determining the
151 | appropriateness of using or redistributing the Work and assume any
152 | risks associated with Your exercise of permissions under this License.
153 |
154 | 8. Limitation of Liability. In no event and under no legal theory,
155 | whether in tort (including negligence), contract, or otherwise,
156 | unless required by applicable law (such as deliberate and grossly
157 | negligent acts) or agreed to in writing, shall any Contributor be
158 | liable to You for damages, including any direct, indirect, special,
159 | incidental, or consequential damages of any character arising as a
160 | result of this License or out of the use or inability to use the
161 | Work (including but not limited to damages for loss of goodwill,
162 | work stoppage, computer failure or malfunction, or any and all
163 | other commercial damages or losses), even if such Contributor
164 | has been advised of the possibility of such damages.
165 |
166 | 9. Accepting Warranty or Additional Liability. While redistributing
167 | the Work or Derivative Works thereof, You may choose to offer,
168 | and charge a fee for, acceptance of support, warranty, indemnity,
169 | or other liability obligations and/or rights consistent with this
170 | License. However, in accepting such obligations, You may act only
171 | on Your own behalf and on Your sole responsibility, not on behalf
172 | of any other Contributor, and only if You agree to indemnify,
173 | defend, and hold each Contributor harmless for any liability
174 | incurred by, or claims asserted against, such Contributor by reason
175 | of your accepting any such warranty or additional liability.
176 |
177 | END OF TERMS AND CONDITIONS
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Spark JobServer Frontend
2 | ========================
3 |
4 | This is a single page application that can be used to monitor and drive the [Spark JobServer](https://github.com/spark-jobserver/spark-jobserver).
5 |
6 | Usage
7 | ------
8 |
9 | The application can be used both inside the JobServer itself, or standalone. In the first case, build the application and deploy it inside `spark-jobserver/main/resources/html`. If you want to use it from the outside, you will have to patch the JobServer routes to add [CORS](http://en.wikipedia.org/wiki/Cross-origin_resource_sharing) support.
10 |
11 | Build and development
12 | ----------------------
13 |
14 | To build the application, you will need [node.js](http://nodejs.org/), [npm](https://www.npmjs.org/), [gulp](http://gulpjs.com/) and [browserify](http://browserify.org/). First, install the dependencies with
15 |
16 | npm install
17 |
18 | Then, you can have a development version with live reload with
19 |
20 | gulp watch
21 |
22 | When you are done, create a production ready version of the JS bundle inside the `dist` folder:
23 |
24 | gulp build
25 |
26 | If you want to serve the application directly from the JobServer, you will need to run the following task, that uses different paths:
27 |
28 | gulp build-jobserver
29 |
30 | License
31 | -------
32 |
33 | [Apache 2](http://opensource.org/licenses/Apache-2.0)
--------------------------------------------------------------------------------
/gulpfile.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var gulp = require('gulp'),
4 | changed = require('gulp-changed'),
5 | sass = require('gulp-sass'),
6 | csso = require('gulp-csso'),
7 | useref = require('gulp-useref'),
8 | autoprefixer = require('gulp-autoprefixer'),
9 | prefix = require('gulp-prefix'),
10 | browserify = require('browserify'),
11 | watchify = require('watchify'),
12 | source = require('vinyl-source-stream'),
13 | buffer = require('vinyl-buffer'),
14 | reactify = require('reactify'),
15 | coffeereactify = require('coffee-reactify'),
16 | uglify = require('gulp-uglify'),
17 | del = require('del'),
18 | notify = require('gulp-notify'),
19 | browserSync = require('browser-sync'),
20 | reload = browserSync.reload,
21 | p = {
22 | cjsx: './scripts/app.cjsx',
23 | sass: 'styles/main.sass',
24 | bundle: 'app.js',
25 | distJs: 'dist/js',
26 | distCss: 'dist/css'
27 | };
28 |
29 | gulp.task('clean', function(cb) {
30 | del(['dist'], cb);
31 | });
32 |
33 | gulp.task('browserSync', function() {
34 | browserSync({
35 | server: {
36 | baseDir: ['./', 'dist/']
37 | }
38 | })
39 | });
40 |
41 | gulp.task('watchify', function() {
42 | var bundler = watchify(browserify(p.cjsx, watchify.args));
43 |
44 | function rebundle() {
45 | return bundler
46 | .bundle()
47 | .on('error', notify.onError())
48 | .pipe(source(p.bundle))
49 | .pipe(gulp.dest(p.distJs))
50 | .pipe(reload({stream: true}));
51 | }
52 |
53 | bundler.transform(coffeereactify)
54 | .on('update', rebundle);
55 | return rebundle();
56 | });
57 |
58 | gulp.task('build-jobserver', ['build'], function () {
59 | return gulp.src('dist/index.html')
60 | .pipe(prefix('html/', null, true))
61 | .pipe(gulp.dest('dist'));
62 | });
63 |
64 | gulp.task('build', ['styles', 'browserify'], function () {
65 | var assets = useref.assets();
66 |
67 | return gulp.src('index.html')
68 | .pipe(assets)
69 | .pipe(csso())
70 | .pipe(assets.restore())
71 | .pipe(useref())
72 | .pipe(gulp.dest('dist'));
73 | });
74 |
75 | gulp.task('browserify', ['clean'], function() {
76 | browserify(p.cjsx)
77 | .transform(coffeereactify)
78 | .bundle()
79 | .pipe(source(p.bundle))
80 | .pipe(buffer())
81 | .pipe(uglify())
82 | .pipe(gulp.dest(p.distJs));
83 | });
84 |
85 | function buildStyles() {
86 | return gulp.src(p.sass)
87 | .pipe(changed(p.distCss))
88 | .pipe(sass({errLogToConsole: true, sourceComments: 'normal'}))
89 | .on('error', notify.onError())
90 | .pipe(autoprefixer('last 1 version'))
91 | .pipe(csso())
92 | .pipe(gulp.dest(p.distCss))
93 | .pipe(reload({stream: true}));
94 | }
95 |
96 | gulp.task('watchStyles', buildStyles);
97 |
98 | gulp.task('styles', ['clean'], buildStyles);
99 |
100 | gulp.task('watchTask', function() {
101 | gulp.watch(p.scss, ['styles']);
102 | });
103 |
104 | gulp.task('watch', ['clean'], function() {
105 | gulp.start(['browserSync', 'watchTask', 'watchify', 'watchStyles']);
106 | });
107 |
108 | gulp.task('default', function() {
109 | console.log('Run "gulp watch, gulp build or build-jobserver"');
110 | });
111 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Spark JobServer
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "jobserver-frontend",
3 | "version": "0.1.0",
4 | "description": "Frontend for Spark JobServer",
5 | "repository": "https://github.com/unicredit/spark-jobserver-frontend",
6 | "dependencies": {
7 | "bootstrap": "3.3.1",
8 | "moment": "2.8.4",
9 | "ramda": "0.8.0",
10 | "react": "0.12.0",
11 | "react-bootstrap": "0.13.0",
12 | "react-router": "0.11.4",
13 | "react-select": "0.2.7",
14 | "rest": "1.2.0",
15 | "signals": "1.0.0",
16 | "when": "3.6.3"
17 | },
18 | "devDependencies": {
19 | "browser-sync": "^1.6.2",
20 | "browserify": "^6.2.0",
21 | "coffee-reactify": "^2.1.0",
22 | "del": "^0.1.3",
23 | "gulp": "^3.8.9",
24 | "gulp-autoprefixer": "1.0.1",
25 | "gulp-changed": "^1.0.0",
26 | "gulp-csso": "^0.2.9",
27 | "gulp-notify": "^2.0.0",
28 | "gulp-prefix": "^0.0.13",
29 | "gulp-sass": "^1.2.2",
30 | "gulp-uglify": "^1.0.1",
31 | "gulp-useref": "^1.0.2",
32 | "reactify": "^0.15.2",
33 | "vinyl-buffer": "^1.0.0",
34 | "vinyl-source-stream": "^1.0.0",
35 | "watchify": "^2.1.0"
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/scripts/app.cjsx:
--------------------------------------------------------------------------------
1 | # @cjsx React.DOM
2 |
3 | # Copyright 2014 UniCredit S.p.A.
4 |
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 |
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | React = require('react/addons')
18 | { Route, Redirect } = Router = require('react-router')
19 |
20 | Main = require('./components/Main.cjsx')
21 | Jobs = require('./components/Jobs.cjsx')
22 | JobResult = require('./components/JobResult.cjsx')
23 | JobSubmit = require('./components/JobSubmit.cjsx')
24 | Jars = require('./components/Jars.cjsx')
25 | Contexts = require('./components/Contexts.cjsx')
26 |
27 |
28 | window.onload = ->
29 | routes =
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 | Router.run routes, (Handler) ->
40 | React.render(, document.body)
--------------------------------------------------------------------------------
/scripts/components/Config.cjsx:
--------------------------------------------------------------------------------
1 | # @cjsx React.DOM
2 |
3 | # Copyright 2014 UniCredit S.p.A.
4 |
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 |
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 |
18 | React = require('react/addons')
19 |
20 | api = require('../services/api.coffee')
21 | prettyPrint = require('../services/pretty-print.coffee')
22 |
23 |
24 | module.exports = React.createClass
25 | componentWillMount: ->
26 | api.jobConfig(@props.id).then (result) => @setState(config: result)
27 |
28 | getInitialState: ->
29 | config: null
30 |
31 | render: ->
32 | if not @state.config then return null
33 |
34 |
--------------------------------------------------------------------------------
/scripts/components/Context.cjsx:
--------------------------------------------------------------------------------
1 | # @cjsx React.DOM
2 |
3 | # Copyright 2014 UniCredit S.p.A.
4 |
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 |
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | React = require('react/addons')
18 | Button = require('react-bootstrap/Button')
19 | Modal = require('react-bootstrap/Modal')
20 | ModalTrigger = require('react-bootstrap/ModalTrigger')
21 |
22 | api = require('../services/api.coffee')
23 | contextRemoved = require('../events/context-removed.coffee')
24 |
25 |
26 | ConfirmDelete = React.createClass
27 | delete: ->
28 | @props.onDelete()
29 | @props.onRequestHide()
30 |
31 | render: ->
32 |
33 |
--------------------------------------------------------------------------------
/scripts/components/Contexts.cjsx:
--------------------------------------------------------------------------------
1 | # @cjsx React.DOM
2 |
3 | # Copyright 2014 UniCredit S.p.A.
4 |
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 |
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | React = require('react/addons')
18 | Row = require('react-bootstrap/Row')
19 |
20 | api = require('../services/api.coffee')
21 | contextLoaded = require('../events/context-loaded.coffee')
22 | contextRemoved = require('../events/context-removed.coffee')
23 | Context = require('./Context.cjsx')
24 | CreateContext = require('./CreateContext.cjsx')
25 |
26 |
27 | module.exports = React.createClass
28 | componentWillMount: ->
29 | api.contexts().then (result) => @setState(contexts: result)
30 | contextLoaded.add @uploaded
31 | contextRemoved.add @removed
32 |
33 | componentWillUnmount: ->
34 | contextLoaded.remove @uploaded
35 | contextRemoved.remove @removed
36 |
37 | removed: (context) ->
38 | contexts = @state.contexts.filter (c) -> c != context
39 | @setState(contexts: contexts)
40 |
41 | uploaded: ->
42 | api.contexts().then (result) => @setState(contexts: result, success: true)
43 |
44 | getInitialState: ->
45 | contexts: []
46 | success: false
47 |
48 | render: ->
49 | contextList = @state.contexts.map (context) =>
50 |
51 |
52 |
53 |
Available contexts
54 |
55 |
56 |
57 |
Name
58 |
59 |
60 |
61 | { contextList }
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/scripts/components/CreateContext.cjsx:
--------------------------------------------------------------------------------
1 | # @cjsx React.DOM
2 |
3 | # Copyright 2014 UniCredit S.p.A.
4 |
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 |
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | React = require('react/addons')
18 | Row = require('react-bootstrap/Row')
19 | Col = require('react-bootstrap/Col')
20 | Alert = require('react-bootstrap/Alert')
21 | Input = require('react-bootstrap/Input')
22 | Select = require('react-select')
23 |
24 | api = require('../services/api.coffee')
25 | contextLoaded = require('../events/context-loaded.coffee')
26 |
27 |
28 | units = [
29 | { value: 'K', label: 'Kb' }
30 | { value: 'M', label: 'Mb' }
31 | { value: 'G', label: 'Gb' }
32 | ]
33 |
34 | module.exports = React.createClass
35 | mixins: [React.addons.LinkedStateMixin]
36 |
37 | getInitialState: ->
38 | cpu: null
39 | memory: null
40 | memoryUnit: 'M'
41 | error: null
42 |
43 | isInteger: (text) -> parseInt(text).toString() == text
44 |
45 | validate: (ref) ->
46 | value = if @refs[ref] then @refs[ref].getValue()
47 | if value and not @isInteger(value) then 'error'
48 |
49 | changeUnit: (unit) -> @setState(memoryUnit: unit)
50 |
51 | submit: ->
52 | if @state.cpu and not @isInteger(@state.cpu) then return
53 | if @state.memory and not @isInteger(@state.memory) then return
54 | api.createContext(@state.contextName, @state.cpu, @state.memory, @state.memoryUnit).then @handleResponse
55 |
56 | handleResponse: (response) ->
57 | if response.status.code == 200
58 | contextLoaded.dispatch true
59 | @setState(error: null)
60 | else
61 | @setState(error: response.entity.result)
62 |
63 | render: ->
64 | error = if @state.error then { @state.error }
65 | success = if @props.success and not @state.error then 'Context successfully created'
66 |
67 |
--------------------------------------------------------------------------------
/scripts/components/Jar.cjsx:
--------------------------------------------------------------------------------
1 | # @cjsx React.DOM
2 |
3 | # Copyright 2014 UniCredit S.p.A.
4 |
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 |
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | React = require('react/addons')
18 |
19 | time = require('../services/time.coffee')
20 |
21 |
22 | module.exports = React.createClass
23 | render: ->
24 | [name, date] = @props.jar
25 |
26 |
27 |
{ name }
28 |
{ time.format(date) }
29 |
--------------------------------------------------------------------------------
/scripts/components/JarLoad.cjsx:
--------------------------------------------------------------------------------
1 | # @cjsx React.DOM
2 |
3 | # Copyright 2014 UniCredit S.p.A.
4 |
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 |
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | React = require('react/addons')
18 | Row = require('react-bootstrap/Row')
19 | Col = require('react-bootstrap/Col')
20 | Alert = require('react-bootstrap/Alert')
21 | Input = require('react-bootstrap/Input')
22 |
23 | api = require('../services/api.coffee')
24 | jarLoaded = require('../events/jar-loaded.coffee')
25 |
26 |
27 | module.exports = React.createClass
28 | mixins: [React.addons.LinkedStateMixin]
29 |
30 | getInitialState: ->
31 | appName: ''
32 | file: null
33 | fileType: null
34 | error: null
35 |
36 | submit: (event) ->
37 | if not @state.appName
38 | @setError('No application name')
39 | return
40 | if not @state.file
41 | @setError('No file selected')
42 | return
43 | api.jarLoad(@state.appName, @state.file, @state.fileType).then @handleResponse
44 |
45 | setError: (text) -> @setState(error: text)
46 |
47 | handleFile: (event) ->
48 | file = event.target.files[0]
49 | type = file.type
50 | reader = new FileReader()
51 | reader.onload = (upload) =>
52 | @setState(file: upload.target.result, fileType: type)
53 | reader.readAsBinaryString(file)
54 |
55 | handleResponse: (response) ->
56 | if response.status.code == 200
57 | jarLoaded.dispatch true
58 | @setError(null)
59 | else
60 | console.log response
61 | @setError(response.entity.result)
62 |
63 | render: ->
64 | error = if @state.error then { @state.error }
65 | success = if @props.success and not @state.error then 'Application successfully uploaded'
66 |
67 |
--------------------------------------------------------------------------------
/scripts/components/Jars.cjsx:
--------------------------------------------------------------------------------
1 | # @cjsx React.DOM
2 |
3 | # Copyright 2014 UniCredit S.p.A.
4 |
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 |
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | React = require('react/addons')
18 | Row = require('react-bootstrap/Row')
19 | { compose, map, toPairs, sortBy, head } = require('ramda')
20 |
21 | api = require('../services/api.coffee')
22 | jarLoaded = require('../events/jar-loaded.coffee')
23 | Jar = require('./Jar.cjsx')
24 | JarLoad = require('./JarLoad.cjsx')
25 |
26 |
27 | module.exports = React.createClass
28 | componentWillMount: ->
29 | api.jars().then (result) => @setState(jars: result)
30 | jarLoaded.add @uploaded
31 |
32 | componentWillUnmount: ->
33 | jarLoaded.remove @uploaded
34 |
35 | uploaded: ->
36 | api.jars().then (result) => @setState(jars: result, success: true)
37 |
38 | getInitialState: ->
39 | jars: {}
40 | success: false
41 |
42 | render: ->
43 | jarList = compose(
44 | map((jar) -> )
45 | sortBy(head)
46 | toPairs
47 | )(@state.jars)
48 |
49 |
50 |
51 |
Uploaded applications
52 |
53 |
54 |
55 |
Name
56 |
Uploaded at
57 |
58 |
59 | { jarList }
60 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/scripts/components/Job.cjsx:
--------------------------------------------------------------------------------
1 | # @cjsx React.DOM
2 |
3 | # Copyright 2014 UniCredit S.p.A.
4 |
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 |
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | React = require('react/addons')
18 |
19 | time = require('../services/time.coffee')
20 | clickJob = require('../events/click-job.coffee')
21 |
22 |
23 | module.exports = React.createClass
24 | click: ->
25 | clickJob.dispatch @props.job.jobId
26 |
27 | render: ->
28 | job = @props.job
29 | label = React.addons.classSet
30 | "label": true
31 | "clickable": true
32 | "label-default": job.status == "RUNNING"
33 | "label-success": job.status == "FINISHED"
34 | "label-danger": job.status == "ERROR"
35 |
36 |
37 |
38 |
{ job.classPath }
39 |
{ job.context }
40 |
{ time.formatSecsDuration(job.duration) }
41 |
{ time.format(job.startTime) }
42 |
--------------------------------------------------------------------------------
/scripts/components/JobResult.cjsx:
--------------------------------------------------------------------------------
1 | # @cjsx React.DOM
2 |
3 | # Copyright 2014 UniCredit S.p.A.
4 |
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 |
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | React = require('react/addons')
18 | Router = require('react-router')
19 | Row = require('react-bootstrap/Row')
20 | Jumbotron = require('react-bootstrap/Jumbotron')
21 |
22 | Config = require('./Config.cjsx')
23 | api = require('../services/api.coffee')
24 | prettyPrint = require('../services/pretty-print.coffee')
25 |
26 |
27 | module.exports = React.createClass
28 | mixins: [ Router.State ]
29 |
30 | componentWillMount: ->
31 | api.jobResult(@getParams().id).then (result) => @setState(result)
32 |
33 | getInitialState: ->
34 | status: null
35 | result: null
36 |
37 | render: ->
38 | if @state.status == null then return null
39 |
40 | labelClass = React.addons.classSet
41 | "label": true
42 | "label-default": @state.status == "RUNNING"
43 | "label-success": @state.status == "OK"
44 | "label-danger": @state.status == "ERROR"
45 |
46 |
47 |
Job { @props.id }
48 |
49 |
50 |
51 |
52 |
Configuration
53 |
54 |
--------------------------------------------------------------------------------
/scripts/components/JobSubmit.cjsx:
--------------------------------------------------------------------------------
1 | # @cjsx React.DOM
2 |
3 | # Copyright 2014 UniCredit S.p.A.
4 |
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 |
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | React = require('react/addons')
18 | Router = require('react-router')
19 | Row = require('react-bootstrap/Row')
20 | Col = require('react-bootstrap/Col')
21 | Alert = require('react-bootstrap/Alert')
22 | Input = require('react-bootstrap/Input')
23 | Select = require('react-select')
24 |
25 | api = require('../services/api.coffee')
26 |
27 | makeOption = (param) ->
28 | value: param
29 | label: param
30 |
31 | module.exports = React.createClass
32 | mixins: [React.addons.LinkedStateMixin, Router.Navigation]
33 |
34 | componentWillMount: ->
35 | api.contexts().then (result) =>
36 | @setState(contexts: result.map(makeOption))
37 | api.jars().then (result) => @setState(applications: Object.keys(result).map(makeOption))
38 |
39 | getInitialState: ->
40 | application: null
41 | context: null
42 | config: ''
43 | classPath: null
44 | error: null
45 | success: null
46 | applications: []
47 | contexts: []
48 |
49 | changeApplication: (app) -> @setState(application: app)
50 |
51 | changeContext: (context) -> @setState(context: context)
52 |
53 | backtoJobs: ->
54 | @transitionTo('jobs')
55 |
56 | submit: ->
57 | if not @state.classPath
58 | @setState(error: 'Missing classPath')
59 | return
60 | if not @state.application
61 | @setState(error: 'Missing application')
62 | return
63 | api.jobSubmit(@state.config, @state.application, @state.classPath, @state.context).then @handleResponse
64 |
65 | handleResponse: (response) ->
66 | if response.status.code == 202
67 | id = response.entity.result.jobId
68 | @setState(error: null, success: "Job successfully submitted with id #{ id }")
69 | setTimeout @backtoJobs, 3000
70 | else
71 | @setState(error: response.entity.result, success: null)
72 |
73 | render: ->
74 | error = if @state.error then { @state.error }
75 | success = if @state.success then { @state.success }
76 |
77 |
--------------------------------------------------------------------------------
/scripts/components/Jobs.cjsx:
--------------------------------------------------------------------------------
1 | # @cjsx React.DOM
2 |
3 | # Copyright 2014 UniCredit S.p.A.
4 |
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 |
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | React = require('react/addons')
18 | Row = require('react-bootstrap/Row')
19 | ramda = require('ramda')
20 |
21 | api = require('../services/api.coffee')
22 | Job = require('./Job.cjsx')
23 |
24 |
25 | module.exports = React.createClass
26 | componentWillMount: ->
27 | api.jobs().then (result) => @setState(jobs: result)
28 |
29 | getInitialState: ->
30 | jobs: []
31 |
32 | render: ->
33 | jobList = ramda.reverse(@state.jobs).map (job) ->
34 |
35 |
36 |
Latest jobs
37 |
38 |
39 |
40 |
Id
41 |
Job Name
42 |
Context
43 |
Duration
44 |
Started at
45 |
46 |
47 | { jobList }
48 |
49 |
--------------------------------------------------------------------------------
/scripts/components/Main.cjsx:
--------------------------------------------------------------------------------
1 | # @cjsx React.DOM
2 |
3 | # Copyright 2014 UniCredit S.p.A.
4 |
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 |
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | React = require('react/addons')
18 | { Link, RouteHandler, Navigation } = require('react-router')
19 | Nav = require('react-bootstrap/Nav')
20 | NavItem = require('react-bootstrap/NavItem')
21 |
22 | clickJob = require('../events/click-job.coffee')
23 |
24 |
25 | module.exports = React.createClass
26 | mixins: [Navigation]
27 |
28 | componentWillMount: ->
29 | clickJob.add (id) =>
30 | @transitionTo('job', id: id)
31 |
32 | render: ->
33 |
34 |
48 |
49 |
--------------------------------------------------------------------------------
/scripts/events/click-job.coffee:
--------------------------------------------------------------------------------
1 | # Copyright 2014 UniCredit S.p.A.
2 |
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 |
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | signals = require('signals')
16 |
17 | module.exports = new signals.Signal()
--------------------------------------------------------------------------------
/scripts/events/context-loaded.coffee:
--------------------------------------------------------------------------------
1 | # Copyright 2014 UniCredit S.p.A.
2 |
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 |
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | signals = require('signals')
16 |
17 | module.exports = new signals.Signal()
--------------------------------------------------------------------------------
/scripts/events/context-removed.coffee:
--------------------------------------------------------------------------------
1 | # Copyright 2014 UniCredit S.p.A.
2 |
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 |
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | signals = require('signals')
16 |
17 | module.exports = new signals.Signal()
--------------------------------------------------------------------------------
/scripts/events/jar-loaded.coffee:
--------------------------------------------------------------------------------
1 | # Copyright 2014 UniCredit S.p.A.
2 |
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 |
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | signals = require('signals')
16 |
17 | module.exports = new signals.Signal()
--------------------------------------------------------------------------------
/scripts/services/api.coffee:
--------------------------------------------------------------------------------
1 | # Copyright 2014 UniCredit S.p.A.
2 |
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 |
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | rest = require('rest')
16 | mime = require('rest/interceptor/mime')
17 | errorCode = require('rest/interceptor/errorCode')
18 | interceptor = require('rest/interceptor')
19 | binarySend = require('./binary-send.coffee')
20 |
21 | identity = (x) -> x
22 |
23 | # needed because the server response is not valid JSON
24 | # but still uses the application/json content type
25 | fixJson = interceptor
26 | init: identity
27 | request: identity
28 | response: identity
29 | success: identity
30 | error: (resp, config, meta) ->
31 | if resp.status.code == 200 then { entity: resp.entity, status: resp.status }
32 |
33 | client = rest.wrap(mime).wrap(fixJson).wrap(errorCode, code: 500)
34 | baseUrl = ''
35 |
36 | module.exports =
37 | jobs: ->
38 | client(path: "#{ baseUrl }/jobs").then (response) -> response.entity
39 |
40 | jobResult: (id) ->
41 | client(path: "#{ baseUrl }/jobs/#{ id }").then (response) -> response.entity
42 |
43 | jobConfig: (id) ->
44 | client(path: "#{ baseUrl }/jobs/#{ id }/config").then (response) -> response.entity
45 |
46 | jobSubmit: (config, appName, classPath, context) ->
47 | params =
48 | appName: appName
49 | classPath: classPath
50 | if context then params.context = context
51 | client(path: "#{ baseUrl }/jobs", entity: config, params: params)
52 |
53 | jars: ->
54 | client(path: "#{ baseUrl }/jars").then (response) -> response.entity
55 |
56 | jarLoad: (appName, jar, type) ->
57 | binarySend("#{ baseUrl }/jars/#{ appName }", jar, type)
58 |
59 | contexts: ->
60 | client(path: "#{ baseUrl }/contexts").then (response) -> response.entity
61 |
62 | createContext: (name, cpu, memory, unit) ->
63 | unitShort = unit[0].toUpperCase()
64 | params = {}
65 | if cpu then params['num-cpu-cores'] = cpu
66 | if memory then params['memory-per-node'] = "#{ memory }#{ unitShort }"
67 | client(path: "#{ baseUrl }/contexts/#{ name }", method: 'POST', params: params)
68 |
69 | deleteContext: (name) ->
70 | client(path: "#{ baseUrl }/contexts/#{ name }", method: 'DELETE')
71 |
--------------------------------------------------------------------------------
/scripts/services/binary-send.coffee:
--------------------------------------------------------------------------------
1 | When = require('when')
2 |
3 | byteValue = (x) -> x.charCodeAt(0) & 0xff
4 |
5 | sendAsBinaryDefault = (data) ->
6 | ords = Array.prototype.map.call(data, byteValue)
7 | ui8a = new Uint8Array(ords)
8 | this.send(ui8a.buffer)
9 |
10 | XMLHttpRequest.prototype.sendAsBinary ?= sendAsBinaryDefault
11 |
12 |
13 | module.exports = (url, data, type) ->
14 | deferred = When.defer()
15 | xhr = new XMLHttpRequest()
16 | xhr.open('POST', url)
17 | xhr.overrideMimeType(type)
18 | xhr.setRequestHeader("Content-Type", type)
19 | xhr.onloadend = ->
20 | entity = try
21 | JSON.parse(xhr.responseText)
22 | catch e
23 | xhr.responseText
24 |
25 | deferred.resolve
26 | status:
27 | code: xhr.status
28 | text: xhr.statusText
29 | entity: entity
30 | xhr.sendAsBinary(data)
31 | deferred.promise
--------------------------------------------------------------------------------
/scripts/services/pretty-print.coffee:
--------------------------------------------------------------------------------
1 | # Copyright 2014 UniCredit S.p.A.
2 |
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 |
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | # from http://jsfiddle.net/unLSJ/
16 |
17 | replacer = (match, pIndent, pKey, pVal, pEnd) ->
18 | key = ''
19 | val = ''
20 | str = ''
21 | r = pIndent || ''
22 | if (pKey)
23 | r = r + key + pKey.replace(/[": ]/g, '') + ': '
24 | if (pVal)
25 | r = r + (if pVal[0] == '"' then str else val) + pVal + ''
26 | r + (pEnd || '')
27 |
28 | jsonLine = /^( *)("[\w]+": )?("[^"]*"|[\w.+-]*)?([,[{])?$/mg
29 |
30 | module.exports =
31 | json: (obj) ->
32 | JSON.stringify(obj, null, 3)
33 | .replace(/&/g, '&')
34 | .replace(/\\"/g, '"')
35 | .replace(//g, '>')
37 | .replace(jsonLine, replacer)
--------------------------------------------------------------------------------
/scripts/services/time.coffee:
--------------------------------------------------------------------------------
1 | # Copyright 2014 UniCredit S.p.A.
2 |
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 |
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | moment = require('moment')
16 |
17 | secondsRegex = /(\d+\.\d*) secs/
18 |
19 | module.exports =
20 | formatSecsDuration: (secs) ->
21 | try
22 | duration = moment.duration(parseFloat(secondsRegex.exec(secs)[1]), 'seconds')
23 | minutes = Math.floor(duration.asMinutes())
24 | if minutes
25 | "#{ minutes } m #{ duration.seconds() } s"
26 | else
27 | "#{ duration.asSeconds().toFixed(1) } s"
28 | catch e
29 | secs
30 |
31 | format: (date) ->
32 | moment(date).format("D MMM H:mm:ss")
--------------------------------------------------------------------------------
/styles/_colors.sass:
--------------------------------------------------------------------------------
1 | // Copyright 2014 UniCredit S.p.A.
2 |
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 |
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | $primary: #428BCA
16 | $background: #EEEEEE
17 | $text: #333333
--------------------------------------------------------------------------------
/styles/main.sass:
--------------------------------------------------------------------------------
1 | // Copyright 2014 UniCredit S.p.A.
2 |
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 |
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | @import _colors
16 |
17 | .clickable
18 | cursor: pointer
19 |
20 | nav
21 | margin-bottom: 20px
22 |
23 | .active
24 | background-color: $background
25 |
26 | pre
27 | background-color: ghostwhite
28 | border: 1px solid silver
29 | padding: 10px 20px
30 | margin: 20px
31 |
32 | .json-key
33 | color: brown
34 |
35 | .json-value
36 | color: navy
37 |
38 | .json-string
39 | color: olive
40 |
41 | .jar-form .alert, .context-form .alert
42 | margin: 20px 0
43 |
44 | .Select
45 | margin-top: -2px
46 |
47 | textarea
48 | resize: vertical
49 |
50 | .modal-backdrop
51 | min-height: 100%
--------------------------------------------------------------------------------