@@ -125,6 +125,7 @@ class DataHarmonizer {
125
125
) ;
126
126
this . columnHelpEntries = options . columnHelpEntries || [
127
127
'column' ,
128
+ 'slot_uri' ,
128
129
'description' ,
129
130
'guidance' ,
130
131
'examples' ,
@@ -162,6 +163,7 @@ class DataHarmonizer {
162
163
163
164
// Reset specify header modal values when the modal is closed
164
165
$ ( '#specify-headers-modal' ) . on ( 'hidden.bs.modal' , ( ) => {
166
+ $ ( '.mapping-row' ) . remove ( ) ;
165
167
$ ( '#specify-headers-err-msg' ) . hide ( ) ;
166
168
$ ( '#specify-headers-confirm-btn' ) . unbind ( ) ;
167
169
} ) ;
@@ -176,7 +178,7 @@ class DataHarmonizer {
176
178
( field ) => field . title === field_reference
177
179
) ;
178
180
$ ( '#field-description-text' ) . html (
179
- urlToClickableAnchor ( this . getComment ( field ) )
181
+ this . getComment ( field )
180
182
) ;
181
183
$ ( '#field-description-modal' ) . modal ( 'show' ) ;
182
184
} ) ;
@@ -1037,6 +1039,30 @@ class DataHarmonizer {
1037
1039
hotInstance . render ( ) ; // Render the table to apply changes
1038
1040
}
1039
1041
1042
+ renderSemanticID ( curieOrURI , as_markup = false ) {
1043
+ if ( curieOrURI ) {
1044
+ if ( curieOrURI . toLowerCase ( ) . startsWith ( 'http' ) ) {
1045
+ if ( as_markup )
1046
+ return `[${ curieOrURI } ](${ curieOrURI } )` ;
1047
+
1048
+ return `<a href="${ curieOrURI } " target="_blank">${ curieOrURI } </a>` ;
1049
+ }
1050
+ else if ( curieOrURI . includes ( ':' ) ) {
1051
+ const [ prefix , reference ] = curieOrURI . split ( ':' , 2 ) ;
1052
+ if ( prefix && reference && ( prefix in this . schema . prefixes ) ) {
1053
+ // Lookup curie
1054
+ let url = this . schema . prefixes [ prefix ] [ 'prefix_reference' ] + reference ;
1055
+ if ( as_markup )
1056
+ return `[${ curieOrURI } ](${ url } )` ;
1057
+ return `<a href="${ url } " target="_blank">${ curieOrURI } </a>` ;
1058
+ }
1059
+ else
1060
+ return `${ curieOrURI } ` ;
1061
+ }
1062
+ }
1063
+ return '' ;
1064
+ }
1065
+
1040
1066
/**
1041
1067
* Presents reference guide in a popup.
1042
1068
* @param {String } mystyle simple css stylesheet commands to override default.
@@ -1046,6 +1072,7 @@ class DataHarmonizer {
1046
1072
1047
1073
let style = `
1048
1074
body {
1075
+ background-color:#fff;
1049
1076
font-family: arial;
1050
1077
margin:5% 5% 5% 5%;
1051
1078
}
@@ -1080,17 +1107,19 @@ class DataHarmonizer {
1080
1107
let row_html = '' ;
1081
1108
for ( const section of this . sections ) {
1082
1109
row_html += `<tr class="section">
1083
- <td colspan="${ this . columnHelpEntries . length } "><h3>${
1110
+ <td colspan="${ this . columnHelpEntries . length - 1 } "><h3>${
1084
1111
section . title || section . name
1085
1112
} </h3></td>
1086
1113
</tr>
1087
1114
` ;
1088
1115
for ( const slot of section . children ) {
1089
1116
const slot_dict = this . getCommentDict ( slot ) ;
1090
1117
1118
+ const slot_uri = this . renderSemanticID ( slot_dict . slot_uri ) ;
1119
+
1091
1120
row_html += '<tr>' ;
1092
1121
if ( this . columnHelpEntries . includes ( 'column' ) ) {
1093
- row_html += `<td class="label">${ slot_dict . title } </td>` ;
1122
+ row_html += `<td class="label">${ slot_dict . title } <br> ${ slot_uri } < /td>` ;
1094
1123
}
1095
1124
if ( this . columnHelpEntries . includes ( 'description' ) ) {
1096
1125
row_html += `<td>${ slot_dict . description } </td>` ;
@@ -1102,38 +1131,62 @@ class DataHarmonizer {
1102
1131
row_html += `<td>${ slot_dict . examples } </td>` ;
1103
1132
}
1104
1133
if ( this . columnHelpEntries . includes ( 'menus' ) ) {
1105
- row_html += ` <td>${ slot_dict . sources || '' } </td>` ;
1134
+ row_html += ` <td>${ slot_dict . menus || '' } </td>` ;
1106
1135
}
1107
1136
row_html += '</tr>' ;
1108
1137
}
1109
1138
}
1110
1139
1140
+ // Note this may include more enumerations than exist in a given template.
1141
+ let enum_html = `` ;
1142
+ for ( const key of Object . keys ( this . schema . enums ) . sort ( ) ) {
1143
+ const enumeration = this . schema . enums [ key ] ;
1144
+ let title = enumeration . title != enumeration . name ? enumeration . title : '' ;
1145
+ enum_html += `<tr class="section">
1146
+ <td colspan="2" id="${ enumeration . name } ">${ enumeration . name } </td>
1147
+ <td colspan="2" style="font-size:1.2rem;">"${ title } "<br>${ this . renderSemanticID ( enumeration . enum_uri ) } </td>
1148
+ </tr>` ;
1149
+
1150
+ for ( const item_key in enumeration . permissible_values ) {
1151
+ const item = enumeration . permissible_values [ item_key ] ;
1152
+ let text = item . text != item_key ? item . text : '' ;
1153
+ enum_html += `<tr>
1154
+ <td>${ this . renderSemanticID ( item . meaning ) } </td>
1155
+ <td>${ item_key } </td>
1156
+ <td>${ text } </td>
1157
+ <td></td>
1158
+ </tr>` ;
1159
+ }
1160
+ }
1161
+
1111
1162
var win = window . open (
1112
1163
'' ,
1113
1164
'Reference' ,
1114
- 'toolbar=no,location=no ,directories=no,status=no,menubar=no,scrollbars=yes,resizable=yes,width=1000,height=600'
1165
+ 'toolbar=no,location=yes ,directories=no,status=no,menubar=no,scrollbars=yes,resizable=yes,width=1000,height=600'
1115
1166
) ;
1116
1167
1117
- win . document . head . innerHTML = `
1118
- <meta charset="utf-8">
1119
- <title>${ i18next . t ( 'reference_guide_title' ) } "${
1168
+ win . document . open ( ) ; // For reloads
1169
+ win . document . write ( `<!DOCTYPE html>
1170
+ <html lang="en">
1171
+ <head>
1172
+ <meta charset="utf-8">
1173
+ <title>${ i18next . t ( 'reference_guide_title' ) } "${
1120
1174
schema_template . title || schema_template . name
1121
1175
} " template</title>
1122
- <meta name="description" content="${ schema_template . description || '' } ">
1123
- <style>${ style } </style>
1124
- ` ;
1125
-
1126
- win . document . body . innerHTML = `
1127
- <div>
1176
+ <meta name="description" content="${ schema_template . description || '' } ">
1177
+ <style>${ style } </style>
1178
+ </head>
1179
+ <body>
1180
+ <div>
1128
1181
<h2>${ i18next . t ( 'reference_guide_title' ) } "${
1129
1182
schema_template . title || schema_template . name
1130
1183
} " template</h2>
1131
- <hr size="2" />
1184
+ <hr/>
1132
1185
<p>${ schema_template . description || '' } </p>
1133
1186
1134
1187
<table>
1135
- <thead>
1136
- <tr>
1188
+ <thead>
1189
+ <tr>
1137
1190
${
1138
1191
this . columnHelpEntries . includes ( 'column' )
1139
1192
? `<th class="label">${ i18next . t ( 'help-sidebar__column' ) } </th>`
@@ -1161,16 +1214,25 @@ class DataHarmonizer {
1161
1214
? `<th class="data_status">${ i18next . t ( 'help-sidebar__menus' ) } </th>`
1162
1215
: ''
1163
1216
}
1164
- </tr>
1165
- </thead>
1166
- <tbody>
1167
- ${ row_html }
1168
- </tbody>
1169
- </table>
1217
+ </tr>
1218
+ </thead>
1219
+ <tbody>
1220
+ ${ row_html }
1221
+ </tbody>
1222
+ </table>
1170
1223
</div>
1171
- </body>
1172
- </html>
1173
- ` ;
1224
+ <div>
1225
+ <table>
1226
+ <thead>
1227
+ <tr class="section">
1228
+ <th colspan="4">${ i18next . t ( 'help-picklists' ) } </th>
1229
+ </tr>
1230
+ </thead>
1231
+ <tbody>${ enum_html } </tbody>
1232
+ </table>
1233
+ </div>
1234
+ </body>
1235
+ </html>` ) ;
1174
1236
return false ;
1175
1237
}
1176
1238
@@ -1346,23 +1408,20 @@ class DataHarmonizer {
1346
1408
let flatHeaders = this . getFlatHeaders ( ) ;
1347
1409
const self = this ;
1348
1410
if ( flatHeaders ) {
1349
- $ ( '#field-mapping' ) . prepend (
1350
- '<col></col>' . repeat ( flatHeaders [ 1 ] . length + 1 )
1351
- ) ;
1352
- $ ( '#expected-headers-tr' ) . html (
1353
- '<td><b>Expected second row</b></td> <td>' +
1354
- flatHeaders [ 1 ] . join ( '</td><td>' ) +
1355
- '</td>'
1356
- ) ;
1357
- $ ( '#actual-headers-tr' ) . html (
1358
- '<td><b>Imported second row</b></td> <td>' +
1359
- matrix [ 1 ] . join ( '</td><td>' ) +
1360
- '</td>'
1361
- ) ;
1362
- flatHeaders [ 1 ] . forEach ( function ( item , i ) {
1363
- if ( item != matrix [ 1 ] [ i ] ) {
1364
- $ ( '#field-mapping col' ) . get ( i + 1 ) . style . backgroundColor = 'orange' ;
1411
+ const $fieldMappingBody = $ ( '#field-mapping-body' ) ;
1412
+ flatHeaders [ 1 ] . forEach ( function ( expectedHeader , i ) {
1413
+ const expectedHeaderCell =
1414
+ `<td class="field-mapping-cell">${ expectedHeader } </td>`
1415
+ const actualHeaderCell =
1416
+ `<td class="field-mapping-cell">${ matrix [ 1 ] [ i ] } </td>` ;
1417
+ const rowCells = expectedHeaderCell + actualHeaderCell ;
1418
+ let row ;
1419
+ if ( expectedHeader !== matrix [ 1 ] [ i ] ) {
1420
+ row = $ ( `<tr class="table-warning mapping-row">${ rowCells } </tr>` ) ;
1421
+ } else {
1422
+ row = $ ( `<tr class="mapping-row">${ rowCells } </tr>` ) ;
1365
1423
}
1424
+ $fieldMappingBody . append ( row ) ;
1366
1425
} ) ;
1367
1426
1368
1427
$ ( '#specify-headers-modal' ) . modal ( 'show' ) ;
@@ -1455,8 +1514,8 @@ class DataHarmonizer {
1455
1514
// Close current dialog and switch to error message
1456
1515
//$('specify-headers-modal').modal('hide');
1457
1516
//$('#unmapped-headers-modal').modal('hide');
1458
- const errMsg = `The template for the loaded file has a configuration error:<br/ >
1459
- <strong>${ parent . title } </strong><br/ >
1517
+ const errMsg = `The template for the loaded file has a configuration error:<br>
1518
+ <strong>${ parent . title } </strong><br>
1460
1519
This is a field that has no parent, or a section that has no fields.` ;
1461
1520
$ ( '#unmapped-headers-list' ) . html ( errMsg ) ;
1462
1521
$ ( '#unmapped-headers-modal' ) . modal ( 'show' ) ;
@@ -1491,8 +1550,16 @@ class DataHarmonizer {
1491
1550
// Map current column indices to their indices in matrix to map
1492
1551
const headerMap = { } ;
1493
1552
const unmappedHeaders = [ ] ;
1494
- for ( const [ i , expectedVal ] of expectedSecondaryHeaders . entries ( ) ) {
1553
+ for ( let [ i , expectedVal ] of expectedSecondaryHeaders . entries ( ) ) {
1495
1554
headerMap [ i ] = actualSecondaryHeaders . findIndex ( ( actualVal ) => {
1555
+ // Case insensitivity
1556
+ if ( typeof actualVal === 'string' || actualVal instanceof String ) {
1557
+ actualVal = actualVal . toLowerCase ( )
1558
+ }
1559
+ if ( typeof expectedVal === 'string' || expectedVal instanceof String ) {
1560
+ expectedVal = expectedVal . toLowerCase ( )
1561
+ }
1562
+
1496
1563
return actualVal === expectedVal ;
1497
1564
} ) ;
1498
1565
if ( headerMap [ i ] === - 1 ) {
@@ -1868,6 +1935,14 @@ class DataHarmonizer {
1868
1935
) } </strong>: ${ field . title || field . name } </p>`;
1869
1936
}
1870
1937
1938
+ // Requires markup treatment of URLS.
1939
+ const slot_uri = this . renderSemanticID ( field . slot_uri ) ;
1940
+ if ( field . slot_uri && this . columnHelpEntries . includes ( 'slot_uri' ) ) {
1941
+ ret += `<p><strong data-i18n="help-sidebar__column">${ i18next . t (
1942
+ 'help-sidebar__slot_uri'
1943
+ ) } </strong>: ${ slot_uri } </p>`;
1944
+ }
1945
+
1871
1946
if ( field . description && this . columnHelpEntries . includes ( 'description' ) ) {
1872
1947
ret += `<p><strong data-i18n="help-sidebar__description">${ i18next . t (
1873
1948
'help-sidebar__description'
@@ -1907,10 +1982,12 @@ class DataHarmonizer {
1907
1982
let guide = {
1908
1983
title : field . title ,
1909
1984
name : field . name ,
1910
- description : field . description || '' ,
1985
+ slot_uri : field . slot_uri ,
1986
+ description : urlToClickableAnchor ( field . description ) || '' ,
1911
1987
guidance : '' ,
1912
1988
examples : '' ,
1913
1989
sources : '' ,
1990
+ menus : ''
1914
1991
} ;
1915
1992
1916
1993
let guidance = [ ] ;
@@ -1919,7 +1996,7 @@ class DataHarmonizer {
1919
1996
}
1920
1997
if ( field . pattern ) {
1921
1998
guidance . push (
1922
- i18next . t ( 'reference_guide_msg_pattern_regex' ) + ' ' + field . pattern
1999
+ i18next . t ( 'reference_guide_msg_pattern_regex' ) + '<br> ' + field . pattern
1923
2000
) ;
1924
2001
}
1925
2002
if ( field . structured_pattern ) {
@@ -1955,7 +2032,13 @@ class DataHarmonizer {
1955
2032
guidance . push ( i18next . t ( 'reference_guide_msg_unique_record' ) ) ;
1956
2033
}
1957
2034
if ( field . sources && field . sources . length ) {
1958
- let sources = [ ] ;
2035
+ let menus = [ ] ;
2036
+ for ( const item of field . sources ) {
2037
+ menus . push ( '<a href="#' + item + '" target="Reference">' + item + '</a>' ) ;
2038
+ }
2039
+ guide . menus = '<ul><li>' + menus . join ( '</li><li>' ) + '</li></ul>' ;
2040
+ /*
2041
+ // List null value menu items directly
1959
2042
for (const [, item] of Object.entries(field.sources)) {
1960
2043
// List null value menu items directly
1961
2044
if (item === 'NullValueMenu') {
@@ -1967,7 +2050,8 @@ class DataHarmonizer {
1967
2050
sources.push(item);
1968
2051
}
1969
2052
}
1970
- guide . sources = '<ul><li>' + sources . join ( '</li>\n<li>' ) + '</li></ul>' ;
2053
+ */
2054
+ guide . sources = '<ul><li>' + field . sources . join ( '</li><li>' ) + '</li></ul>' ;
1971
2055
}
1972
2056
if ( field . multivalued ) {
1973
2057
guidance . push ( i18next . t ( 'reference_guide_msg_more_than_one_selection' ) ) ;
@@ -1979,6 +2063,10 @@ class DataHarmonizer {
1979
2063
} )
1980
2064
. join ( '\n' ) ;
1981
2065
2066
+ // Makes full URIs that aren't in markup into <a href>
2067
+ if ( guide . guidance )
2068
+ guide . guidance = urlToClickableAnchor ( guide . guidance ) ;
2069
+
1982
2070
if ( field . examples && field . examples . length ) {
1983
2071
let examples = [ ] ;
1984
2072
let first_item = true ;
@@ -1994,9 +2082,9 @@ class DataHarmonizer {
1994
2082
1995
2083
if ( first_item === true ) {
1996
2084
first_item = false ;
1997
- examples += '<ul><li>' + i18next . t ( item . value ) + '</li>\n ' ;
2085
+ examples += '<ul><li>' + i18next . t ( item . value ) + '</li>' ;
1998
2086
} else {
1999
- examples += '<li>' + i18next . t ( item . value ) + '</li>\n ' ;
2087
+ examples += '<li>' + i18next . t ( item . value ) + '</li>' ;
2000
2088
}
2001
2089
}
2002
2090
guide . examples = examples + '</ul>' ;
0 commit comments