Show the rule info popup when clicking on a chapter section.

master
Pacman Ghost 3 years ago
parent 504fdd8138
commit f9808d2070
  1. 120
      asl_rulebook2/webapp/static/NavPane.js
  2. 60
      asl_rulebook2/webapp/static/RuleInfo.js
  3. 3
      asl_rulebook2/webapp/static/css/NavPane.css
  4. 2
      asl_rulebook2/webapp/static/css/TabbedPages.css

@ -1,70 +1,43 @@
import { gMainApp, gAppConfig, gContentDocs, gEventBus, gUrlParams } from "./MainApp.js" ;
import { gMainApp, gAppConfig, gContentDocs, gEventBus } from "./MainApp.js" ;
import { showWarningMsg } from "./utils.js" ;
// --------------------------------------------------------------------
gMainApp.component( "nav-pane", {
template: `
<tabbed-pages>
<tabbed-page tabId="search" caption="Search" >
<nav-pane-search />
</tabbed-page>
<tabbed-page tabId="chapters" caption="Chapters" >
<nav-pane-chapters />
</tabbed-page>
</tabbed-pages>`,
} ) ;
// --------------------------------------------------------------------
gMainApp.component( "nav-pane-search", {
data() { return {
ruleInfo: [],
seqNo: 0, // nb: for the test suite
closeRuleInfoImageUrl: gImagesBaseUrl + "cross.png", //eslint-disable-line no-undef
ruleInfoTransitionName: gUrlParams.get("no-animations") ? "" : "ruleinfo-slide",
} ; },
template: `
<search-box id="search-box" @search=onSearch />
<search-results :data-seqno=seqNo id="search-results" />
<!-- FUDGE! We want the "close" button to stay in the top-right corner of the rule info popup.
If we put it inside the <rule-info> element with an absolute position, it scrolls with the content,
so we place it outside the <rule-info> element, with an absolute position, and a larger z-index.
It doesn't look so good when the v-scrollbar appears, but we can live with that.
-->
<transition :name=ruleInfoTransitionName @after-enter=onAfterEnterRuleInfoTransition >
<div v-show="ruleInfo.length > 0" >
<img :src=closeRuleInfoImageUrl @click=closeRuleInfo ref="closeRuleInfoButton"
title="Close the rule info" class="close-rule-info"
/>
<rule-info :ruleInfo=ruleInfo ref="rule-info" />
</div>
</transition>
`,
<div>
<tabbed-pages>
<tabbed-page tabId="search" caption="Search" >
<nav-pane-search />
</tabbed-page>
<tabbed-page tabId="chapters" caption="Chapters" >
<nav-pane-chapters />
</tabbed-page>
</tabbed-pages>
<rule-info :ruleInfo=ruleInfo @close=closeRuleInfo />
</div>`,
created() {
// notify the test suite that the search results are now available
gEventBus.on( "search-done", () => {
this.seqNo += 1 ;
} ) ;
// show any Q+A when a target is opened
// show any Q+A and annotations when a target is opened
gEventBus.on( "show-target", (cdocId, target) => {
if ( gAppConfig.DISABLE_AUTO_SHOW_RULE_INFO )
return ;
// get the Q+A and annotations for the target being opened
// get the rule info for the target being opened
// NOTE: Targets are associated with a content doc, but the Q+A is global, which is not quite
// the right thing to do - what if there is a ruleid that is the same multiple content docs,
// but is referenced in the Q+A? Hopefully, this will never happen... :-/
let url = gGetRuleInfoUrl.replace( "RULEID", target ) ; //eslint-disable-line no-undef
$.getJSON( url, (resp) => {
if ( resp.length > 0 )
this.showRuleInfo( resp ) ;
if ( resp.length > 0 ) {
// install the rule info entries
this.ruleInfo = resp ;
}
} ).fail( (xhr, status, errorMsg) => {
showWarningMsg( "Couldn't get the Q+A for " + target + ". <div class='pre'>" + errorMsg + "</div>" ) ;
} ) ;
@ -75,41 +48,44 @@ gMainApp.component( "nav-pane-search", {
},
methods: {
closeRuleInfo() {
// close the rule info popup
this.ruleInfo = [] ;
},
},
} ) ;
// --------------------------------------------------------------------
gMainApp.component( "nav-pane-search", {
data() { return {
seqNo: 0, // nb: for the test suite
} ; },
template: `
<search-box id="search-box" @search=onSearch />
<search-results :data-seqno=seqNo id="search-results" />
`,
created() {
// notify the test suite that the search results are now available
gEventBus.on( "search-done", () => {
this.seqNo += 1 ;
} ) ;
},
methods: {
onSearch( queryString ) {
// run the search (handled elsewhere)
if ( this.ruleInfo.length > 0 )
if ( $("#rule-info").css( "display" ) != "none" )
return ; // nb: dont respond to key-presses if the rule info popup is open
gEventBus.emit( "search", queryString ) ;
},
showRuleInfo( ruleInfo ) {
// install the rule info entries
this.ruleInfo = ruleInfo ;
$( this.$refs.closeRuleInfoButton ).hide() ;
},
closeRuleInfo() {
// close the rule info popup
this.ruleInfo = [] ;
},
onAfterEnterRuleInfoTransition() {
// FUDGE! We have to wait until the rule info popup is open before we can check
// if it has a v-scrollbar or not, and hence where we should put the close button.
this.$nextTick( () => {
let ruleInfo = this.$refs[ "rule-info" ].$el ;
let closeButton = this.$refs.closeRuleInfoButton ;
if ( ruleInfo.clientHeight >= ruleInfo.scrollHeight )
$(closeButton).css( "right", "6px" ) ;
else {
// FUDGE! The v-scrollbar is visible, so we move the "close" button left a bit.
// This adjustment won't update if the pane is resized, but we can live with that.
$(closeButton).css( "right", "18px" ) ;
}
$(closeButton).fadeIn( 200 ) ;
} ) ;
},
},
} ) ;

@ -1,4 +1,4 @@
import { gMainApp } from "./MainApp.js" ;
import { gMainApp, gUrlParams } from "./MainApp.js" ;
import { makeImagesZoomable } from "./utils.js" ;
// --------------------------------------------------------------------
@ -6,17 +6,61 @@ import { makeImagesZoomable } from "./utils.js" ;
gMainApp.component( "rule-info", {
props: [ "ruleInfo" ],
data() { return {
closeRuleInfoImageUrl: gImagesBaseUrl + "cross.png", //eslint-disable-line no-undef
ruleInfoTransitionName: gUrlParams.get("no-animations") ? "" : "ruleinfo-slide",
} ; },
// FUDGE! We want the "close" button to stay in the top-right corner of the rule info popup as the user
// scrolls around. If we put it in together with the content itself, with an absolute position, it scrolls
// with the content, so we place it outside the content, with an absolute position, and a larger z-index.
// It doesn't look so good when the v-scrollbar appears, but we can live with that.
template: `
<div id="rule-info">
<div v-for="ri in ruleInfo" :key=ri >
<annotation v-if="ri.ri_type == 'errata'" :anno=ri />
<annotation v-else-if="ri.ri_type == 'user-anno'" :anno=ri />
<qa-entry v-else-if="ri.ri_type == 'qa'" :qaEntry=ri />
<div v-else> ???:{{ri.ri_type}} </div>
</div>
<div>
<img :src=closeRuleInfoImageUrl style="display:none;"
@click="$emit('close')" ref="closeRuleInfoButton"
title="Close the rule info" class="close-rule-info"
/>
<transition :name=ruleInfoTransitionName @after-enter=onAfterEnterRuleInfoTransition >
<div v-show="ruleInfo.length > 0" id="rule-info" ref="ruleInfo" >
<div class="content" ref="content">
<div v-for="ri in ruleInfo" :key=ri >
<annotation v-if="ri.ri_type == 'errata'" :anno=ri />
<annotation v-else-if="ri.ri_type == 'user-anno'" :anno=ri />
<qa-entry v-else-if="ri.ri_type == 'qa'" :qaEntry=ri />
<div v-else> ???:{{ri.ri_type}} </div>
</div>
</div>
</div>
</transition>
</div>`,
beforeUpdate() {
// hide the close button until the "enter" transition has completed
$( this.$refs.closeRuleInfoButton ).hide() ;
},
methods: {
onAfterEnterRuleInfoTransition() {
// FUDGE! We have to wait until the rule info popup is open before we can check
// if it has a v-scrollbar or not, and hence where we should put the close button.
this.$nextTick( () => {
let ruleInfo = this.$refs.ruleInfo ;
let closeButton = this.$refs.closeRuleInfoButton ;
if ( ruleInfo.clientHeight >= ruleInfo.scrollHeight )
$(closeButton).css( "right", "6px" ) ;
else {
// FUDGE! The v-scrollbar is visible, so we move the "close" button left a bit.
// This adjustment won't update if the pane is resized, but we can live with that.
$(closeButton).css( "right", "18px" ) ;
}
$(closeButton).fadeIn( 200 ) ;
} ) ;
},
},
} ) ;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

@ -1,5 +1,4 @@
#nav { margin: 0 5px ; }
#nav { margin: 0 5px ; position: relative ; }
#nav .no-chapters { font-style: italic ; color: #888 ; }
#nav .wrapper { position: relative ; }
#nav .tab-strip { border-top: 1px solid #aaa ; padding: 5px 5px ; }

@ -1,4 +1,4 @@
.tabbed-pages { display: flex ; flex-direction: column ; }
.tabbed-pages { display: flex ; flex-direction: column ; height: 100% ; }
.tabbed-pages .tabbed-page { height: calc(100% - 35px) ; display: flex ; flex-direction: column ; }
.tabbed-pages .tabbed-page .wrapper { flex-grow: 1 ; margin: 5px 0 2px 0 ; height: calc(100% - 10px) ; overflow-y: auto ; }
.tabbed-pages .tab-strip { height: 24px ; display: flex ; font-size: 10pt ; font-style: italic ; }

Loading…
Cancel
Save