@@ -16,3 +16,8 @@ pre.terminal { | |||||
.w-1 { | .w-1 { | ||||
width: 1px !important; | width: 1px !important; | ||||
} | } | ||||
div.wb-json-viewer { | |||||
font-family: "Courier New", fixed-width; | |||||
white-space: pre; | |||||
} |
@@ -1,7 +1,13 @@ | |||||
import arvadosTypeName from 'arvados-type-name'; | import arvadosTypeName from 'arvados-type-name'; | ||||
const UUID_REGEX = /[a-z0-9]{5}-[a-z0-9]{5}-[a-z0-9]{15}/g; | |||||
const PDH_REGEX = /[a-f0-9]{32}\+[0-9]+/g; | |||||
const UUID_PATTERN = '[a-z0-9]{5}-[a-z0-9]{5}-[a-z0-9]{15}'; | |||||
const PDH_PATTERN = '[a-f0-9]{32}\\+[0-9]+'; | |||||
const UUID_REGEX = new RegExp(UUID_PATTERN); | |||||
const PDH_REGEX = new RegExp(PDH_PATTERN); | |||||
const UUID_REGEX_G = new RegExp(UUID_PATTERN, 'g'); | |||||
const PDH_REGEX_G = new RegExp(PDH_PATTERN, 'g'); | |||||
class WBIdTools { | class WBIdTools { | ||||
static isIdentifier(value) { | static isIdentifier(value) { | ||||
@@ -32,6 +38,28 @@ class WBIdTools { | |||||
return ( m && m.index === 0 ); | return ( m && m.index === 0 ); | ||||
} | } | ||||
static detectIdentifiers(value) { | |||||
return this.detectUuids(value).concat(this.detectPDHs(value)); | |||||
} | |||||
static detectUuids(value) { | |||||
let m; | |||||
const res = []; | |||||
while (m = UUID_REGEX_G.exec(value)) { | |||||
res.push(m); | |||||
} | |||||
return res; | |||||
} | |||||
static detectPDHs(value) { | |||||
let m; | |||||
const res = []; | |||||
while (m = PDH_REGEX_G.exec(value)) { | |||||
res.push(m); | |||||
} | |||||
return res; | |||||
} | |||||
static typeName(value) { | static typeName(value) { | ||||
if (this.isPDH(value)) | if (this.isPDH(value)) | ||||
return 'collection'; | return 'collection'; | ||||
@@ -0,0 +1,39 @@ | |||||
import { h, Component } from 'preact'; | |||||
import WBIdTools from 'wb-id-tools'; | |||||
import urlForObject from 'url-for-object'; | |||||
function detectIds(value) { | |||||
const matches = WBIdTools.detectIdentifiers(value); | |||||
matches.sort((a, b) => (a.index - b.index)); | |||||
const res = []; | |||||
let ofs = 0; | |||||
for (let i = 0; i < matches.length; i++) { | |||||
const { index } = matches[i]; | |||||
const id = matches[i][0]; | |||||
const typeName = WBIdTools.typeName(id); | |||||
const url = (typeName === 'group' ? '/browse/' + id : | |||||
typeName === 'collection' ? '/collection-browse/' + id : | |||||
urlForObject({ uuid: id })); | |||||
res.push(value.substring(ofs, index)); | |||||
res.push(h('a', { href: url }, id)); | |||||
ofs = index + id.length; | |||||
} | |||||
res.push(value.substring(ofs)); | |||||
return res; | |||||
} | |||||
class WBJsonViewer extends Component { | |||||
render({ value, stringify }) { | |||||
if (stringify) | |||||
value = JSON.stringify(value, null, 2); | |||||
return ( | |||||
<div class="wb-json-viewer">{ detectIds(value) }</div> | |||||
); | |||||
} | |||||
} | |||||
WBJsonViewer.defaultProps = { | |||||
stringify: true | |||||
}; | |||||
export default WBJsonViewer; |