Title: サイドバーの「新しい〜」メニューをスペースごとに表示/非表示するには
DocSDK137: サイドバーの「新しい〜」メニューに独自の項目を追加するには では、サイドバーのドロップダウン式の「新しい〜」追加メニューに新しい項目を追加する方法を解説しました。ここでは、更に手を加えて、特定のスペースでのみ「新しい〜」追加メニューが表示されるようにしてみます。
既存の追加メニューの確認
ドロップダウン式メニュー
サイドバーの「新しい〜」ドロップダウン メニューは、com/traction/sdl/gwtrpc の shared.sdl の「addmenu」関数で作られています。
<sdl.function name="addmenu">
<variable.local.set name="firstOption" value="<#addmenu-firstoption />" />
<gwt.rpc.view name="AddMenu">
<#addmenu-options />
</gwt.rpc.view>
</sdl.function>
メニューの項目
メニューの中に表示される「新しいタスク」や「新しい予定」などの項目は、上記の「addmenu」関数から参照されている「addmenu-options」関数で作られています。「addmenu-task」や「addmenu-event」など、更に各メニュー項目用の別の関数が参照されています。
<sdl.function name="addmenu-options">
<#addmenu-newentry />
<#addmenu-task />
<#addmenu-event />
<#addmenu-milestone />
<#addmenu-goal />
</sdl.function>
これらの関数への参照をスペースごとに制御することで、メニュー項目を表示/非表示できます。
特定のスペースにいるかどうかの判断
TeamPage をマンションに例えると、スペースは部屋に当たります。TeamPage というマンションに入った(ログインした)ユーザーが現在どこにいるのかは、画面の左上の見出しで判断できます。
例えば、「すべてのスペース」と表示されているときは、まだ玄関にいるようなものです。どの部屋(スペース)にも入っていません。ユーザーのプロフィールページが表示されているときも同様です。これに対して、特定のスペースの表示名が表示されているときは、特定の部屋(スペース)に入っている状態です。
サイドバーの「新しい〜」の表示をスペースで表示したり非表示にしたりするには、ユーザーが「どの部屋に入っているのか」を判別する必要があります。
journalrequest.project.*
その判別を SDL で行うには、<journalrequest.project.*>
タグを使います。
sdl ファイルの中で、例えば <journalrequest.project.name>
を実行すると、実行された位置のスペース名が返されます。(例: スペースのダッシュボードを作成する dashboard.sdl の中で <journalrequest.project.name>
を実行すると、そのスペースの名前が返ってきます。)
- journalrequest.projet.name ... スペースの「名前」
- journalrequest.project.displayname ... スペースの「表示名」
- journalrequest.project.id ... スペースの ID 番号(スペースセットアップの左上に括弧付きで表示される番号)
読み取りできる最初のスペース問題
しかし、この <journalrequest.project.*>
タグは、どのスペースにも入っていない状態の場合、「読み取り権限のある最初の(文字コード順に並べたときの先頭の)スペース」が返される仕様になっています。
例えば、フロントページやユーザー プロフィール ページを表示する SDL で <journalrequest.project.name>
を実行すると、null が返されるのではなく、実行したユーザーの読み取り権限のある「名前順で最初のスペース」の名前が返されます。
これは TeamPage 開発の歴史的な理由による制限事項です。
これでは「名前順で最初のスペース」の中にいるのか外にいるのかが判別できません。
特定の1つのスペースにいるかどうかの判別
この判別の参考になるのが、com/traction/sdl/gtwrpc にある tabs.sdl の「main」関数です。
<sdl.function name="main">
<and "<journalrequest.singleproject />"
"<journalrequest.includesallprojects not />">
<#main-singleproject />
<else>
<journalrequest.includesallprojects>
<#main-allprojects />
<else>
<#main-multiproject />
</journalrequest.includesallprojects>
</and>
</sdl.function>
次の 2 つのタグにより、「いずれか 1 つのスペースの中にいるのか」「すべてのスペースを含む場所(=どのスペースにも入っていない場所)にいるのか」を判別し、その組み合わせにより、「名前順で最初のスペースにいるのではなく、どのスペースにも入っていない場所にいるのか」を正確に判断できます。
- journalrequest.singleproject ... いずれか 1 つのスペースの中にいる場合は true を返す。
- journalrequest.includesallprojects ... すべてのスペースを含む場所(=どのスペースにも入っていない場所)にいる場合は true を返す。
追加メニュー項目の表示/非表示カスタマイズ
それでは、このコードを利用して、サイドバーの「新しい〜」メニューの項目が特定のスペースの場合に表示/非表示されるようにカスタマイズしてみましょう。
tabs#main 借用
tabs.sdl の「main」関数を shared.sdl の中へ「current-project-position」という関数名でコピーします。(tabs.sdl の「main」関数をコピーし、shared.sdl の適当な場所へ貼り付け、関数名を「current-project-position」に変更します。)
<sdl.function name="current-project-position">
<and "<journalrequest.singleproject />"
"<journalrequest.includesallprojects not />">
__journalrequest.project.name__
<else>
<journalrequest.includesallprojects>
*AllProjects*
<else>
*MultipleProjects*
</journalrequest.includesallprojects>
</and>
</sdl.function>
どこか特定の 1 つのスペースに入っている場合、<journalrequest.project.name>
タグにより(「__journalrequest.project.name__
」という表記法を使っています)そのスペースの名前を返します。どこか 1 つのスペースに入っていない場合は、「*AllProjects*」か「*MultiProjects*」を返します。
特定のスペースでのみ「新しいタスク」を表示する
コード
ここでは例として、「新しいタスク」メニュー項目を「Sandbox」スペースでだけ表示するようにしてみます。
「新しいタスク」メニュー項目を表示するコードは、com/traction/sdl/gwtrpc の shared.sdl の「addmenu-task」関数です。
<sdl.function name="addmenu-task">
<#addmenu-action actionName="NewTask" actionKey="task">
</sdl.function>
「〜かどうかの判断」いわゆる「if 条件」の判別をするには <compare.equals>...</compare.equals>
タグを使います。このタグの間に「addmenu-task」の内容を挟み込み、「current-project-position」関数の返り値が「Sandbox」かどうか調べる、というパラメーターを追加します。
<sdl.function name="addmenu-task">
<!-- current-project-position の返り値をが「Sandbox」だったら
「NewTask」の addmenu-action を実行する -->
<compare.equals "<#current-project-position />" "Sandbox">
<#addmenu-action actionName="NewTask" actionKey="task">
</compare.equals>
</sdl.function>
これにより、特定の「Sandbox」スペースの中でだけサイドバーに「新しいタスク」が表示される、という動作を実現できます。
動作確認
「すべてのスペース」やユーザーのプロフィール ページ、「Sandbox」以外のスペースでは、ドロップダウン追加メニューの [新しいタスク] は表示されません。
「Sandbox」スペースに移動すると、[新しいタスク] メニューが表示されます。
特定のスペースで「新しい予定」を隠す(非表示にする)
コード
ここでは、上記の逆の例として、「新しいタスク」メニュー項目を「Sandbox」スペースでだけ隠す=「Sandbox」スペース以外で表示するようにしてみます。
上記では <compare.equals "A" "B">...</compare.equals>
を使って「A と B とが合致したら」という条件判断をしましたが、今回は <compare.equals>
タグに not
属性を追加して「A と B とが合致しなかったら」という条件判断をします。
<sdl.function name="addmenu-task">
<!-- current-project-position の返り値をが「Sandbox」ではなかったら
「NewTask」の addmenu-action を実行する -->
<compare.equals "<#current-project-position />" "Sandbox" not>
<#addmenu-action actionName="NewTask" actionKey="task">
</compare.equals>
</sdl.function>
動作確認
「すべてのスペース」や「Design」スペースでは、ドロップダウン式メニューに [新しいタスク] が表示されます。
「Sandbox」スペースでは、[新しいタスク] メニューは表示されません。