cpee-worklist 1.0.1 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0d4b5845fbbb37c846fa8234c8ba28de6d7f0d193625c2686ee44d6ea81eac15
4
- data.tar.gz: 8b07e9f4aa48f5eeb5bfe4b07ec8a649400e58fbbe8525c10ac7bead3b7ca929
3
+ metadata.gz: d6229f6eaedcaa06c02c5ce94d75f7afee3477d4150d3c21810413de7686b92c
4
+ data.tar.gz: 7d61bdf4f65ce0383dd42fe1d92f6ad083cdd81184008a871b78404640364e66
5
5
  SHA512:
6
- metadata.gz: 39609cc388783cfca5c3cd3a9b05b220e96f755d44c24cb6aed6ec14a11049e0fece4e14aaa328fdd03c7e1877a592a3a16059a7b77d856e0f17d2c31ad3c2d3
7
- data.tar.gz: 53d844473c1cdd012fa99bb6f680cd7d1dd96041d0b2fd4b3e9ff70c885d9e6cb0eba9dfc1a9cddfeb7612b61c7524014a9c371e7851d9d246111b6d61345e51
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.1"
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'
@@ -271,7 +271,8 @@ module CPEE
271
271
  class TaskGiveBack < Riddl::Implementation #{{{
272
272
  def response
273
273
  index = @a[0].activities.index{ |c| c["id"] == @r.last }
274
- if index && (@a[0].activities[index]['user'] == @r[-3])
274
+
275
+ if index && (@a[0].activities[index]['user'].include?(@r[-3]))
275
276
  activity = @a[0].activities[index]
276
277
  activity['user'] = []
277
278
  callback_id = @a[0].activities[index]['id']
@@ -312,7 +313,7 @@ module CPEE
312
313
  index = @a[0].activities.index{ |c| c["id"] == @r.last }
313
314
  if index
314
315
  user = @p[0].value
315
- @a[0].activities[index]["user"] = user if CPEE::Worklist::User::ok?(@a[0].opts,@a[0].activities[index],user)
316
+ @a[0].activities[index]["user"] << user if CPEE::Worklist::User::ok?(@a[0].opts,@a[0].activities[index],user)
316
317
  callback_id = @a[0].activities[index]['id']
317
318
  info = CPEE::Worklist::User::info(@a[0].opts,@a[0].activities[index],user)
318
319
  @a[0].activities.serialize
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.1
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-12 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