aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTerry Truong <terry06890@gmail.com>2022-05-12 13:06:49 +1000
committerTerry Truong <terry06890@gmail.com>2022-05-12 13:06:49 +1000
commitb19bab9098e3eae71845faa7c8d17e9d03548d22 (patch)
tree987af00760fd2b76b07a92272c6dfa722df65cb6 /src
parenta9fa4cf9a40c4e636772d743371163daddda159c (diff)
Enable info-display for search suggestions
Add info-icon to SearchModal, sending event when clicked. Change App to allow info-modal display on top of search-modal. Also make info-icon-click events send a node name instead of a LayoutNode, and make TileInfoModal and server get/send additional node info, seeing as the client might not have info about the node's common name, tips, etc, anymore.
Diffstat (limited to 'src')
-rw-r--r--src/App.vue20
-rw-r--r--src/components/SearchModal.vue26
-rw-r--r--src/components/Tile.vue6
-rw-r--r--src/components/TileInfoModal.vue22
4 files changed, 47 insertions, 27 deletions
diff --git a/src/App.vue b/src/App.vue
index 55dc271..3cabecd 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -100,7 +100,7 @@ export default defineComponent({
layoutMap: initLayoutMap(layoutTree), // Maps names to LayoutNode objects
overflownRoot: false, // Set when displaying a root tile with many children, with overflow
// Modals and settings related
- infoModalNode: null as LayoutNode | null, // Node to display info for, or null
+ infoModalNodeName: null as string | null, // Name of node to display info for, or null
helpOpen: false,
searchOpen: false,
settingsOpen: false,
@@ -323,9 +323,11 @@ export default defineComponent({
this.overflownRoot = false;
},
// For tile-info events
- onInfoIconClick(node: LayoutNode){
- this.resetMode();
- this.infoModalNode = node;
+ onInfoIconClick(nodeName: string){
+ if (!this.searchOpen){
+ this.resetMode();
+ }
+ this.infoModalNodeName = nodeName;
},
// For help events
onHelpIconClick(){
@@ -574,7 +576,7 @@ export default defineComponent({
});
},
resetMode(){
- this.infoModalNode = null;
+ this.infoModalNodeName = null;
this.searchOpen = false;
this.helpOpen = false;
this.settingsOpen = false;
@@ -634,12 +636,12 @@ export default defineComponent({
text-white/40 hover:text-white hover:cursor-pointer"/>
<!-- Modals -->
<transition name="fade">
- <tile-info-modal v-if="infoModalNode != null" :node="infoModalNode" :tolMap="tolMap" :uiOpts="uiOpts"
- @info-modal-close="infoModalNode = null"/>
+ <search-modal v-if="searchOpen" :tolMap="tolMap" :uiOpts="uiOpts" ref="searchModal"
+ @search-close="searchOpen = false" @search-node="onSearchNode" @info-icon-click="onInfoIconClick"/>
</transition>
<transition name="fade">
- <search-modal v-if="searchOpen" :tolMap="tolMap" :uiOpts="uiOpts"
- @search-close="searchOpen = false" @search-node="onSearchNode" ref="searchModal"/>
+ <tile-info-modal v-if="infoModalNodeName != null" :nodeName="infoModalNodeName" :tolMap="tolMap" :uiOpts="uiOpts"
+ @info-modal-close="infoModalNodeName = null"/>
</transition>
<transition name="fade">
<help-modal v-if="helpOpen" :uiOpts="uiOpts" @help-modal-close="helpOpen = false"/>
diff --git a/src/components/SearchModal.vue b/src/components/SearchModal.vue
index eccc685..bc77a39 100644
--- a/src/components/SearchModal.vue
+++ b/src/components/SearchModal.vue
@@ -1,6 +1,7 @@
<script lang="ts">
import {defineComponent, PropType} from 'vue';
import SearchIcon from './icon/SearchIcon.vue';
+import InfoIcon from './icon/InfoIcon.vue';
import {LayoutNode} from '../layout';
import type {TolMap} from '../tol';
@@ -23,6 +24,18 @@ export default defineComponent({
tolMap: {type: Object as PropType<TolMap>, required: true},
uiOpts: {type: Object, required: true},
},
+ computed: {
+ infoIconStyles(): Record<string,string> {
+ let size = this.uiOpts.infoIconSz + 'px';
+ return {
+ width: size,
+ height: size,
+ minWidth: size,
+ minHeight: size,
+ margin: this.uiOpts.infoIconMargin + 'px',
+ };
+ },
+ },
methods: {
onCloseClick(evt: Event){
if (evt.target == this.$el || (this.$refs.searchIcon as typeof SearchIcon).$el.contains(evt.target)){
@@ -123,12 +136,15 @@ export default defineComponent({
}
}
},
+ onInfoIconClick(nodeName: string){
+ this.$emit('info-icon-click', nodeName);
+ },
},
mounted(){
(this.$refs.searchInput as HTMLInputElement).focus();
},
- components: {SearchIcon, },
- emits: ['search-node', 'search-close', ],
+ components: {SearchIcon, InfoIcon, },
+ emits: ['search-node', 'search-close', 'info-icon-click'],
});
</script>
@@ -143,8 +159,10 @@ export default defineComponent({
<div class="absolute top-[100%] w-full">
<div v-for="(sugg, idx) of searchSuggs"
:style="{backgroundColor: idx == focusedSuggIdx ? '#a3a3a3' : 'white'}"
- class="bg-white border p-1 hover:underline hover:cursor-pointer"
- @click="resolveSearch(sugg.name)">
+ class="border p-1 hover:underline hover:cursor-pointer" @click="resolveSearch(sugg.name)">
+ <info-icon :style="infoIconStyles"
+ class="float-right text-stone-500 hover:text-stone-900 hover:cursor-pointer"
+ @click.stop="onInfoIconClick(sugg.name)"/>
{{sugg.name == sugg.altName ? sugg.name : `${sugg.altName} (aka ${sugg.name})`}}
</div>
<div v-if="searchHasMoreSuggs" class="bg-white px-1 text-center border">...</div>
diff --git a/src/components/Tile.vue b/src/components/Tile.vue
index ddf2fc0..86770ef 100644
--- a/src/components/Tile.vue
+++ b/src/components/Tile.vue
@@ -315,7 +315,7 @@ export default defineComponent({
this.$emit(this.isLeaf ? 'leaf-click-held' : 'nonleaf-click-held', this.layoutNode);
},
onInfoIconClick(evt: Event){
- this.$emit('info-icon-click', this.layoutNode);
+ this.$emit('info-icon-click', this.layoutNode.name);
},
// Mouse hover handling
onMouseEnter(evt: Event){
@@ -341,8 +341,8 @@ export default defineComponent({
onInnerNonleafClickHeld(node: LayoutNode){
this.$emit('nonleaf-click-held', node);
},
- onInnerInfoIconClick(node: LayoutNode){
- this.$emit('info-icon-click', node);
+ onInnerInfoIconClick(nodeName: string){
+ this.$emit('info-icon-click', nodeName);
},
// Other
onTransitionEnd(evt: Event){
diff --git a/src/components/TileInfoModal.vue b/src/components/TileInfoModal.vue
index 6701f1f..4b904b2 100644
--- a/src/components/TileInfoModal.vue
+++ b/src/components/TileInfoModal.vue
@@ -13,27 +13,25 @@ export default defineComponent({
desc: null as null | string,
fromRedirect: false,
imgInfo: null as null | {eolId: string, sourceUrl: string, license: string, copyrightOwner: string},
+ tolNode: null as null | TolNode,
};
},
props: {
- node: {type: Object as PropType<LayoutNode>, required: true},
+ nodeName: {type: String, required: true},
tolMap: {type: Object as PropType<TolMap>, required: true},
uiOpts: {type: Object, required: true},
},
computed: {
- tolNode(): TolNode {
- return this.tolMap.get(this.node.name)!;
- },
displayName(): string {
- if (this.tolNode.commonName == null){
- return capitalizeWords(this.node.name);
+ if (this.tolNode == null || this.tolNode.commonName == null){
+ return capitalizeWords(this.nodeName);
} else {
- return `${capitalizeWords(this.tolNode.commonName)} (aka ${capitalizeWords(this.node.name)})`;
+ return `${capitalizeWords(this.tolNode.commonName)} (aka ${capitalizeWords(this.nodeName)})`;
}
},
imgStyles(): Record<string,string> {
return {
- backgroundImage: this.tolNode.imgName != null ?
+ backgroundImage: this.tolNode != null && this.tolNode.imgName != null ?
'linear-gradient(to bottom, rgba(0,0,0,0.4), #0000 40%, #0000 60%, rgba(0,0,0,0.4) 100%),' +
'url(\'/img/' + this.tolNode.imgName.replaceAll('\'', '\\\'') + '\')' :
'none',
@@ -55,7 +53,7 @@ export default defineComponent({
created(){
let url = new URL(window.location.href);
url.pathname = '/data/info';
- url.search = '?name=' + encodeURIComponent(this.node.name);
+ url.search = '?name=' + encodeURIComponent(this.nodeName);
fetch(url.toString())
.then(response => response.json())
.then(obj => {
@@ -63,6 +61,7 @@ export default defineComponent({
if (obj.desc != null){
this.desc = obj.desc.text;
this.fromRedirect = obj.desc.fromRedirect;
+ this.tolNode = obj.nodeObj;
}
this.imgInfo = obj.imgInfo;
}
@@ -81,8 +80,9 @@ export default defineComponent({
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}}
- <div v-if="tolNode.children.length > 0">({{tolNode.children.length}} children)</div>
- <div>({{tolNode.tips}} tips)</div>
+ <div v-if="tolNode != null">
+ ({{tolNode.children.length}} children, {{tolNode.tips}} tips)
+ </div>
</h1>
<hr class="mb-4 border-stone-400"/>
<div class="flex">