aboutsummaryrefslogtreecommitdiff
path: root/src/components
diff options
context:
space:
mode:
Diffstat (limited to 'src/components')
-rw-r--r--src/components/TileInfoModal.vue240
1 files changed, 111 insertions, 129 deletions
diff --git a/src/components/TileInfoModal.vue b/src/components/TileInfoModal.vue
index 90ad9a7..c8f8047 100644
--- a/src/components/TileInfoModal.vue
+++ b/src/components/TileInfoModal.vue
@@ -1,76 +1,66 @@
<script lang="ts">
+
import {defineComponent, PropType} from 'vue';
import CloseIcon from './icon/CloseIcon.vue';
-import Tile from './Tile.vue'
import {LayoutNode, LayoutOptions} from '../layout';
-import {TolNode, TolMap, UiOptions, DescInfo, ImgInfo, TileInfoResponse} from '../lib';
+import {TolNode, TolMap, UiOptions, DescInfo, ImgInfo, NodeInfo, InfoResponse} from '../lib';
import {capitalizeWords} from '../util';
-// Displays information about a tree-of-life node
export default defineComponent({
- data(){
- return {
- tolNode: null as null | TolNode,
- descInfo: null as null | DescInfo,
- descInfo1: null as null | DescInfo,
- descInfo2: null as null | DescInfo,
- imgInfo: null as null | ImgInfo,
- imgInfo1: null as null | ImgInfo,
- imgInfo2: null as null | ImgInfo,
- };
- },
props: {
nodeName: {type: String, required: true},
tolMap: {type: Object as PropType<TolMap>, required: true},
+ // Options
lytOpts: {type: Object as PropType<LayoutOptions>, required: true},
uiOpts: {type: Object as PropType<UiOptions>, required: true},
},
+ data(){
+ return {
+ // These are set using a server response
+ tolNode: null as null | TolNode,
+ nodes: [] as TolNode[], // The nodes to display info for
+ imgInfos: [] as (ImgInfo | null)[],
+ descInfos: [] as (DescInfo | null)[],
+ };
+ },
computed: {
- displayName(): string {
- if (this.tolNode == null || this.tolNode.commonName == null){
- return capitalizeWords(this.nodeName);
- } else {
- return `${capitalizeWords(this.tolNode.commonName)} (aka ${capitalizeWords(this.nodeName)})`;
- }
- },
- subName1(): string {
- return this.displayName.substring(1, this.displayName.indexOf(' + '));
- },
- subName2(): string {
- return this.displayName.substring(this.displayName.indexOf(' + ') + 3, this.displayName.length - 1);
- },
- imgStyles(): Record<string,string> {
- return this.getImgStyles(this.tolNode == null ? null : this.tolNode.imgName as string);
- },
- firstImgStyles(): Record<string,string> {
- return this.getImgStyles(this.tolNode!.imgName![0]);
- },
- secondImgStyles(): Record<string,string> {
- return this.getImgStyles(this.tolNode!.imgName![1]);
+ subNames(): [string, string] | null {
+ const regex = /\[(.+) \+ (.+)\]/;
+ let results = regex.exec(this.nodeName);
+ return results == null ? null : [results[1], results[2]];
},
- dummyNode(): LayoutNode {
- let newNode = new LayoutNode(this.nodeName, []);
- newNode.dims = [this.lytOpts.maxTileSz, this.lytOpts.maxTileSz];
- return newNode;
+ styles(): Record<string,string> {
+ return {
+ backgroundColor: this.uiOpts.bgColorAlt,
+ borderRadius: this.uiOpts.borderRadius + 'px',
+ boxShadow: this.uiOpts.shadowNormal,
+ overflow: 'visible auto',
+ };
},
},
methods: {
- onCloseClick(evt: Event){
- if (evt.target == this.$el || (this.$refs.closeIcon as typeof CloseIcon).$el.contains(evt.target)){
- this.$emit('close');
+ getDisplayName(name: string, tolNode: TolNode | null): string {
+ if (tolNode == null || tolNode.commonName == null){
+ return capitalizeWords(name);
+ } else {
+ return `${capitalizeWords(tolNode.commonName)} (aka ${capitalizeWords(name)})`;
}
},
- getImgStyles(imgName: string | null){
+ getImgStyles(tolNode: TolNode): Record<string,string> {
+ let imgName = null;
+ if (typeof(tolNode.imgName) === 'string'){ // Exclude string-array case
+ imgName = tolNode.imgName;
+ }
return {
- boxShadow: this.uiOpts.shadowNormal,
- borderRadius: this.uiOpts.borderRadius + 'px',
+ width: this.lytOpts.maxTileSz + 'px',
+ height: this.lytOpts.maxTileSz + 'px',
backgroundImage: imgName != null ?
'url(\'/img/' + imgName.replaceAll('\'', '\\\'') + '\')' :
'none',
- backgroundColor: '#1c1917',
+ backgroundColor: this.uiOpts.bgColorDark,
backgroundSize: 'cover',
- width: this.lytOpts.maxTileSz + 'px',
- height: this.lytOpts.maxTileSz + 'px',
+ borderRadius: this.uiOpts.borderRadius + 'px',
+ boxShadow: this.uiOpts.shadowNormal,
};
},
licenseToUrl(license: string){
@@ -103,41 +93,54 @@ export default defineComponent({
return "[INVALID LICENSE]";
}
},
+ onClose(evt: Event){
+ if (evt.target == this.$el || (this.$refs.closeIcon as typeof CloseIcon).$el.contains(evt.target)){
+ this.$emit('close');
+ }
+ },
},
- created(){
+ async created(){
+ // Query server for tol-node info
let url = new URL(window.location.href);
url.pathname = '/data/info';
url.search = '?name=' + encodeURIComponent(this.nodeName);
- url.search += this.uiOpts.useReducedTree ? '&tree=reduced' : '';
- fetch(url.toString())
- .then(response => response.json())
- .then(obj => {
- this.tolNode = obj.tolNode;
- if (!Array.isArray(obj.descData)){
- this.descInfo = obj.descData;
- } else {
- [this.descInfo1, this.descInfo2] = obj.descData;
- }
- if (!Array.isArray(obj.imgData)){
- this.imgInfo = obj.imgData;
- } else {
- [this.imgInfo1, this.imgInfo2] = obj.imgData;
- }
- });
+ if (this.uiOpts.useReducedTree){
+ url.search += '&tree=reduced';
+ }
+ let responseObj: InfoResponse;
+ try {
+ let response = await fetch(url.toString());
+ responseObj = await response.json();
+ } catch (error){
+ console.log("ERROR: Unable to retrieve data from server")
+ return;
+ }
+ // Set fields from response
+ this.tolNode = responseObj.nodeInfo.tolNode;
+ if (responseObj.subNodesInfo.length == 0){
+ this.nodes = [this.tolNode]
+ this.imgInfos = [responseObj.nodeInfo.imgInfo];
+ this.descInfos = [responseObj.nodeInfo.descInfo];
+ } else {
+ for (let nodeInfo of responseObj.subNodesInfo){
+ this.nodes.push(nodeInfo.tolNode);
+ this.imgInfos.push(nodeInfo.imgInfo);
+ this.descInfos.push(nodeInfo.descInfo);
+ }
+ }
},
- components: {CloseIcon, Tile, },
+ components: {CloseIcon, },
emits: ['close', ],
});
</script>
<template>
-<div class="fixed left-0 top-0 w-full h-full bg-black/40" @click="onCloseClick">
- <div class="absolute left-1/2 -translate-x-1/2 w-4/5 max-h-[80%] overflow-y-auto top-1/2 -translate-y-1/2 p-4
- bg-stone-50 rounded-md shadow shadow-black">
- <close-icon @click.stop="onCloseClick" ref="closeIcon"
+<div class="fixed left-0 top-0 w-full h-full bg-black/40" @click="onClose">
+ <div class="absolute left-1/2 -translate-x-1/2 top-1/2 -translate-y-1/2 w-4/5 max-h-[80%] p-4" :style="styles">
+ <close-icon @click.stop="onClose" ref="closeIcon"
class="block absolute top-2 right-2 w-6 h-6 hover:cursor-pointer"/>
<h1 class="text-center text-xl font-bold mb-2">
- {{displayName}}
+ {{getDisplayName(nodeName, tolNode)}}
<div v-if="tolNode != null">
({{tolNode.children.length}} children, {{tolNode.tips}} tips,
<a :href="'https://tree.opentreeoflife.org/opentree/argus/opentree13.4@' + tolNode.otolId">
@@ -145,66 +148,45 @@ export default defineComponent({
</div>
</h1>
<hr class="mb-4 border-stone-400"/>
- <div class="flex">
- <div class="mr-4">
- <div v-if="tolNode == null"/>
- <div v-else-if="!Array.isArray(tolNode.imgName)">
- <div :style="imgStyles"/>
- <ul v-if="imgInfo != null">
- <li>Obtained via: {{imgInfo.src}}</li>
- <li>License: <a :href="licenseToUrl(imgInfo.license)">{{imgInfo.license}}</a></li>
- <li><a :href="imgInfo.url" class="underline">Source URL</a></li>
- <li>Artist: {{imgInfo.artist}}</li>
- <li v-if="imgInfo.credit != ''">Credit: {{imgInfo.credit}}</li>
- </ul>
- </div>
- <div v-else>
- <div v-if="tolNode.imgName[0] != null" :style="firstImgStyles"/>
- <ul v-if="imgInfo1 != null">
- <li>Obtained via: {{imgInfo1.src}}</li>
- <li>License: <a :href="licenseToUrl(imgInfo1.license)">{{imgInfo1.license}}</a></li>
- <li><a :href="imgInfo1.url" class="underline">Source URL</a></li>
- <li>Artist: {{imgInfo1.artist}}</li>
- <li v-if="imgInfo1.credit != ''">Credit: {{imgInfo1.credit}}</li>
- </ul>
- <div v-if="tolNode.imgName[1] != null" :style="secondImgStyles"/>
- <ul v-if="imgInfo2 != null">
- <li>Obtained via: {{imgInfo2.src}}</li>
- <li>License: <a :href="licenseToUrl(imgInfo2.license)">{{imgInfo2.license}}</a></li>
- <li><a :href="imgInfo2.url" class="underline">Source URL</a></li>
- <li>Artist: {{imgInfo2.artist}}</li>
- <li v-if="imgInfo2.credit != ''">Credit: {{imgInfo2.credit}}</li>
- </ul>
- </div>
- </div>
- <div v-if="descInfo == null && descInfo1 == null && descInfo2 == null">
- (No description found)
- </div>
- <div v-else-if="descInfo != null">
- <div>
- Redirected: {{descInfo.fromRedirect}} <br/>
- Short-description from {{descInfo.fromDbp ? 'DBpedia' : 'Wikipedia'}} <br/>
- <a :href="'https://en.wikipedia.org/?curid=' + descInfo.wikiId" class="underline">
- Wikipedia Link
- </a>
- </div>
- <hr/>
- <div>{{descInfo.text}}</div>
- </div>
- <div v-else>
- <div>
- <h2 class="font-bold">{{subName1}}</h2>
- <div v-if="descInfo1 != null">{{descInfo1.text}}</div>
- <div v-else>(No description found)</div>
- </div>
- <div>
- <h2 class="font-bold">{{subName2}}</h2>
- <div v-if="descInfo2 != null">{{descInfo2.text}}</div>
- <div v-else>(No description found)</div>
+ <div v-if="tolNode == null">Querying server</div>
+ <template v-else>
+ <div v-if="nodes.length > 1">This is a compound node</div>
+ <div v-for="idx in (nodes.length == 1 ? [0] : [0, 1])">
+ <h1 v-if="nodes.length > 1" class="text-center font-bold">
+ {{getDisplayName(subNames![idx], nodes[idx])}}
+ </h1>
+ <div class="flex gap-1">
+ <div class="w-1/2">
+ <div :style="getImgStyles(nodes[idx])"/>
+ <ul v-if="imgInfos[idx]! != null">
+ <li>Obtained via: {{imgInfos[idx]!.src}}</li>
+ <li>License:
+ <a :href="licenseToUrl(imgInfos[idx]!.license)">{{imgInfos[idx]!.license}}</a>
+ </li>
+ <li><a :href="imgInfos[idx]!.url" class="underline">Source URL</a></li>
+ <li>Artist: {{imgInfos[idx]!.artist}}</li>
+ <li v-if="imgInfos[idx]!.credit != ''" class="overflow-auto">
+ Credit: {{imgInfos[idx]!.credit}}
+ </li>
+ </ul>
+ </div>
+ <div v-if="descInfos[idx]! != null">
+ <div>
+ Redirected: {{descInfos[idx]!.fromRedirect}} <br/>
+ Short-description from {{descInfos[idx]!.fromDbp ? 'DBpedia' : 'Wikipedia'}} <br/>
+ <a :href="'https://en.wikipedia.org/?curid=' + descInfos[idx]!.wikiId" class="underline">
+ Wikipedia Link
+ </a>
+ </div>
+ <hr/>
+ <div>{{descInfos[idx]!.text}}</div>
+ </div>
+ <div v-else>
+ (No description found)
+ </div>
</div>
</div>
- </div>
-
+ </template>
</div>
</div>
</template>