qa_server 2.1.0 → 2.2.0

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.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/CHANGELOG.md +6 -0
  4. data/app/assets/stylesheets/qa_server/_fetch.scss +16 -0
  5. data/app/assets/stylesheets/qa_server/_monitor-status.scss +34 -0
  6. data/app/assets/stylesheets/qa_server/_qa_server.scss +1 -1
  7. data/app/assets/stylesheets/qa_server/_styles.scss +4 -0
  8. data/app/controllers/qa_server/fetch_controller.rb +60 -0
  9. data/app/controllers/qa_server/monitor_status_controller.rb +4 -2
  10. data/app/models/qa_server/performance_history.rb +151 -0
  11. data/app/prepends/prepended_linked_data/find_term.rb +16 -0
  12. data/app/prepends/prepended_linked_data/search_query.rb +16 -0
  13. data/app/presenters/qa_server/fetch_presenter.rb +65 -0
  14. data/app/presenters/qa_server/monitor_status_presenter.rb +114 -8
  15. data/app/presenters/qa_server/navmenu_presenter.rb +1 -0
  16. data/app/services/qa_server/authority_loader_service.rb +35 -29
  17. data/app/views/layouts/qa_server.html.erb +3 -1
  18. data/app/views/qa_server/fetch/index.html.erb +62 -0
  19. data/app/views/qa_server/monitor_status/index.html.erb +62 -2
  20. data/config/locales/qa_server.en.yml +24 -0
  21. data/config/routes.rb +1 -0
  22. data/lib/generators/qa_server/config_generator.rb +9 -0
  23. data/lib/generators/qa_server/templates/config/authorities/linked_data/DISABLED/scenarios/mesh_bioportal_ld4l_cache_validation.yml +2 -0
  24. data/lib/generators/qa_server/templates/config/authorities/linked_data/getty_aat_ld4l_cache.json +1 -1
  25. data/lib/generators/qa_server/templates/config/authorities/linked_data/getty_tgn_ld4l_cache.json +1 -1
  26. data/lib/generators/qa_server/templates/config/authorities/linked_data/getty_ulan_ld4l_cache.json +1 -1
  27. data/lib/generators/qa_server/templates/config/authorities/linked_data/locdemographics_ld4l_cache.json +110 -3
  28. data/lib/generators/qa_server/templates/config/authorities/linked_data/locgenres_ld4l_cache.json +71 -25
  29. data/lib/generators/qa_server/templates/config/authorities/linked_data/locsubjects_ld4l_cache.json +76 -12
  30. data/lib/generators/qa_server/templates/config/authorities/linked_data/nalt_ld4l_cache.json +2 -4
  31. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/loc_direct_validation.yml +3 -0
  32. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/loc_validation.yml +6 -0
  33. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/locdemographics_ld4l_cache_validation.yml +1 -0
  34. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/locgenres_ld4l_cache_validation.yml +13 -14
  35. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/locsubjects_ld4l_cache_validation.yml +1 -18
  36. data/lib/generators/qa_server/templates/config/authorities/linked_data/scenarios/oclcfast_direct_validation.yml +10 -10
  37. data/lib/generators/qa_server/templates/db/migrate/20190813045549_create_performance_history.rb.erb +12 -0
  38. data/lib/qa_server/version.rb +1 -1
  39. metadata +10 -2
@@ -29,6 +29,7 @@ module QaServer
29
29
  @leftmenu_items << { label: I18n.t("qa_server.menu.authorities"), url: authority_list_index_path }
30
30
  @leftmenu_items << { label: I18n.t("qa_server.menu.check_status"), url: check_status_index_path }
31
31
  @leftmenu_items << { label: I18n.t("qa_server.menu.monitor_status"), url: monitor_status_index_path }
32
+ @leftmenu_items << { label: I18n.t("qa_server.menu.fetch_term"), url: fetch_index_path }
32
33
 
33
34
  @rightmenu_items = []
34
35
  @rightmenu_items << { label: "LD4L Gateway", url: "http://ld4l.org/" }
@@ -2,38 +2,44 @@
2
2
  # This class loads an authority.
3
3
  module QaServer
4
4
  class AuthorityLoaderService
5
- # Load a QA authority
6
- # @param authority_name [String] name of the authority to load (e.g. "agrovoc_direct")
7
- # @param status_log [ScenarioLogger] logger to hold failure information if the authority cannot be loaded
8
- # @return [Qa::Authorities::LinkedData::GenericAuthority] the instance of the authority that can receive QA requests OR nil if fails to load
9
- def self.load(authority_name:, status_log:)
10
- begin
11
- authority = load_authority(authority_name, status_log)
12
- return nil if authority.blank?
13
- rescue Exception => e
14
- status_log.add(authority_name: authority_name,
15
- status: QaServer::ScenarioValidator::FAIL,
16
- error_message: "Unable to load authority '#{authority_name}'; cause: #{e.message}")
17
- return nil
5
+ class << self
6
+ # Load a QA authority
7
+ # @param authority_name [String] name of the authority to load (e.g. "agrovoc_direct")
8
+ # @param status_log [ScenarioLogger] logger to hold failure information if the authority cannot be loaded
9
+ # @return [Qa::Authorities::LinkedData::GenericAuthority] the instance of the authority that can receive QA requests OR nil if fails to load
10
+ def load(authority_name:, status_log: nil)
11
+ begin
12
+ authority = load_authority(authority_name, status_log)
13
+ return nil if authority.blank?
14
+ rescue Exception => e
15
+ if status_log.present?
16
+ status_log.add(authority_name: authority_name,
17
+ status: QaServer::ScenarioValidator::FAIL,
18
+ error_message: "Unable to load authority '#{authority_name}'; cause: #{e.message}")
19
+ end
20
+ return nil
21
+ end
22
+ authority
18
23
  end
19
- authority
20
- end
21
24
 
22
- def self.authority_key(authority_name)
23
- authority_name.upcase.to_sym
24
- end
25
- private_class_method :authority_key
25
+ private
26
26
 
27
- def self.load_authority(authority_name, status_log)
28
- authority = Qa::Authorities::LinkedData::GenericAuthority.new(authority_key(authority_name))
29
- if authority.blank?
30
- status_log.add(authority_name: authority_name,
31
- status: QaServer::ScenarioValidator::FAIL,
32
- error_message: "Unable to load authority '#{authority_name}'; cause: UNKNOWN")
33
- return nil
34
- end
35
- authority
27
+ def authority_key(authority_name)
28
+ authority_name.upcase.to_sym
29
+ end
30
+
31
+ def load_authority(authority_name, status_log)
32
+ authority = Qa::Authorities::LinkedData::GenericAuthority.new(authority_key(authority_name))
33
+ if authority.blank?
34
+ if status_log.present?
35
+ status_log.add(authority_name: authority_name,
36
+ status: QaServer::ScenarioValidator::FAIL,
37
+ error_message: "Unable to load authority '#{authority_name}'; cause: UNKNOWN")
38
+ end
39
+ return nil
40
+ end
41
+ authority
42
+ end
36
43
  end
37
- private_class_method :load_authority
38
44
  end
39
45
  end
@@ -47,7 +47,9 @@
47
47
 
48
48
  <div id="content-wrapper" class="container" role="main">
49
49
  <a name="skip_to_content"></a>
50
- <%# = render '/flash_msg' %>
50
+ <% flash.each do |key, value| %>
51
+ <div class="alert alert-<%= key %>"><%= value %></div>
52
+ <% end %>
51
53
  <% if content_for?(:page_header) %>
52
54
  <div class="row">
53
55
  <div class="col-xs-12 main-header">
@@ -0,0 +1,62 @@
1
+ <script>
2
+ function validate_authority(form) {
3
+ form.submit();
4
+ document.getElementById('status-loading-message').style.display = 'block';
5
+ }
6
+ </script>
7
+
8
+ <div class="page-description">
9
+
10
+ <h2><%= t('qa_server.fetch.title') %></h2>
11
+
12
+ <%= form_tag({ action: 'index' }, { method: :get }) do %>
13
+ <p>
14
+ <%= label_tag('uri', t('qa_server.fetch.uri_field_label'), class: 'horizontal-list') %>
15
+ <%= text_field_tag('uri', @presenter.uri, placeholder: 'Enter URI for term...', size: 75, maxlength: 75) %>
16
+ </p>
17
+ <p>
18
+ <%= label_tag('authority', t('qa_server.fetch.authority_field_label'), class: 'horizontal-list') %>
19
+ <% if @presenter.term_results? %>
20
+ <%= select_tag('authority', options_for_select(@presenter.authorities_list, @presenter.authority)) %>
21
+ <% else %>
22
+ <%= select_tag('authority', options_for_select(@presenter.authorities_list), include_blank: t('qa_server.fetch.select_authority')) %>
23
+ <% end %>
24
+ </p>
25
+ <p>
26
+ <%= label_tag('results_format', t('qa_server.fetch.format_field_label'), class: 'horizontal-list') %>
27
+ <%= select_tag('results_format', options_for_select(@presenter.formats_list, @presenter.format)) %>
28
+ </p>
29
+ <p>
30
+ <%= submit_tag t('qa_server.fetch.submit_button'), class: 'submit_button' %>
31
+ </p>
32
+ <% end %>
33
+
34
+ <div id="status-loading-message" class="wait-message"><%= t('qa_server.fetch.wait_message') %></div>
35
+
36
+ <% if @presenter.term_results? %>
37
+ <div id="term-results-section" class="results-section">
38
+ <h3><%= t('qa_server.fetch.term_results') %></h3>
39
+ <table class="status">
40
+ <tr>
41
+ <th><%= t('qa_server.fetch.uri_field_label') %></th>
42
+ <td><%= @presenter.uri %></td>
43
+ </tr>
44
+ <tr>
45
+ <th><%= t('qa_server.fetch.authority_field_label') %></th>
46
+ <td><%= @presenter.authority %></td>
47
+ </tr>
48
+ <tr>
49
+ <th><%= t('qa_server.fetch.format_field_label') %></th>
50
+ <td><%= @presenter.format %></td>
51
+ </tr>
52
+ </table>
53
+
54
+ <div id="term-results" class="results-panel">
55
+ <pre><%= @presenter.term_results %></pre>
56
+ </div>
57
+
58
+ </div>
59
+
60
+ <% end %>
61
+
62
+ </div>
@@ -26,7 +26,7 @@
26
26
  <p class="status-update-dtstamp"><%= t('qa_server.monitor_status.summary.last_updated', date: @presenter.last_updated) %></p>
27
27
 
28
28
  <% if @presenter.failures? %>
29
- <div id="status-section" class="status-section">
29
+ <div id="failures" class="status-section">
30
30
  <h4><%= t('qa_server.monitor_status.failures.title') %></h4>
31
31
 
32
32
  <table class="status">
@@ -60,7 +60,7 @@
60
60
  <% end %>
61
61
 
62
62
  <% if @presenter.history? && @presenter.display_history_details?%>
63
- <div id="status-section" class="status-section">
63
+ <div id="availability-history" class="status-section">
64
64
  <h3><%= t('qa_server.monitor_status.history.title') %></h3>
65
65
  <p class="status-update-dtstamp"><%= t('qa_server.monitor_status.history.since', date: @presenter.first_updated) %></p>
66
66
  <%#= column_chart @presenter.historical_summary, stacked: true, colors: ["green", "red"], xtitle: 'Authority', ytitle: 'Pass-Fail', legend: 'bottom' %>
@@ -90,4 +90,64 @@
90
90
  <% end %>
91
91
  </div>
92
92
  <% end %>
93
+
94
+ <% if @presenter.performance_data? %>
95
+ <div id="performance-data" class="status-section">
96
+ <h3><%= t('qa_server.monitor_status.performance.title') %></h3>
97
+
98
+ <script>
99
+ function switch_performance_view(id) {
100
+ document.getElementById('performance-by-the-hour').style.display = 'none';
101
+ document.getElementById('performance-by-the-day').style.display = 'none';
102
+ document.getElementById('performance-by-the-month').style.display = 'none';
103
+ document.getElementById(id).style.display = 'block';
104
+ }
105
+ </script>
106
+
107
+ <div id="performance-by-the-hour" class="performance-data-section">
108
+ <div id="right-menu-section">
109
+ <ul class="right-menu">
110
+ <li class="selected"><%= t('qa_server.monitor_status.performance.menu_day') %></li>
111
+ <li class="clickable" onClick="switch_performance_view('performance-by-the-day')"><%= t('qa_server.monitor_status.performance.menu_month') %></li>
112
+ <li class="clickable" onClick="switch_performance_view('performance-by-the-month')"><%= t('qa_server.monitor_status.performance.menu_year') %></li>
113
+ </ul>
114
+ </div>
115
+
116
+ <div id="performance-chart-by-the-hour" class="performance-chart">
117
+ <p>Data for the last 24 hours</p>
118
+ <%= image_tag(@presenter.performance_for_day_graph, alt: 'Performance data for the last 24 hours.') %>
119
+ </div>
120
+ </div>
121
+
122
+ <div id="performance-by-the-day" class="performance-data-section">
123
+ <div id="right-menu-section">
124
+ <ul class="right-menu">
125
+ <li class="clickable" onClick="switch_performance_view('performance-by-the-hour')"><%= t('qa_server.monitor_status.performance.menu_day') %></li>
126
+ <li class="selected"><%= t('qa_server.monitor_status.performance.menu_month') %></li>
127
+ <li class="clickable" onClick="switch_performance_view('performance-by-the-month')"><%= t('qa_server.monitor_status.performance.menu_year') %></li>
128
+ </ul>
129
+ </div>
130
+
131
+ <div id="performance-chart-by-the-day" class="performance-chart">
132
+ <p>Data for the last 30 days</p>
133
+ <%= image_tag(@presenter.performance_for_month_graph, alt: 'Performance data for the last 30 days.') %>
134
+ </div>
135
+ </div>
136
+
137
+ <div id="performance-by-the-month" class="performance-data-section">
138
+ <div id="right-menu-section">
139
+ <ul class="right-menu">
140
+ <li class="clickable" onClick="switch_performance_view('performance-by-the-hour')"><%= t('qa_server.monitor_status.performance.menu_day') %></li>
141
+ <li class="clickable" onClick="switch_performance_view('performance-by-the-day')"><%= t('qa_server.monitor_status.performance.menu_month') %></li>
142
+ <li class="selected"><%= t('qa_server.monitor_status.performance.menu_year') %></li>
143
+ </ul>
144
+ </div>
145
+
146
+ <div id="performance-chart-by-the-month" class="performance-chart">
147
+ <p>Data for the last 12 months</p>
148
+ <%= image_tag(@presenter.performance_for_year_graph, alt: 'Performance data for the last 12 months.') %>
149
+ </div>
150
+ </div>
151
+ </div>
152
+ <% end %>
93
153
  </div>
@@ -7,6 +7,7 @@ en:
7
7
  authorities: Authorities
8
8
  check_status: Check Status
9
9
  monitor_status: Monitor Status
10
+ fetch_term: Fetch Term
10
11
  authority_list:
11
12
  title: Authority List
12
13
  see_check_status_html: 'See <a href="%{href}">Check Status</a> to test whether an authority is online.'
@@ -36,6 +37,15 @@ en:
36
37
  subauthority: Subauthority
37
38
  subject_uri: Expected Subject
38
39
  url: Sample URL
40
+ fetch:
41
+ title: Fetch a Term
42
+ authority_field_label: Authority
43
+ select_authority: Select authority...
44
+ format_field_label: Format
45
+ uri_field_label: URI
46
+ submit_button: Fetch Term
47
+ wait_message: Fetching term...
48
+ term_results: Results
39
49
  monitor_status:
40
50
  title: Monitor Status
41
51
  summary:
@@ -64,5 +74,19 @@ en:
64
74
  days_passing: Days Passing
65
75
  days_tested: Days Tested
66
76
  percent_failing: Percent Failing
77
+ performance:
78
+ title: Performance Metrics
79
+ menu_day: Day
80
+ menu_month: Month
81
+ menu_year: Year
82
+ load_time_ms: Load Time (ms)
83
+ normalization_time_ms: Normalization Time (ms)
84
+ combined_time_ms: Full Request Time (ms)
85
+ x_axis_hour: Hour
86
+ x_axis_day: Day
87
+ x_axis_month: Month
88
+ y_axis_ms: Milliseconds (ms)
89
+ now: NOW
90
+ today: TODAY
67
91
  usage:
68
92
  title: Usage
@@ -10,4 +10,5 @@ QaServer::Engine.routes.draw do
10
10
  resources :check_status, only: 'index'
11
11
  resources :monitor_status, only: 'index'
12
12
  resources :authority_list, only: 'index'
13
+ resources :fetch, only: 'index'
13
14
  end
@@ -34,4 +34,13 @@ class QaServer::ConfigGenerator < Rails::Generators::Base
34
34
  def create_initializer_config_file
35
35
  copy_file 'config/initializers/qa_server.rb'
36
36
  end
37
+
38
+ def append_prepends
39
+ inject_into_file 'config/application.rb', after: /Rails::Application/ do
40
+ "\n config.to_prepare do"\
41
+ "\n Qa::Authorities::LinkedData::FindTerm.prepend PrependedLinkedData::FindTerm"\
42
+ "\n Qa::Authorities::LinkedData::SearchQuery.prepend PrependedLinkedData::SearchQuery"\
43
+ "\n end\n"
44
+ end
45
+ end
37
46
  end
@@ -4,6 +4,8 @@ authority:
4
4
  search:
5
5
  -
6
6
  query: malignant
7
+ maxRecords: '4'
8
+ result_size: 1800
7
9
  term:
8
10
  -
9
11
  identifier: 'http://purl.bioontology.org/ontology/MESH/C535700'
@@ -24,7 +24,7 @@
24
24
  },
25
25
  "term_id": "URI",
26
26
  "results": {
27
- "id_ldpath": "dc:identifier ::xsd:string",
27
+ "id_ldpath": "dc:identifier ::xsd:string",
28
28
  "label_ldpath": "skos:prefLabel ::xsd:string",
29
29
  "altlabel_ldpath": "skos:altLabel ::xsd:string",
30
30
  "broader_ldpath": "skos:broader ::xsd:anyURI",
@@ -25,7 +25,7 @@
25
25
  },
26
26
  "term_id": "URI",
27
27
  "results": {
28
- "id_ldpath": "dc:identifier ::xsd:string",
28
+ "id_ldpath": "dc:identifier ::xsd:string",
29
29
  "label_ldpath": "skos:prefLabel ::xsd:string",
30
30
  "altlabel_ldpath": "skos:altLabel ::xsd:string",
31
31
  "broader_ldpath": "skos:broader ::xsd:anyURI",
@@ -24,7 +24,7 @@
24
24
  },
25
25
  "term_id": "URI",
26
26
  "results": {
27
- "id_ldpath": "dc:identifier ::xsd:string",
27
+ "id_ldpath": "dc:identifier ::xsd:string",
28
28
  "label_ldpath": "skos:prefLabel ::xsd:string",
29
29
  "altlabel_ldpath": "skos:altLabel ::xsd:string",
30
30
  "broader_ldpath": "skos:broader ::xsd:anyURI",
@@ -27,7 +27,7 @@
27
27
  "results": {
28
28
  "id_ldpath": "loc:lccn ::xsd:string",
29
29
  "label_ldpath": "skos:prefLabel ::xsd:string",
30
- "altlabel_ldpath": "skos:altLabel ::xsd:string",
30
+ "altlabel_ldpath": "madsrdf:hasVariant/madsrdf:variantLabel ::xsd:string",
31
31
  "sameas_ldpath": "skos:exactMatch ::xsd:anyURI"
32
32
  }
33
33
  },
@@ -35,7 +35,7 @@
35
35
  "url": {
36
36
  "@context": "http://www.w3.org/ns/hydra/context.jsonld",
37
37
  "@type": "IriTemplate",
38
- "template": "http://services.ld4l.org/ld4l_services/loc_demographics_batch.jsp?{?query}&{?maxRecords}&{?lang}",
38
+ "template": "http://services.ld4l.org/ld4l_services/loc_demographics_batch.jsp?{?query}&{?maxRecords}&{?startRecord}&{?lang}",
39
39
  "variableRepresentation": "BasicRepresentation",
40
40
  "mapping": [
41
41
  {
@@ -52,6 +52,13 @@
52
52
  "required": false,
53
53
  "default": "20"
54
54
  },
55
+ {
56
+ "@type": "IriTemplateMapping",
57
+ "variable": "startRecord",
58
+ "property": "hydra:freetextQuery",
59
+ "required": false,
60
+ "default": "1"
61
+ },
55
62
  {
56
63
  "@type": "IriTemplateMapping",
57
64
  "variable": "lang",
@@ -65,8 +72,108 @@
65
72
  "query": "query"
66
73
  },
67
74
  "results": {
68
- "label_ldpath": "madsrdf:authoritativeLabel ::xsd:string",
75
+ "label_ldpath": "skos:prefLabel ::xsd:string",
69
76
  "sort_ldpath": "vivo:rank ::xsd:string"
77
+ },
78
+ "context": {
79
+ "groups": {
80
+ "hierarchy": {
81
+ "group_label_i18n": "qa.linked_data.authority.locdemographics_ld4l_cache.hierarchy",
82
+ "group_label_default": "Hierarchy"
83
+ }
84
+ },
85
+ "properties": [
86
+ {
87
+ "property_label_i18n": "qa.linked_data.authority.locdemographics_ld4l_cache.preferred_label",
88
+ "property_label_default": "Preferred label",
89
+ "ldpath": "skos:prefLabel :: xsd:string",
90
+ "selectable": true,
91
+ "drillable": false
92
+ },
93
+ {
94
+ "group_id": "hierarchy",
95
+ "property_label_i18n": "qa.linked_data.authority.locdemographics_ld4l_cache.broader",
96
+ "property_label_default": "Broader",
97
+ "ldpath": "skos:broader :: xsd:string",
98
+ "selectable": true,
99
+ "drillable": true,
100
+ "expansion_label_ldpath": "skos:prefLabel ::xsd:string",
101
+ "expansion_id_ldpath": "loc:lccn ::xsd:string"
102
+ },
103
+ {
104
+ "group_id": "hierarchy",
105
+ "property_label_i18n": "qa.linked_data.authority.locdemographics_ld4l_cache.narrower",
106
+ "property_label_default": "Narrower",
107
+ "ldpath": "skos:narrower :: xsd:string",
108
+ "selectable": true,
109
+ "drillable": true,
110
+ "expansion_label_ldpath": "skos:prefLabel ::xsd:string",
111
+ "expansion_id_ldpath": "loc:lccn ::xsd:string"
112
+ },
113
+ {
114
+ "property_label_i18n": "qa.linked_data.authority.locdemographics_ld4l_cache.variant_label",
115
+ "property_label_default": "Variant",
116
+ "ldpath": "madsrdf:hasVariant/madsrdf:variantLabel :: xsd:string",
117
+ "selectable": false,
118
+ "drillable": false
119
+ },
120
+ {
121
+ "property_label_i18n": "qa.linked_data.authority.locdemographics_ld4l_cache.earlier_form",
122
+ "property_label_default": "Earlier form",
123
+ "ldpath": "madsrdf:hasEarlierEstablishedForm/madsrdf:variantLabel :: xsd:string",
124
+ "selectable": false,
125
+ "drillable": false
126
+ },
127
+ {
128
+ "property_label_i18n": "qa.linked_data.authority.locdemographics_ld4l_cache.related",
129
+ "property_label_default": "Related",
130
+ "ldpath": "skos:related/skos:prefLabel :: xsd:string",
131
+ "selectable": false,
132
+ "drillable": false
133
+ },
134
+ {
135
+ "property_label_i18n": "qa.linked_data.authority.locdemographics_ld4l_cache.note",
136
+ "property_label_default": "Note",
137
+ "ldpath": "skos:note :: xsd:string",
138
+ "selectable": false,
139
+ "drillable": false
140
+ },
141
+ {
142
+ "property_label_i18n": "qa.linked_data.authority.locdemographics_ld4l_cache.example",
143
+ "property_label_default": "Example",
144
+ "ldpath": "skos:example :: xsd:string",
145
+ "selectable": false,
146
+ "drillable": false
147
+ },
148
+ {
149
+ "property_label_i18n": "qa.linked_data.authority.locdemographics_ld4l_cache.citation_note",
150
+ "property_label_default": "Citation note",
151
+ "ldpath": "madsrdf:hasSource/madsrdf:citation-note :: xsd:string",
152
+ "selectable": false,
153
+ "drillable": false
154
+ },
155
+ {
156
+ "property_label_i18n": "qa.linked_data.authority.locdemographics_ld4l_cache.citation_source",
157
+ "property_label_default": "Citation source",
158
+ "ldpath": "madsrdf:hasSource/madsrdf:citation-source :: xsd:string",
159
+ "selectable": false,
160
+ "drillable": false
161
+ },
162
+ {
163
+ "property_label_i18n": "qa.linked_data.authority.locdemographics_ld4l_cache.citation_status",
164
+ "property_label_default": "Citation status",
165
+ "ldpath": "madsrdf:hasSource/madsrdf:citation-status :: xsd:string",
166
+ "selectable": false,
167
+ "drillable": false
168
+ },
169
+ {
170
+ "property_label_i18n": "qa.linked_data.authority.locdemographics_ld4l_cache.scheme",
171
+ "property_label_default": "Scheme",
172
+ "ldpath": "madsrdf:isMemberOfMADSScheme/rdfs:label :: xsd:string",
173
+ "selectable": false,
174
+ "drillable": false
175
+ }
176
+ ]
70
177
  }
71
178
  }
72
179
  }