You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

navigationItem.vue 4.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. <template>
  2. <li :id="item.id" :class="[{'icon-loading-small': item.loading, 'open': item.opened, 'collapsible': item.collapsible&&item.children&&item.children.length>0 }, item.classes]">
  3. <!-- Bullet -->
  4. <div v-if="item.bullet" class="app-navigation-entry-bullet" :style="{ backgroundColor: item.bullet }"></div>
  5. <!-- Main link -->
  6. <a v-if="item.href" :href="(item.href) ? item.href : '#' " @click="toggleCollapse" :class="item.icon" >
  7. <img v-if="item.iconUrl" :alt="item.text" :src="item.iconUrl">
  8. {{item.text}}
  9. </a>
  10. <!-- Router link if specified. href OR router -->
  11. <router-link :to="item.router" v-else-if="item.router" :class="item.icon" >
  12. <img v-if="item.iconUrl" :alt="item.text" :src="item.iconUrl">
  13. {{item.text}}
  14. </router-link>
  15. <!-- Popover, counter and button(s) -->
  16. <div v-if="item.utils" class="app-navigation-entry-utils">
  17. <ul>
  18. <!-- counter -->
  19. <li v-if="Number.isInteger(item.utils.counter)"
  20. class="app-navigation-entry-utils-counter">{{item.utils.counter}}</li>
  21. <!-- first action if only one action and counter -->
  22. <li v-if="item.utils.actions && item.utils.actions.length === 1 && Number.isInteger(item.utils.counter)"
  23. class="app-navigation-entry-utils-menu-button">
  24. <button @click="item.utils.actions[0].action" :class="item.utils.actions[0].icon" :title="item.utils.actions[0].text"></button>
  25. </li>
  26. <!-- second action only two actions and no counter -->
  27. <li v-else-if="item.utils.actions && item.utils.actions.length === 2 && !Number.isInteger(item.utils.counter)"
  28. v-for="action in item.utils.actions" :key="action.action"
  29. class="app-navigation-entry-utils-menu-button">
  30. <button @click="action.action" :class="action.icon" :title="action.text"></button>
  31. </li>
  32. <!-- menu if only at least one action and counter OR two actions and no counter-->
  33. <li v-else-if="item.utils.actions && item.utils.actions.length > 1 && (Number.isInteger(item.utils.counter) || item.utils.actions.length > 2)"
  34. class="app-navigation-entry-utils-menu-button">
  35. <button v-click-outside="hideMenu" @click="showMenu" ></button>
  36. </li>
  37. </ul>
  38. </div>
  39. <!-- if more than 2 actions or more than 1 actions with counter -->
  40. <div v-if="item.utils && item.utils.actions && item.utils.actions.length > 1 && (Number.isInteger(item.utils.counter) || item.utils.actions.length > 2)"
  41. class="app-navigation-entry-menu" :class="{ 'open': openedMenu }">
  42. <popover-menu :menu="item.utils.actions"/>
  43. </div>
  44. <!-- undo entry -->
  45. <div class="app-navigation-entry-deleted" v-if="item.undo">
  46. <div class="app-navigation-entry-deleted-description">{{item.undo.text}}</div>
  47. <button class="app-navigation-entry-deleted-button icon-history" :title="t('settings', 'Undo')"></button>
  48. </div>
  49. <!-- edit entry -->
  50. <div class="app-navigation-entry-edit" v-if="item.edit">
  51. <form>
  52. <input type="text" v-model="item.text">
  53. <input type="submit" value="" class="icon-confirm">
  54. <input type="submit" value="" class="icon-close" @click.stop.prevent="cancelEdit">
  55. </form>
  56. </div>
  57. <!-- if the item has children, inject the component with proper data -->
  58. <ul v-if="item.children">
  59. <navigation-item v-for="(item, key) in item.children" :item="item" :key="key" />
  60. </ul>
  61. </li>
  62. </template>
  63. <script>
  64. import popoverMenu from '../popoverMenu';
  65. import ClickOutside from 'vue-click-outside';
  66. import Vue from 'vue';
  67. export default {
  68. name: 'navigationItem',
  69. props: ['item'],
  70. components: {
  71. popoverMenu
  72. },
  73. directives: {
  74. ClickOutside
  75. },
  76. data() {
  77. return {
  78. openedMenu: false
  79. }
  80. },
  81. methods: {
  82. showMenu() {
  83. this.openedMenu = true;
  84. },
  85. hideMenu() {
  86. this.openedMenu = false;
  87. },
  88. toggleCollapse() {
  89. // if item.opened isn't set, Vue won't trigger view updates https://vuejs.org/v2/api/#Vue-set
  90. // ternary is here to detect the undefined state of item.opened
  91. Vue.set(this.item, 'opened', this.item.opened ? !this.item.opened : true);
  92. },
  93. cancelEdit() {
  94. // remove the editing class
  95. if (Array.isArray(this.item.classes))
  96. this.item.classes = this.item.classes.filter(item => item !== 'editing');
  97. }
  98. },
  99. mounted() {
  100. // prevent click outside event with popupItem.
  101. this.popupItem = this.$el;
  102. },
  103. }
  104. </script>