knartform 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ module Knartform
2
+ end
3
+
4
+ require_relative 'knartform/action_group'
5
+ require_relative 'knartform/knart'
@@ -0,0 +1,17 @@
1
+ module Knartform
2
+ class ActionGroup
3
+ attr_accessor :knart
4
+ attr_accessor :level
5
+ attr_accessor :document
6
+ attr_accessor :node
7
+
8
+ def initialize(level = 0)
9
+ self.level = level
10
+ end
11
+
12
+ def to_html
13
+ path = File.expand_path('../../views/action_group.slim', __FILE__)
14
+ html = Slim::Template.new(path, pretty: true, disable_escape: true).render(self)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,71 @@
1
+ require 'nokogiri'
2
+ require 'slim'
3
+
4
+ require_relative 'action_group'
5
+
6
+ module Knartform
7
+ class Knart
8
+ attr_accessor :document
9
+ attr_accessor :type
10
+ HTML_OPTIONS = {}.freeze
11
+
12
+ def initialize(file)
13
+ load(file)
14
+ end
15
+
16
+ def load(file)
17
+ self.document = nil
18
+ self.type = nil
19
+ begin
20
+ puts "Loading #{file.path}..."
21
+ self.document = Nokogiri::XML(file) { |config| config.options = Nokogiri::XML::ParseOptions::STRICT }
22
+ self.type = document.xpath('//knart:knowledgeDocument/knart:metadata/knart:artifactType', knart: 'urn:hl7-org:knowledgeartifact:r1').first['value']
23
+ puts "Detected 'artifactType' of '#{type}'."
24
+ rescue Nokogiri::XML::SyntaxError => e
25
+ puts "Issue in KNART document: #{e}"
26
+ end
27
+ end
28
+
29
+ def loaded?
30
+ !document.nil?
31
+ end
32
+
33
+ def to_html(options = {})
34
+ opts = HTML_OPTIONS.merge(options)
35
+ html = nil
36
+ case type
37
+ when 'Documentation Template'
38
+ path = File.expand_path('../../views/documentation_template.slim', __FILE__)
39
+ html = Slim::Template.new(path, pretty: true, disable_escape: true).render(self)
40
+ else
41
+ path = File.expand_path('../../views/unsupported.slim', __FILE__)
42
+ html = Slim::Template.new(path, pretty: true).render(self)
43
+ end
44
+ html
45
+ end
46
+
47
+ def first_attribute(nodes, name)
48
+ nodes.empty? ? '' : nodes.first[name]
49
+ end
50
+
51
+ def dummy_edit_and_delete
52
+ path = File.expand_path('../../views/dummy_edit_and_delete.slim', __FILE__)
53
+ html = Slim::Template.new(path, pretty: true).render(self)
54
+ end
55
+
56
+ def dummy_add_button
57
+ path = File.expand_path('../../views/dummy_add_button.slim', __FILE__)
58
+ html = Slim::Template.new(path, pretty: true).render(self)
59
+ end
60
+
61
+ def dummy_edit_button
62
+ path = File.expand_path('../../views/dummy_edit_button.slim', __FILE__)
63
+ html = Slim::Template.new(path, pretty: true).render(self)
64
+ end
65
+
66
+ def dummy_drag_control
67
+ path = File.expand_path('../../views/dummy_drag_control.slim', __FILE__)
68
+ html = Slim::Template.new(path, pretty: true).render(self)
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,12 @@
1
+ h4 Metadata Items Section
2
+ table.table.table-sm.table-striped
3
+ thead
4
+ tr
5
+ th(scope="col") Item
6
+ th(scope="col") Count
7
+ tbody
8
+ - result[:metadata].each do |k, count|
9
+ / tr(class="#{result[:metadata][k] > 0 ? '': 'text-warning'}")
10
+ tr(class="#{result[:metadata][k] > 0 ? '': 'text-danger'}")
11
+ td = k
12
+ td = count
@@ -0,0 +1,324 @@
1
+ doctype html
2
+ html(lang="en")
3
+ head
4
+ meta(charset="utf-8")
5
+ meta(name="viewport" content="width=device-width, initial-scale=0.5, shrink-to-fit=no")
6
+ meta(name="description" content="")
7
+ meta(name="author" content="")
8
+ //- link(rel="icon" href="../../../../favicon.ico")
9
+ title Repository Spot Check Report
10
+
11
+
12
+ / Bootstrap
13
+ script(src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous")
14
+ script(src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous")
15
+ script(src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js" integrity="sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T" crossorigin="anonymous")
16
+
17
+ // Bootstrap core CSS
18
+ link(href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" rel="stylesheet")
19
+ link(href="https://blackrockdigital.github.io/startbootstrap-clean-blog/css/clean-blog.min.css" rel="stylesheet")
20
+ / script(src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.bundle.min.js")
21
+
22
+ / DataTables support: https://datatables.net/examples/styling/bootstrap4
23
+ / link(href="//cdn.datatables.net/1.10.16/css/dataTables.bootstrap4.min.css" rel="stylesheet")
24
+ link(href="https://cdn.datatables.net/1.10.16/css/jquery.dataTables.min.css" rel="stylesheet")
25
+ / script(href="https://cdn.datatables.net/1.10.16/js/jquery.dataTables.min.js")
26
+ script(src="https://cdn.datatables.net/1.10.16/js/jquery.dataTables.min.js")
27
+
28
+
29
+
30
+ css:
31
+ .card-columns {
32
+ column-count: 2;
33
+ column-gap: 30px;
34
+ padding-left: 30px;
35
+ padding-right: 30px;
36
+ }
37
+
38
+ .card {
39
+ position: relative;
40
+ display: inline-block;
41
+ width: 100%;
42
+ }
43
+
44
+ body {
45
+ font-size: 12px;
46
+ }
47
+ javascript:
48
+ $(document).ready(function() {
49
+ $('#identifiers').DataTable();
50
+ $('#resources').DataTable();
51
+ $('#publishers').DataTable();
52
+ $('#contributors').DataTable();
53
+ $('#supportingEvidence').DataTable();
54
+ $('#eventHistory').DataTable();
55
+ $('#applicability').DataTable();
56
+ $('#validations').DataTable();
57
+ } );
58
+
59
+ body
60
+ .container-fluid
61
+ .jumbotron
62
+ h1 Generated Spot Check Report
63
+ p.lead
64
+ | Summary information extracted from KNART XML documents.
65
+ h4 Table of Contents
66
+ h5 Composites
67
+ ol
68
+ - composites.each do |file, result|
69
+ li
70
+ a(href="##{file}") = result[:title]
71
+
72
+ h5 KNARTs
73
+ ol
74
+ - knarts.each do |file, result|
75
+ li
76
+ a(href="##{file}") = result[:title]
77
+ h5
78
+ a(href="#validations") Validations
79
+ h5 Cross-Document Consistency
80
+ ol
81
+ li
82
+ a(href="#identifiers") Identifiers
83
+ li
84
+ a(href="#resources") Resources
85
+ li
86
+ a(href="#publishers") Publishers
87
+ li
88
+ a(href="#contributors") Contributors
89
+ li
90
+ a(href="#supportingEvidence") Supporting Evidence
91
+ li
92
+ a(href="#eventHistory") Event History
93
+ li
94
+ a(href="#applicability") Applicability
95
+ li
96
+ a(href="#validations") Validations
97
+
98
+
99
+ section
100
+ h1 Composites
101
+ .card-columns
102
+ - composites.each do |file, result|
103
+ .card(id="#{file}")
104
+ .card-body
105
+ h2.card-title = result[:title]
106
+ .card-subtitle = result[:artifactType]
107
+ small.text-muted = file
108
+
109
+ section
110
+ == render_partial('metadata.slim', {result: result})
111
+
112
+ section
113
+ h4
114
+ | Artifacts (
115
+ = result[:artifacts].length
116
+ | )
117
+ table.table.table-sm.table-striped
118
+ thead
119
+ tr
120
+ th Name
121
+ th Trigger
122
+ tbody
123
+ - result[:artifacts].each do |a|
124
+ tr
125
+ td
126
+ = a.dig(:name, :value)
127
+ | (
128
+ = a.dig(:artifactType, :value)
129
+ | )
130
+ br
131
+ = a.dig(:reference, :url, :address)
132
+ - if name = a.dig(:reference, :identifiers, :identifier, :identifierName)
133
+ | (
134
+ small = name
135
+ | )
136
+ = a[:knowledgeDocument] ? '(embedded)' : nil
137
+ td
138
+ = a.dig(:eventBinding, :triggers, :trigger, :onEventName)
139
+ / - a.dig(:eventBinding, :triggers)&.each do |t|
140
+ / = a.dig(:trigger, :onEventName)
141
+ section
142
+ / - svg = root + '/' + file + '.svg'
143
+ - svg = file + '.svg'
144
+ / - if File.exist?(File.dirname(__FILE__) + '/' + svg)
145
+ h4 Flow Diagram
146
+ small = svg
147
+ br
148
+ a(href="#{svg}" target="_blank")
149
+ img(src="#{svg}" alt="Composite KNART Flow Diagram")
150
+
151
+ section
152
+ h1 KNARTs
153
+ .card-columns
154
+ - knarts.each do |file, result|
155
+ .card(id="#{file}")
156
+ .card-body
157
+ h4.card-title = result[:title]
158
+ .card-subtitle = result[:artifactType]
159
+ small.text-muted = file
160
+ hr
161
+ == render_partial('metadata.slim', {result: result})
162
+
163
+ section
164
+ h1 XML Validation
165
+ hr
166
+ table#validations.table.table-sm.table-striped
167
+ thead
168
+ tr
169
+ th File
170
+ th Result
171
+ th Errors
172
+ th Run At
173
+ tbody
174
+ - manifest['groups'].each do |group|
175
+ - group['items'].select{|n| n['validation']}.each do |item|
176
+ tr
177
+ td = item['path']
178
+ / item.dig('validation', 'passed')
179
+ td
180
+ = item.dig('validation', 'display')
181
+ / | (
182
+ / = item.dig('validation', 'code')
183
+ / | )
184
+ td = item.dig('validation', 'errors')
185
+ td = item.dig('validation', 'run_at')
186
+
187
+
188
+ section
189
+ h1 KNART Consistency
190
+ hr
191
+
192
+ h2 Identifiers
193
+ table#identifiers.table.table-sm.table-striped
194
+ thead
195
+ tr
196
+ th Root
197
+ th Extension
198
+ th Name
199
+ th Version
200
+ th File
201
+ tbody
202
+ - knarts.each do |file, result|
203
+ - result[:doc].xpath('//xmlns:identifiers/xmlns:identifier').each do |c|
204
+ tr
205
+ td = c.xpath('./@root')
206
+ td = c.xpath('./@extension')
207
+ td = c.xpath('./@identifierName')
208
+ td = c.xpath('./@version')
209
+ td = file
210
+
211
+ h2 Resources
212
+ table#resources.table.table-sm.table-striped
213
+ thead
214
+ tr
215
+ th Title
216
+ th Identifiers
217
+ th Description
218
+ th File
219
+ tbody
220
+ - knarts.each do |file, result|
221
+ - result[:doc].xpath('//xmlns:relatedResources//xmlns:resource').each do |c|
222
+ tr
223
+ td = c.xpath('./xmlns:title/@value')
224
+ td
225
+ - c.xpath('.//xmlns:identifier/@extension').collect{|n|n.to_s}.each do |n|
226
+ = n
227
+ br
228
+ td = c.xpath('./xmlns:description/@value').to_s
229
+ td = file
230
+
231
+ h2 Publishers
232
+ table#publishers.table.table-sm.table-striped
233
+ thead
234
+ tr
235
+ th Type
236
+ th Name
237
+ th File
238
+ tbody
239
+ - knarts.each do |file, result|
240
+ - result[:doc].xpath('//xmlns:publishers/xmlns:publisher').each do |n|
241
+ tr
242
+ td = n.xpath('./@xsi:type')
243
+ td = n.xpath('./xmlns:name/@value')
244
+ td = file
245
+
246
+ h2 Contributors
247
+ table#contributors.table.table-sm.table-striped
248
+ thead
249
+ tr
250
+ th Given
251
+ th Family
252
+ th Title
253
+ th Affiliation
254
+ th File
255
+ tbody
256
+ - knarts.each do |file, result|
257
+ - result[:doc].xpath('//xmlns:contributions//xmlns:contributor').each do |c|
258
+ tr
259
+ td = c.xpath('./xmlns:name/dt:part[@type="GIV"]/@value')
260
+ td = c.xpath('./xmlns:name/dt:part[@type="FAM"]/@value')
261
+ td
262
+ - c.xpath('./xmlns:name/dt:part[@type="TITLE"]/@value').collect{|n|n.to_s}.each do |n|
263
+ = n
264
+ br
265
+ td = c.xpath('./xmlns:affiliation/xmlns:name/@value')
266
+ td = file
267
+
268
+ h2 Supporting Evidence
269
+ table#supportingEvidence.table.table-sm.table-striped
270
+ thead
271
+ tr
272
+ th Title
273
+ th Identifiers
274
+ th Description
275
+ th Location
276
+ th File
277
+ tbody
278
+ - knarts.each do |file, result|
279
+ - result[:doc].xpath('//xmlns:metadata/xmlns:supportingEvidence//xmlns:resource').each do |n|
280
+ tr
281
+ td = n.xpath('./xmlns:title/@value')
282
+ td
283
+ - n.xpath('.//xmlns:identifier/@extension').collect{|n|n.to_s}.each do |n|
284
+ = n
285
+ br
286
+ td = n.xpath('./xmlns:description/@value')
287
+ td = n.xpath('./xmlns:location/@value')
288
+ td = file
289
+
290
+
291
+ h2 Event History
292
+ table#eventHistory.table.table-sm.table-striped
293
+ thead
294
+ tr
295
+ th Type
296
+ th Date/Time
297
+ th File
298
+ tbody
299
+ - knarts.each do |file, result|
300
+ - result[:doc].xpath('//xmlns:eventHistory/xmlns:artifactLifeCycleEvent').each do |n|
301
+ tr
302
+ td = n.xpath('./xmlns:eventType/@value')
303
+ td = n.xpath('./xmlns:eventDateTime/@value')
304
+ td = file
305
+
306
+ h2 Applicability
307
+ table#applicability.table.table-sm.table-striped
308
+ thead
309
+ tr
310
+ th Focus
311
+ th Description
312
+ th Code
313
+ th System
314
+ th File
315
+ tbody
316
+ - knarts.each do |file, result|
317
+ - result[:doc].xpath('//xmlns:applicability/xmlns:coverage').each do |n|
318
+ tr
319
+ td = n.xpath('./xmlns:focus/@value')
320
+ td = n.xpath('./xmlns:description/@value')
321
+ td = n.xpath('./xmlns:value/@code')
322
+ td = n.xpath('./xmlns:value/@codeSystem')
323
+ td = file
324
+
@@ -0,0 +1,90 @@
1
+ .action_group
2
+ - title = node.xpath('./knart:title', knart: 'urn:hl7-org:knowledgeartifact:r1').first['value']
3
+ - case self.level
4
+ - when 0
5
+ h1.title = title
6
+ - when 1
7
+ h2.title = title
8
+ - when 2
9
+ h3.title = title
10
+ - when 3
11
+ h4.title = title
12
+ - when 4
13
+ h5.title = title
14
+ - else
15
+ p.title = title
16
+ / span.glyphicon.glyphicon-align-justify
17
+ / = knart.dummy_drag_control
18
+ - node.xpath('./knart:subElements/knart:simpleAction', knart: 'urn:hl7-org:knowledgeartifact:r1').each do |sa|
19
+ - sa.xpath('./knart:documentationConcept', knart: 'urn:hl7-org:knowledgeartifact:r1').each do |dc|
20
+ - sa.xpath('./knart:documentationConcept', knart: 'urn:hl7-org:knowledgeartifact:r1').each do |dc|
21
+ .row
22
+ .col-md-5
23
+ .form-group
24
+ label = dc.xpath('./knart:prompt', knart: 'urn:hl7-org:knowledgeartifact:r1').first['value']
25
+ - dataType = dc.xpath('./knart:responseDataType', knart: 'urn:hl7-org:knowledgeartifact:r1').first['value']
26
+ - cardinality = dc.xpath('./knart:responseCardinality', knart: 'urn:hl7-org:knowledgeartifact:r1').first['value']
27
+ - enumeration = dc.xpath('./knart:responseRange[@xsi:type="EnumerationConstraint"]', knart: 'urn:hl7-org:knowledgeartifact:r1', xsi: 'http://www.w3.org/2001/XMLSchema-instance').length > 0
28
+ - other = dc.xpath('./knart:responseRange[strictSelection="false"]', knart: 'urn:hl7-org:knowledgeartifact:r1').length > 0
29
+ / - if cardinality == "Single" && enumeration
30
+ select
31
+ - dc.xpath('./knart:responseRange/knart:item', knart: 'urn:hl7-org:knowledgeartifact:r1').each do |item|
32
+ - value = item.xpath('./knart:value', knart: 'urn:hl7-org:knowledgeartifact:r1').first
33
+ option value="#{value['value']}" #{value['value']}
34
+ - if other
35
+ option value="other" Other (Please Specify)
36
+ - if other
37
+ input type="text" class="form-control input-lg"
38
+ .col-md-7
39
+ = knart.dummy_add_button
40
+ - itemCodes = dc.xpath('./knart:itemCodes/knart:itemCode', knart: 'urn:hl7-org:knowledgeartifact:r1')
41
+ h4 Item Codes
42
+ table.table.table-condensed.table-striped
43
+ thead
44
+ tr
45
+ th Code
46
+ th System
47
+ tbody
48
+ - itemCodes.each do |itemCode|
49
+ tr
50
+ td = itemCode['code']
51
+ td = itemCode['codeSystem']
52
+
53
+ = knart.dummy_add_button
54
+ - items = dc.xpath('./knart:responseRange[@xsi:type="EnumerationConstraint"]/knart:item', knart: 'urn:hl7-org:knowledgeartifact:r1', xsi: 'http://www.w3.org/2001/XMLSchema-instance')
55
+ h4 Responses
56
+ table.table.table-condensed.table-striped
57
+ thead
58
+ tr
59
+ th Display
60
+ th Type
61
+ th Value
62
+ th Codes
63
+ th Actions
64
+ tbody
65
+ - items.each do |item|
66
+ tr
67
+ - value = item.xpath('./knart:value', knart: 'urn:hl7-org:knowledgeartifact:r1').first
68
+ td = value['value']
69
+ td = value['xsi:type']
70
+ td = value['valueType']
71
+ td
72
+ - codes = item.xpath('./knart:codes/knart:code', knart: 'urn:hl7-org:knowledgeartifact:r1')
73
+ - if codes.length > 0
74
+ ul
75
+ - codes.each do |code|
76
+ li
77
+ a href="http://www.snomedbrowser.com/Codes/Details/#{code['code']}" = code['code']
78
+ br
79
+ small #{code['codeSystemName']} (#{code['codeSystem']})
80
+ td = knart.dummy_edit_and_delete
81
+ / node..xpath('//knart:knowledgeDocument/knart:metadata/knart:applicability/knart:coverage', knart: 'urn:hl7-org:knowledgeartifact:r1').each do
82
+
83
+
84
+ / Child recursion
85
+ - node.xpath('./knart:subElements/knart:actionGroup', knart: 'urn:hl7-org:knowledgeartifact:r1').each do |ag|
86
+ - child = Knartform::ActionGroup.new(self.level + 1)
87
+ - child.knart = self.knart
88
+ - child.document = document
89
+ - child.node = ag
90
+ = child.to_html