cpee-worklist 1.0.2 → 1.0.3

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
  SHA256:
3
- metadata.gz: 6713f404c79214aa4ec557ee3cf5606d47fca1fb3d7f4f64fefb352cde21fd46
4
- data.tar.gz: 837b838cd8ae36f3ff110bae123d786ad8d35d81708184ad0bda189ec8ef4405
3
+ metadata.gz: d6229f6eaedcaa06c02c5ce94d75f7afee3477d4150d3c21810413de7686b92c
4
+ data.tar.gz: 7d61bdf4f65ce0383dd42fe1d92f6ad083cdd81184008a871b78404640364e66
5
5
  SHA512:
6
- metadata.gz: b4551fa6484b3e8b0c4344994d6ad8d09cdd53272c6f35f332640aa16a845a50a9b69c0e9d6fc835f17d09c81845ea0f1bb83ad48013bef0ff863beb756719e4
7
- data.tar.gz: '018294928c3d1279480cf7734e33563376a493c5b8cb5abf7df0ee2685c207aa421a305c7e2f56062d65364d797c661a7f4ac4d1d52cd7f151a134b50ad56631'
6
+ metadata.gz: f3808ba81ed27f153ab0aed6e2a8bc783875172ba9ba45849faa2eba77851f3d8cd9058b9c4cccf2eea7e5b0f6a9b7c2f203d0b16705382fc2d0d005b938787a
7
+ data.tar.gz: e22efb1573c63a6e5656537b889205ffdf0cdc6c27a3346005a32fc3093bc48a0510be494b694c379a10f9299d1f65b0878bce506986b4867a14ac5bb6a30bb1
@@ -1,13 +1,13 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "cpee-worklist"
3
- s.version = "1.0.2"
3
+ s.version = "1.0.3"
4
4
  s.platform = Gem::Platform::RUBY
5
5
  s.license = "LGPL-3.0-or-later"
6
6
  s.summary = "Worklist for the cloud process execution engine (cpee.org)"
7
7
 
8
8
  s.description = "see http://cpee.org"
9
9
 
10
- s.files = Dir['{server/worklist,server/worklist.conf,lib/**/*}'] + %w(LICENSE Rakefile cpee-worklist.gemspec README.md AUTHORS)
10
+ s.files = Dir['{server/worklist,server/worklist.conf,lib/**/*,ui/**/*,tools/**/*}'] + %w(LICENSE Rakefile cpee-worklist.gemspec README.md AUTHORS)
11
11
  s.require_path = 'lib'
12
12
  s.extra_rdoc_files = ['README.md']
13
13
  s.bindir = 'tools'
data/tools/cpee-worklist CHANGED
@@ -23,28 +23,65 @@ def wrap(s, width=78, indent=18)
23
23
  return lines.join "\n"
24
24
  end
25
25
 
26
+ def js_libs(cockpit)
27
+ res = Typhoeus.get('https://cpee.org/js_libs/js_libs.zip')
28
+ if res.success?
29
+ File.write(File.join(cockpit,'js_libs.zip'),res.response_body)
30
+ Zip::File.open(File.join(cockpit,'js_libs.zip')) do |zip_file|
31
+ zip_file.each do |entry|
32
+ case entry.ftype
33
+ when :directory
34
+ Dir.mkdir(File.join(cockpit,entry.name)) rescue nil
35
+ when :file
36
+ File.write(File.join(cockpit,entry.name),entry.get_input_stream.read)
37
+ when :symlink
38
+ FileUtils.ln_s(File.join('.',entry.get_input_stream.read),File.join(cockpit,entry.name), force: true)
39
+ end
40
+ end
41
+ end
42
+ true
43
+ else
44
+ puts 'Internet access required to download javascript libs from "http://cpee.org/js_libs/js_libs.zip".'
45
+ false
46
+ end
47
+ end
48
+
26
49
  ARGV.options { |opt|
27
50
  opt.summary_indent = ' ' * 2
28
51
  opt.summary_width = 15
29
- opt.banner = "Usage:\n#{opt.summary_indent}#{File.basename($0)} [DIR]\n"
52
+ opt.banner = "Usage:\n#{opt.summary_indent}#{File.basename($0)} [options] cpui DIR | new DIR\n"
30
53
  opt.on("Options:")
31
54
  opt.on("--help", "-h", "This text") { puts opt; exit }
32
55
  opt.on("")
33
- opt.on(wrap("[DIR] scaffolds a sample instantiation service. Post a testset to a model to keep going in one operation."))
56
+ opt.on(wrap("[cpui DIR] scaffolds a sample html client. New versions might require manual merging if you changed something."))
57
+ opt.on("")
58
+ opt.on(wrap("[new DIR] scaffolds a sample instantiation service. Post a testset to a model to keep going in one operation."))
34
59
  opt.parse!
35
60
  }
36
- if (ARGV.length != 1)
61
+ if (ARGV.length < 2) ||
62
+ (ARGV.length == 2 && !(%w(cpui new).include?(ARGV[0]))) ||
63
+ (ARGV.length > 2)
37
64
  puts ARGV.options
38
65
  exit
39
- else
40
- p1 = ARGV[0]
41
66
  end
67
+ command = ARGV[0]
68
+ p1 = ARGV[1]
42
69
 
43
- insta = "#{curpath}/../server/"
44
- FileUtils.mkdir(p1) rescue nil
45
- if !File.exist?(p1)
46
- FileUtils.cp_r(insta,p1)
47
- else
48
- FileUtils.cp_r(Dir.glob(File.join(insta,'*')).delete_if{|e| e =~ /\.conf/ },p1,remove_destination: true)
49
- puts 'Directory already exists, updating ...'
70
+ if command == 'new'
71
+ insta = "#{curpath}/../server/"
72
+ FileUtils.mkdir(p1) rescue nil
73
+ if !File.exist?(p1)
74
+ FileUtils.cp_r(insta,p1)
75
+ else
76
+ FileUtils.cp_r(Dir.glob(File.join(insta,'*')).delete_if{|e| e =~ /\.conf/ },p1,remove_destination: true)
77
+ puts 'Directory already exists, updating ...'
78
+ end
79
+ elsif command == 'cpui'
80
+ if !File.exist?(p1)
81
+ FileUtils.cp_r(ui,p1)
82
+ else
83
+ FileUtils.cp_r(Dir.glob(File.join(ui,'*')),p1,remove_destination: true)
84
+ puts "Directory already exists, updating ..."
85
+ end
86
+ js_libs(p1)
50
87
  end
data/ui/css/ui.css ADDED
@@ -0,0 +1,167 @@
1
+ body {
2
+ -webkit-user-select: none;
3
+ -moz-user-select: -moz-none;
4
+ -ms-user-select: none;
5
+ user-select: none;
6
+ font-family: sans-serif;
7
+ font-size: 1em;
8
+ }
9
+
10
+ button {
11
+ padding: .5em 2em .55em;
12
+ border: 1px solid ButtonShadow;
13
+ border-radius: 0.2em;
14
+ padding: 0px;
15
+ margin: 0;
16
+ font-family: sans-serif;
17
+ font-size: 0.9em;
18
+ background: ButtonFace;
19
+ background: -webkit-gradient(linear, left top, left bottom, from(ButtonHighlight), to(ButtonFace));
20
+ background: -moz-linear-gradient(top, ButtonHighlight, ButtonFace);
21
+ }
22
+ input { font-family: sans-serif; font-size: 1em; }
23
+
24
+
25
+ #areaorganisation { height: 4em; }
26
+ #areaorganisation input {
27
+ width: 100%;
28
+ box-sizing: border-box;
29
+ -moz-box-sizing: border-box;
30
+ -webkit-box-sizing: border-box;
31
+ }
32
+ #areaorganisation td:nth-child(1) { width: 7em; padding-right: 1em; }
33
+ #areaorganisation td:nth-child(3) { width: 16em; padding-left: 1em; }
34
+
35
+
36
+ #areaconfigure { height: 4em; }
37
+ #areaconfigure table { width: 100%; }
38
+ #areaconfigure td:nth-child(1) { width: 7em; padding-right: 1em; }
39
+ #areaconfigure td:nth-child(3) { width: 100%; padding-left: 1em; }
40
+ #areaconfigure input {
41
+ width: 100%;
42
+ box-sizing: border-box;
43
+ -moz-box-sizing: border-box;
44
+ -webkit-box-sizing: border-box;
45
+ }
46
+ #areaconfigure button[name=base] { width: 100%; }
47
+ #areaconfigure button[name=instance] { width: 100%; }
48
+
49
+ #arealogin { height: 4em; }
50
+ #arealogin td:nth-child(1) { width: 7em; padding-right: 1em; }
51
+ #arealogin td:nth-child(2) { width: 20em; }
52
+ #arealogin td:nth-child(3) { width: 10em; padding-left: 1em; }
53
+ #arealogin form { border: 0 none; }
54
+ #arealogin input {
55
+ width: 100%;
56
+ box-sizing: border-box;
57
+ -moz-box-sizing: border-box;
58
+ -webkit-box-sizing: border-box;
59
+ }
60
+ #arealogin button[name=getListBt] { width: 100%; }
61
+
62
+ div.tabbed table.tabbar td.tabbehind input {
63
+ border: 0 none;
64
+ text-align: right;
65
+ width: 100%;
66
+ }
67
+
68
+ div.tabbed table.tabbar td.tabbehind button {
69
+ margin-left: 0.5em;
70
+ }
71
+
72
+ button.highlight { background-color: #cc0000; }
73
+
74
+ #parameters .tabbelow { height: 9em; min-height: 1.7em; }
75
+
76
+ #areatasks { height: 100%; overflow-x: hidden; overflow-y: scroll; }
77
+ #dat_message {
78
+ border:1em solid white;
79
+ }
80
+ #dat_tasks {
81
+ border-collapse:collapse;
82
+ border-spacing:0;
83
+ border:1em solid white;
84
+ margin:0;
85
+ padding:0;
86
+ width: 100%;
87
+ }
88
+ #dat_tasks button { border: 1pt solid buttonshadow; padding: 0.2em 0.4em; border-width: 0.2em; }
89
+ #dat_tasks td:nth-child(1) { padding: 0.4em 0; }
90
+ #dat_tasks td:nth-child(1) { min-width: 32ex; white-space: nowrap; padding: 0.4em 0; padding-left: 1em; padding-right: 1em; }
91
+ #dat_tasks td:nth-child(2) { width: 1em; padding-right: 1em; }
92
+ #dat_tasks td:nth-child(3) { white-space: nowrap; padding-right: 1em; }
93
+ #dat_tasks td:nth-child(4) { width: 100%}
94
+ #dat_tasks tr:nth-child(odd) { background-color: ButtonFace; color: ButtonText; }
95
+ #dat_tasks tr:nth-child(odd) input { background-color: ButtonFace; }
96
+
97
+ span.active {
98
+ font-weight: bold;
99
+ color: #cc0000;
100
+ }
101
+ span.passive {
102
+ font-weight: bold;
103
+ color: #3465a4;
104
+ }
105
+ span.vote {
106
+ font-weight: bold;
107
+ color: #73d216;
108
+ }
109
+
110
+ .ui-resizable-handle {
111
+ z-index: 99999;
112
+ color: ButtonShadow;
113
+ position: absolute;
114
+ white-space:nowrap;
115
+ }
116
+ .ui-resizable-w {
117
+ cursor: w-resize;
118
+ -webkit-transform: rotate(90deg);
119
+ -webkit-transform-origin: 0% 100%;
120
+ -moz-transform: rotate(90deg);
121
+ -moz-transform-origin: left bottom;
122
+ margin-top: -1em;
123
+ margin-left: 0.3em;
124
+ }
125
+ .ui-resizable-s {
126
+ right:2em;
127
+ cursor: s-resize;
128
+ text-align: right;
129
+ margin-top: 1.1em;
130
+ }
131
+ ui-area > form {
132
+ border: 1em solid white;
133
+ }
134
+ #areaorganisation ul{
135
+ margin: 0;
136
+ padding: 0;
137
+ padding-left: 1em;
138
+ }
139
+
140
+ div.task {
141
+ padding: 1em;
142
+ }
143
+
144
+ #dat_tasks tr.priority_1:nth-child(even) { background-color: #dc8add30; color: ButtonText; }
145
+ #dat_tasks tr.priority_1:nth-child(even) input { background-color: #dc8add30; }
146
+ #dat_tasks tr.priority_1:nth-child(odd) { background-color: #dc8add80; color: ButtonText; }
147
+ #dat_tasks tr.priority_1:nth-child(odd) input { background-color: #dc8add80; }
148
+
149
+ #dat_tasks tr.priority_1 td:first-child::before {
150
+ content: !
151
+ }
152
+
153
+ #dat_tasks tr.priority_42:nth-child(even) { background-color: #99c1f130; color: ButtonText; }
154
+ #dat_tasks tr.priority_42:nth-child(even) input { background-color: #99c1f130; }
155
+ #dat_tasks tr.priority_42:nth-child(odd) { background-color: #99c1f180; color: ButtonText; }
156
+ #dat_tasks tr.priority_42:nth-child(odd) input { background-color: #99c1f180; }
157
+
158
+ .pulseit{
159
+ animation: pulse linear 2s 3;
160
+ }
161
+ @keyframes pulse {
162
+ 0% { background-color: #ebdef0; }
163
+ 25% { background-color: red; }
164
+ 50% { background-color: #ebdef0; }
165
+ 75% { background-color: red; }
166
+ 100% { background-color: #ebdef0; }
167
+ }
data/ui/direct.html ADDED
@@ -0,0 +1,142 @@
1
+ <!--
2
+ This file is part of CPEE.
3
+
4
+ CPEE is free software: you can redistribute it and/or modify it under the terms
5
+ of the GNU General Public License as published by the Free Software Foundation,
6
+ either version 3 of the License, or (at your option) any later version.
7
+
8
+ CPEE is distributed in the hope that it will be useful, but WITHOUT ANY
9
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
10
+ PARTICULAR PURPOSE. See the GNU General Public License for more details.
11
+
12
+ You should have received a copy of the GNU General Public License along with
13
+ CPEE (file COPYING in the main directory). If not, see
14
+ <http://www.gnu.org/licenses/>.
15
+ -->
16
+
17
+ <!DOCTYPE html>
18
+ <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
19
+ <head>
20
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
21
+ <title>Worklist</title>
22
+
23
+ <!-- libs, do not modify. When local than load local libs. -->
24
+ <script type="text/javascript" src="/js_libs/jquery.min.js"></script>
25
+ <script type="text/javascript" src="/js_libs/jquery.browser.js"></script>
26
+ <script type="text/javascript" src="/js_libs/jquery.svg.min.js"></script>
27
+ <script type="text/javascript" src="/js_libs/jquery.svgdom.min.js"></script>
28
+ <script type="text/javascript" src="/js_libs/vkbeautify.js"></script>
29
+ <script type="text/javascript" src="/js_libs/util.js"></script>
30
+ <script type="text/javascript" src="/js_libs/printf.js"></script>
31
+ <script type="text/javascript" src="/js_libs/strftime.min.js"></script>
32
+ <script type="text/javascript" src="/js_libs/parsequery.js"></script>
33
+ <script type="text/javascript" src="/js_libs/underscore.min.js"></script>
34
+ <script type="text/javascript" src="/js_libs/jquery.caret.min.js"></script>
35
+ <script type="text/javascript" src="/js_libs/jquery.cookie.js"></script>
36
+
37
+ <script type="text/javascript" src="/js_libs/relaxngui.js"></script>
38
+
39
+ <script type="text/javascript" src="/js_libs/uidash.js"></script>
40
+ <link rel="stylesheet" href="/js_libs/uidash.css" type="text/css"/>
41
+
42
+ <link rel="stylesheet" href="/js_libs/relaxngui.css" type="text/css"/>
43
+
44
+ <!-- custom stuff, play arround -->
45
+ <link rel="stylesheet" href="css/ui.css" type="text/css"/>
46
+ <link rel="stylesheet" href="/global_ui/uicpee.css" type="text/css"/>
47
+
48
+ <!-- Flos Stuff -->
49
+ <script type="text/javascript" src="js/worklist.js"></script>
50
+ </head>
51
+ <body data-defaultport="9398" is='x-ui-'>
52
+ <!-- The following are templates that get used during ui generation, change them carefully -->
53
+ <template id="dat_template_tasks_single">
54
+ <tr class="task"> <!--{{{-->
55
+ <td class='name'></td>
56
+ <td class='sep'>⇒</td>
57
+ <td class='deadline'><em>No deadline.</em></td>
58
+ <td class='buttons'>
59
+ <button class='task_take' value=''>Take</button>
60
+ <button class='task_giveback' value=''>Give Back</button>
61
+ <button class='task_do' value=''>Do it!</button>
62
+ </td>
63
+ </tr>
64
+ </template> <!--}}}-->
65
+ <template id="dat_template_tasks_multi"> <!--{{{-->
66
+ <tr class="task">
67
+ <td class='name'></td>
68
+ <td class='sep'>⇒</td>
69
+ <td class='deadline'><em>No Deadline.</em></td>
70
+ <td class='buttons'>
71
+ <button class='task_take' value='' style="visibility: hidden">Take</button>
72
+ <button class='task_giveback' value='' style="visibility: hidden">Give Back</button>
73
+ <button class='task_do' value=''>Do it!</button>
74
+ </td>
75
+ </tr>
76
+ </template> <!--}}}-->
77
+ <template id="dat_template_orgmodels"> <!--{{{-->
78
+ <li class="orgmodel"><a class='link' href=""></a> ⇒ [<a class='model' href="">View Model</a>]</li>
79
+ </template> <!--}}}-->
80
+
81
+ <ui-tabbed class="hidden" id="worklist">
82
+ <ui-tabbar>
83
+ <ui-tab class="switch" ></ui-tab>
84
+ <ui-tab class="" data-tab="login" id="tablogin" >Login</ui-tab>
85
+ <ui-tab class="inactive hidden" data-tab="organisation" id="taborganisation">Organisation</ui-tab>
86
+ <ui-tab class="inactive " data-tab="configure" id="tabconfigure" >Configure</ui-tab>
87
+ <ui-behind><input name="current-instance" type="text" value="" readonly='readonly' style='display:none'/><a id='current-instance'></a></ui-behind>
88
+ <ui-last><a class="logo" href=".."></a></ui-last>
89
+ </ui-tabbar>
90
+ <ui-content>
91
+ <ui-area data-belongs-to-tab="login" id="arealogin"> <!--{ {{-->
92
+ <form>
93
+ <table class='layout'>
94
+ <tr>
95
+ <td>User Name:</td>
96
+ <td><input name="user-name" type="text" value=""/></td>
97
+ </tr>
98
+ <tr>
99
+ <td>Password:</td>
100
+ <td><input name="pass" disabled="disabled" type="text" value="Not necessary in this demo."/></td>
101
+ <td><input name="getListBt" type="submit" value="get Worklist"/></td>
102
+ </tr>
103
+ </table>
104
+ </form>
105
+ </ui-area> <!--}}}-->
106
+
107
+ <ui-area data-belongs-to-tab="organisation" id="areaorganisation" class="inactive"> <!--{{{-->
108
+ <ul id="orgmodels">
109
+ </ul>
110
+ </ui-area> <!--}}}-->
111
+
112
+ <ui-area data-belongs-to-tab="configure" id="areaconfigure" class="inactive"> <!--{{{-->
113
+ <table class='layout'>
114
+ <tr>
115
+ <td>Base URL:</td>
116
+ <td><input name="base-url" type="text" value=""/></td>
117
+ </tr>
118
+ <tr>
119
+ <td>User URL:</td>
120
+ <td><input name="user-url" type="text" value="" readonly='readonly'/></td>
121
+ </tr>
122
+ </table>
123
+ </ui-area> <!--}}}-->
124
+ </ui-content>
125
+ </ui-tabbed>
126
+
127
+ <ui-rest class="hidden" id='main'>
128
+ <ui-tabbar>
129
+ <ui-before ></ui-before>
130
+ <ui-tab class="default" data-tab="task" id="tabtask">Tasks</ui-tab>
131
+ <ui-behind ></ui-behind>
132
+ </ui-tabbar>
133
+ <ui-content>
134
+ <ui-area data-belongs-to-tab="task" id="areatask"> <!--{{{-->
135
+ <div id="dat_message" style="display: none;">Currently no tasks available.</div>
136
+ <table id="dat_tasks" class="layout"></table>
137
+ </ui-area> <!--}}}-->
138
+ </ui-content>
139
+ </ui-rest>
140
+
141
+ </body>
142
+ </html>
data/ui/index.html ADDED
@@ -0,0 +1,143 @@
1
+ <!--
2
+ This file is part of CPEE.
3
+
4
+ CPEE is free software: you can redistribute it and/or modify it under the terms
5
+ of the GNU General Public License as published by the Free Software Foundation,
6
+ either version 3 of the License, or (at your option) any later version.
7
+
8
+ CPEE is distributed in the hope that it will be useful, but WITHOUT ANY
9
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
10
+ PARTICULAR PURPOSE. See the GNU General Public License for more details.
11
+
12
+ You should have received a copy of the GNU General Public License along with
13
+ CPEE (file COPYING in the main directory). If not, see
14
+ <http://www.gnu.org/licenses/>.
15
+ -->
16
+
17
+ <!DOCTYPE html>
18
+ <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
19
+ <head>
20
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
21
+ <title>Worklist</title>
22
+
23
+ <!-- libs, do not modify. When local than load local libs. -->
24
+ <script type="text/javascript" src="/js_libs/jquery.min.js"></script>
25
+ <script type="text/javascript" src="/js_libs/jquery.browser.js"></script>
26
+ <script type="text/javascript" src="/js_libs/jquery.svg.min.js"></script>
27
+ <script type="text/javascript" src="/js_libs/jquery.svgdom.min.js"></script>
28
+ <script type="text/javascript" src="/js_libs/vkbeautify.js"></script>
29
+ <script type="text/javascript" src="/js_libs/util.js"></script>
30
+ <script type="text/javascript" src="/js_libs/printf.js"></script>
31
+ <script type="text/javascript" src="/js_libs/strftime.min.js"></script>
32
+ <script type="text/javascript" src="/js_libs/parsequery.js"></script>
33
+ <script type="text/javascript" src="/js_libs/underscore.min.js"></script>
34
+ <script type="text/javascript" src="/js_libs/jquery.caret.min.js"></script>
35
+ <script type="text/javascript" src="/js_libs/jquery.cookie.js"></script>
36
+ <script type="text/javascript" src="/js_libs/marked.min.js"></script>
37
+
38
+ <script type="text/javascript" src="/js_libs/relaxngui.js"></script>
39
+
40
+ <script type="text/javascript" src="/js_libs/uidash.js"></script>
41
+ <link rel="stylesheet" href="/js_libs/uidash.css" type="text/css"/>
42
+
43
+ <link rel="stylesheet" href="/js_libs/relaxngui.css" type="text/css"/>
44
+
45
+ <!-- custom stuff, play arround -->
46
+ <link rel="stylesheet" href="css/ui.css" type="text/css"/>
47
+ <link rel="stylesheet" href="/global_ui/uicpee.css" type="text/css"/>
48
+
49
+ <!-- Flos Stuff -->
50
+ <script type="text/javascript" src="js/worklist.js"></script>
51
+ </head>
52
+ <body data-defaultport="9398" is='x-ui-'>
53
+ <!-- The following are templates that get used during ui generation, change them carefully -->
54
+ <template id="dat_template_tasks_single">
55
+ <tr class="task"> <!--{{{-->
56
+ <td class='name'></td>
57
+ <td class='sep'>⇒</td>
58
+ <td class='deadline'><em>No deadline.</em></td>
59
+ <td class='buttons'>
60
+ <button class='task_take' value=''>Take</button>
61
+ <button class='task_giveback' value=''>Give Back</button>
62
+ <button class='task_do' value=''>Do it!</button>
63
+ </td>
64
+ </tr>
65
+ </template> <!--}}}-->
66
+ <template id="dat_template_tasks_multi"> <!--{{{-->
67
+ <tr class="task">
68
+ <td class='name'></td>
69
+ <td class='sep'>⇒</td>
70
+ <td class='deadline'><em>No Deadline.</em></td>
71
+ <td class='buttons'>
72
+ <button class='task_take' value='' style="visibility: hidden">Take</button>
73
+ <button class='task_giveback' value='' style="visibility: hidden">Give Back</button>
74
+ <button class='task_do' value=''>Do it!</button>
75
+ </td>
76
+ </tr>
77
+ </template> <!--}}}-->
78
+ <template id="dat_template_orgmodels"> <!--{{{-->
79
+ <li class="orgmodel"><a class='link' href=""></a> ⇒ [<a class='model' href="">View Model</a>]</li>
80
+ </template> <!--}}}-->
81
+
82
+ <ui-tabbed id="worklist">
83
+ <ui-tabbar>
84
+ <ui-tab class="switch" ></ui-tab>
85
+ <ui-tab class="" data-tab="login" id="tablogin" >Login</ui-tab>
86
+ <ui-tab class="inactive hidden" data-tab="organisation" id="taborganisation">Organisation</ui-tab>
87
+ <ui-tab class="inactive " data-tab="configure" id="tabconfigure" >Configure</ui-tab>
88
+ <ui-behind><input name="current-instance" type="text" value="" readonly='readonly' style='display:none'/><a id='current-instance'></a></ui-behind>
89
+ <ui-last><a class="logo" href=".."></a></ui-last>
90
+ </ui-tabbar>
91
+ <ui-content>
92
+ <ui-area data-belongs-to-tab="login" id="arealogin"> <!--{ {{-->
93
+ <form>
94
+ <table class='layout'>
95
+ <tr>
96
+ <td>User Name:</td>
97
+ <td><input name="user-name" type="text" value=""/></td>
98
+ </tr>
99
+ <tr>
100
+ <td>Password:</td>
101
+ <td><input name="pass" disabled="disabled" type="text" value="Not necessary in this demo."/></td>
102
+ <td><input name="getListBt" type="submit" value="get Worklist"/></td>
103
+ </tr>
104
+ </table>
105
+ </form>
106
+ </ui-area> <!--}}}-->
107
+
108
+ <ui-area data-belongs-to-tab="organisation" id="areaorganisation" class="inactive"> <!--{{{-->
109
+ <ul id="orgmodels">
110
+ </ul>
111
+ </ui-area> <!--}}}-->
112
+
113
+ <ui-area data-belongs-to-tab="configure" id="areaconfigure" class="inactive"> <!--{{{-->
114
+ <table class='layout'>
115
+ <tr>
116
+ <td>Base URL:</td>
117
+ <td><input name="base-url" type="text" value=""/></td>
118
+ </tr>
119
+ <tr>
120
+ <td>User URL:</td>
121
+ <td><input name="user-url" type="text" value="" readonly='readonly'/></td>
122
+ </tr>
123
+ </table>
124
+ </ui-area> <!--}}}-->
125
+ </ui-content>
126
+ </ui-tabbed>
127
+
128
+ <ui-rest class="hidden" id='main'>
129
+ <ui-tabbar>
130
+ <ui-before ></ui-before>
131
+ <ui-tab class="default" data-tab="task" id="tabtask">Tasks</ui-tab>
132
+ <ui-behind ></ui-behind>
133
+ </ui-tabbar>
134
+ <ui-content>
135
+ <ui-area data-belongs-to-tab="task" id="areatask"> <!--{{{-->
136
+ <div id="dat_message" style="display: none;">Currently no tasks available.</div>
137
+ <table id="dat_tasks" class="layout"></table>
138
+ </ui-area> <!--}}}-->
139
+ </ui-content>
140
+ </ui-rest>
141
+
142
+ </body>
143
+ </html>
data/ui/js/worklist.js ADDED
@@ -0,0 +1,357 @@
1
+ function toggle_message(message=undefined) { //{{{
2
+ var url =$("input[name=base-url]").val()+'/'+$("input[name=user-name]").val()+'/';
3
+ if ($("#dat_tasks tr").length == 0) {
4
+ if (message != undefined) {
5
+ $("#dat_message").text(message);
6
+ $("#dat_message").show();
7
+ } else {
8
+ $.ajax({
9
+ type: "GET",
10
+ url: url,
11
+ success: function(res){
12
+ $("#dat_message").text(res);
13
+ $("#dat_message").show();
14
+ }
15
+ });
16
+ }
17
+ } else {
18
+ $("#dat_message").hide();
19
+ }
20
+ } //}}}
21
+
22
+ $(document).ready(function() {// {{{
23
+ $("input[name=base-url]").val(location.protocol + "//" + location.host + '/worklist/server');
24
+ $("#arealogin > form").submit(function(event){
25
+ get_worklist();
26
+ subscribe_worklist();
27
+ uidash_toggle_vis_tab($("#worklist .switch"));
28
+ event.preventDefault();
29
+ });
30
+ var q = $.parseQuerySimple();
31
+ if (q.user) {
32
+ $("input[name=user-name]").val(q.user);
33
+ uidash_toggle_vis_tab($("#worklist .switch"));
34
+ get_worklist();
35
+ subscribe_worklist();
36
+ }
37
+ $(document).on('click','.orgmodeltab',function(event){
38
+ var id = $(this).attr('data-tab');
39
+ uidash_empty_tab_contents(id);
40
+ // TODO Hier kommt Raphi
41
+ });
42
+ $(document).on('click','#orgmodels li a.model',function(event){
43
+ // var id = $(this).attr('href').hashCode();
44
+ // if (!uidash_add_tab("#main", "Orgmodel", id, true, 'orgmodeltab')) {
45
+ // uidash_empty_tab_contents(id);
46
+ // }
47
+ // TODO Hier kommt Raphi
48
+ event.preventDefault();
49
+ });
50
+ $(document).on('click','.task_do',function(){
51
+ var url =$("input[name=user-url]").val()+'/tasks';
52
+ var taskid = $(this).parents('tr').attr('data-id');
53
+ var taskidurl = url + '/' + taskid;
54
+ take_work(taskidurl,$('.task_take',$(this).parent()),$('.task_giveback',$(this).parent()),1);
55
+ do_work(taskid,taskidurl);
56
+ });
57
+ $(document).on('click','.task_take',function(){
58
+ var url =$("input[name=user-url]").val()+'/tasks';
59
+ var taskid = $(this).parents('tr').attr('data-id');
60
+ var taskidurl = url + '/' + taskid;
61
+ take_work(taskidurl,$('.task_take',$(this).parent()),$('.task_giveback',$(this).parent()),1);
62
+ });
63
+ $(document).on('click','.task_giveback',function(){
64
+ var url =$("input[name=user-url]").val()+'/tasks';
65
+ var taskid = $(this).parents('tr').attr('data-id');
66
+ var taskidurl = url + '/' + taskid;
67
+ take_work(taskidurl,$('.task_giveback',$(this).parent()),$('.task_take',$(this).parent()),0);
68
+ });
69
+
70
+ });// }}}
71
+
72
+ function get_worklist() {// {{{
73
+ $("input[name=user-url]").val($("input[name=base-url]").val()+'/'+$("input[name=user-name]").val());
74
+ var url =$("input[name=base-url]").val()+'/'+$("input[name=user-name]").val()+'/tasks';
75
+ // subscribe_worklist($("input[name=domain-name]").val());
76
+ // Set url (no more cookie nonsense!)
77
+ history.replaceState({}, '', '?user='+encodeURIComponent($("input[name=user-name]").val()));
78
+
79
+ $.ajax({
80
+ type: "GET",
81
+ url: url,
82
+ dataType: "xml",
83
+ success: function(res){
84
+
85
+ $('#taborganisation').removeClass("hidden");
86
+ $.ajax({
87
+ type: "GET",
88
+ url: $("input[name=base-url]").val()+'/orgmodels/',
89
+ dataType: "xml",
90
+ success: function(res){
91
+ var ctv = $("#orgmodels");
92
+ ctv.empty();
93
+ $(res).find('orgmodel').each(function(){
94
+ var uri = decodeURIComponent($(this).text());
95
+ var node = $($("#dat_template_orgmodels")[0].content.cloneNode(true));
96
+ $('.link',node).text(uri);
97
+ $('.link',node).attr('href',uri);
98
+ $('.model',node).attr('href',uri);
99
+ ctv.append(node);
100
+ });
101
+ }
102
+ });
103
+ $("#main").removeClass("hidden");
104
+ var ctv = $("#dat_tasks");
105
+ ctv.empty();
106
+ $(res).find('task').each(function(){
107
+ if ($(this).attr('all') == "true") {
108
+ var node = $($("#dat_template_tasks_multi")[0].content.cloneNode(true));
109
+ $('.deadline',node).text($(this).attr('deadline'));
110
+ } else {
111
+ var node = $($("#dat_template_tasks_single")[0].content.cloneNode(true));
112
+ }
113
+ var taskidurl = $(this).attr('id');
114
+ var tasklabel = $(this).attr('label');
115
+ node.find('tr').attr('data-id',taskidurl);
116
+ node.find('tr').attr('data-label',tasklabel);
117
+ node.find('tr').addClass('priority_' + $(this).attr('priority'));
118
+ $('.name',node).text(tasklabel);
119
+ if ($(this).attr('uid')=='*') {
120
+ $('.task_giveback',node).prop('disabled', true);
121
+ } else {
122
+ $('.task_take',node).prop('disabled', true);
123
+ }
124
+ ctv.append(node);
125
+ });
126
+ toggle_message();
127
+ },
128
+ error: function(a,b,c) {
129
+ alert("Server not running.");
130
+ }
131
+ });
132
+ }// }}}
133
+
134
+ function take_work(url,butt,butt2,give_or_take){ //{{{
135
+ var op = give_or_take == 1 ? "take" : "giveback";
136
+ $.ajax({
137
+ type: "PUT",
138
+ url: url,
139
+ data:"operation="+op ,
140
+ success: function(){
141
+ $(butt).prop('disabled','true');
142
+ $(butt2).prop('disabled','false');
143
+ },
144
+ error: function(a,b,c){
145
+ alert("Put didn't work");
146
+ }
147
+ });
148
+ } //}}}
149
+
150
+ function do_work(taskid,taskidurl) { //{{{
151
+ $.ajax({
152
+ type: "GET",
153
+ url: taskidurl,
154
+ success:function(res) {
155
+ if (!uidash_add_tab("#main", res.label, taskid, true, '')) { return; };
156
+ $.ajax({
157
+ type: "GET",
158
+ url: res.form,
159
+ dataType: 'text',
160
+ success: async (iform) => {
161
+ let end = false;
162
+ let evaltext = '';
163
+ while (!end) {
164
+ let matches = iform.match(/<worklist-form-load>(.*?)<\/worklist-form-load>/ms);
165
+ if (matches && matches.length > 0) {
166
+ evaltext += matches[1];
167
+ iform = iform.replace(matches[0],'');
168
+ } else {
169
+ let includes = iform.match(/<\/?worklist-include\s+href=(("([^"]*)")|('([^']*)'))\s*\/?\s*>/ms);
170
+ if (includes && includes.length > 0) {
171
+ await $.ajax({
172
+ type: "GET",
173
+ url: includes[3],
174
+ dataType: 'text',
175
+ success: function(inctext) {
176
+ iform = iform.replace(includes[0],inctext);
177
+ }
178
+ });
179
+ } else {
180
+ end = true;
181
+ }
182
+ }
183
+ }
184
+ {
185
+ let replaces = iform.match(/form="worklist-form"/ms);
186
+ if (replaces && replaces.length > 0) {
187
+ iform = iform.replaceAll(replaces[0],'form="form_' + taskid + '"');
188
+ }
189
+ }
190
+ {
191
+ let replaces = iform.match(/div.task.current/ms);
192
+ if (replaces && replaces.length > 0) {
193
+ iform = iform.replaceAll(replaces[0],'div.task.task_' + taskid);
194
+ }
195
+ }
196
+
197
+ let container = $("<div class='task task_" + taskid + "'><form id='form_" + taskid + "'></form></div>");
198
+ container.append(iform);
199
+
200
+ let form = $("ui-area[data-belongs-to-tab="+taskid+"]");
201
+ let data;
202
+ try { data = res.parameters; } catch (e) { data = {}; }
203
+ form.append(container);
204
+
205
+ eval(evaltext); // investigate indirect eval and strict
206
+
207
+ uidash_activate_tab($('ui-tabbar ui-tab[data-tab=' + taskid + ']'));
208
+ $("#form_"+taskid).on('submit',function(e){
209
+ let scount = 0;
210
+ $('select[required][form="form_' + taskid + '"]').each((_,e) => {
211
+ if ($(e).val() == null) { scount += 1; }
212
+ if (scount == 1) {
213
+ $(e).focus();
214
+ $(e).removeClass('pulseit');
215
+
216
+ setTimeout(()=>{$(e).addClass('pulseit')},100);;
217
+ }
218
+ });
219
+ if (scount > 0) {
220
+ e.preventDefault();
221
+ return false;
222
+ }
223
+ var form_data = $(this).serializeArray();
224
+ var send_data = {};
225
+ var headers = {};
226
+ if (res.collect) { headers['CPEE-UPDATE'] = 'true'; }
227
+ send_data['user'] = $("input[name=user-name]").val();
228
+ send_data['raw'] = form_data;
229
+ send_data['data'] = {};
230
+ $.map(send_data['raw'], function(n, i){
231
+ send_data['data'][n['name']] = n['value'];
232
+ });
233
+ $.ajax({
234
+ type: "PUT",
235
+ url: res.url,
236
+ headers: headers,
237
+ contentType: "application/json",
238
+ data: JSON.stringify(send_data),
239
+ success: function(something){
240
+ $.ajax({
241
+ type: "DELETE",
242
+ url: taskidurl,
243
+ success: function(del){
244
+ uidash_close_tab('ui-tab[data-tab='+taskid+'] ui-close');
245
+ get_worklist();
246
+ },
247
+ error: function(a,b,c){
248
+ console.log("Delete failed");
249
+ }
250
+ });
251
+ },
252
+ error: function(a,b,c){
253
+ $.ajax({
254
+ type: "DELETE",
255
+ url: taskidurl,
256
+ success: function(del){
257
+ uidash_close_tab('ui-tab[data-tab='+taskid+'] ui-close');
258
+ get_worklist();
259
+ },
260
+ error: function(a,b,c){
261
+ console.log("Delete failed");
262
+ }
263
+ });
264
+ // TODO
265
+ console.log("Put didnt work");
266
+ }
267
+ });
268
+ e.preventDefault();
269
+ });
270
+ },
271
+ error: function(a,b,c){
272
+ $.ajax({
273
+ type: "DELETE",
274
+ url: taskidurl,
275
+ success: function(del){
276
+ uidash_close_tab('ui-tab[data-tab='+taskid+'] ui-close');
277
+ get_worklist();
278
+ },
279
+ error: function(a,b,c){
280
+ console.log("Delete failed");
281
+ }
282
+ });
283
+ console.log("Error while getting form html");
284
+ }
285
+ });
286
+ },
287
+ error: function(a,b,c){
288
+ console.log("Error while getting url for form");
289
+ }
290
+ });
291
+ } //}}}
292
+
293
+ function subscribe_worklist(){ //{{{
294
+ var url = $("input[name=base-url]").val()+'/notifications/subscriptions/';
295
+ $.ajax({
296
+ type: "POST",
297
+ url: url,
298
+ data: "topic=user&events=status,take,giveback,finish&topic=task&events=add,delete",
299
+ success: function(ret){
300
+ subscription = ret;
301
+ es = new EventSource(url + subscription + "/sse/");
302
+ es.onopen = function() { };
303
+ es.onmessage = function(e) {
304
+ data = JSON.parse(e.data);
305
+ if (data['type'] == 'event') {
306
+ var cid = data.content.callback_id;
307
+ var tr = $('tr[data-id="'+cid+'"]');
308
+ switch(data['topic']) {
309
+ case 'user':
310
+ switch(data['name']) {
311
+ case 'finish':
312
+ if (data.content.user == $("input[name=user-name]").val()) {
313
+ tr.remove();
314
+ toggle_message();
315
+ }
316
+ break;
317
+ case 'status':
318
+ toggle_message(data.content.status);
319
+ default:
320
+ tr.remove();
321
+ get_worklist();
322
+ break;
323
+ }
324
+ break;
325
+ case 'task':
326
+ switch(data['name']) {
327
+ case 'add':
328
+ get_worklist();
329
+ break;
330
+ case 'delete':
331
+ tr.remove();
332
+ toggle_message();
333
+ break;
334
+ }
335
+ break;
336
+ }
337
+ }
338
+ };
339
+ es.onerror = function(e){ }
340
+ },
341
+ error: function(){
342
+ console.log("Not Successful subscribed");
343
+ }
344
+ });
345
+ } //}}}
346
+
347
+ String.prototype.hashCode = function() { //{{{
348
+ var hash = 0, i, chr, len;
349
+ if (this.length == 0) return hash;
350
+ for (i = 0, len = this.length; i < len; i++) {
351
+ chr = this.charCodeAt(i);
352
+ hash = ((hash << 5) - hash) + chr;
353
+ hash |= 0; // Convert to 32bit integer
354
+ }
355
+ return hash;
356
+ }; //}}}
357
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cpee-worklist
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Juergen eTM Mangler
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: tools
12
12
  cert_chain: []
13
- date: 2024-06-20 00:00:00.000000000 Z
13
+ date: 2024-07-01 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: riddl
@@ -109,6 +109,10 @@ files:
109
109
  - server/worklist
110
110
  - server/worklist.conf
111
111
  - tools/cpee-worklist
112
+ - ui/css/ui.css
113
+ - ui/direct.html
114
+ - ui/index.html
115
+ - ui/js/worklist.js
112
116
  homepage: http://cpee.org/
113
117
  licenses:
114
118
  - LGPL-3.0-or-later