side-navigation-bar.vue 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. <template>
  2. <div class="side-navigation"
  3. :class="{
  4. wide: window.wide,
  5. narrow: !window.wide,
  6. active: window.menu ,
  7. collapsed: collapsed
  8. }">
  9. <div class="items">
  10. <div class="item"
  11. :class="{active: window.content === 'projects'}"
  12. @click="show('projects')">
  13. <img src="@/assets/icons/rocket.svg">
  14. <span>Projects</span>
  15. </div>
  16. <div class="item"
  17. :class="{active: window.content === 'settings', inactive: !currentProject}"
  18. @click="ifProjectIsOpened(show, 'settings')">
  19. <img src="@/assets/icons/gear.svg">
  20. <span>Settings</span>
  21. </div>
  22. <div class="item"
  23. :class="{active: window.content === 'add_data', inactive: !currentProject}"
  24. @click="ifProjectIsOpened(show, 'add_data')">
  25. <img src="@/assets/icons/package-dependencies.svg">
  26. <span>Add Data</span>
  27. </div>
  28. <div class="item"
  29. :class="{active: window.content === 'view_data', inactive: !currentProject || !mediaAvailable}"
  30. @click="ifProjectIsOpened(show, 'view_data')">
  31. <img src="@/assets/icons/file-media.svg">
  32. <span>View Data</span>
  33. </div>
  34. <div class="item"
  35. :class="{active: window.content === 'about'}"
  36. @click="show('about')">
  37. <img src="@/assets/icons/info.svg">
  38. <span>About PyCS</span>
  39. </div>
  40. <div v-if="window.wide"
  41. class="item"
  42. :class="{rotate: !collapsed}"
  43. @click="collapse">
  44. <img src="@/assets/icons/paper-airplane.svg">
  45. <span>Collapse</span>
  46. </div>
  47. </div>
  48. <!-- clickable overlay -->
  49. <div class="overlay"
  50. v-if="!window.wide"
  51. @click="closeSelf"/>
  52. </div>
  53. </template>
  54. <script>
  55. export default {
  56. name: "side-navigation-bar",
  57. props: ['window', 'socket', 'status', 'currentProject'],
  58. computed: {
  59. collapsed: function() {
  60. if (!this.status)
  61. return false;
  62. return this.status.settings.frontend.collapse;
  63. },
  64. mediaAvailable: function() {
  65. return this.currentProject && 'data' in this.currentProject && Object.keys(this.currentProject.data).length > 0;
  66. }
  67. },
  68. methods: {
  69. closeSelf: function() {
  70. this.$emit('close', null);
  71. },
  72. ifProjectIsOpened: function(fun, ...args) {
  73. if (this.currentProject)
  74. fun.bind(fun)(...args);
  75. },
  76. show: function(value) {
  77. this.window.content = value;
  78. this.closeSelf();
  79. },
  80. collapse: function() {
  81. this.socket.post('/settings', {
  82. frontend: {
  83. collapse: !this.collapsed
  84. }
  85. });
  86. // TODO then / error
  87. }
  88. }
  89. }
  90. </script>
  91. <style scoped>
  92. .side-navigation {
  93. color: whitesmoke;
  94. }
  95. .side-navigation.wide {
  96. flex-grow: 0;
  97. height: 100%;
  98. }
  99. .side-navigation.narrow {
  100. width: 100vw;
  101. left: -100vw;
  102. position: absolute;
  103. top: 0;
  104. bottom: 0;
  105. transition: 0.2s ease-out;
  106. display: flex;
  107. z-index: 1000;
  108. }
  109. .side-navigation.narrow.active {
  110. left: 0;
  111. }
  112. .items {
  113. flex-grow: 0;
  114. height: 100%;
  115. background-color: #2f2f2f;
  116. min-width: 66%;
  117. }
  118. .item {
  119. cursor: pointer;
  120. white-space: nowrap;
  121. display: flex;
  122. align-items: center;
  123. }
  124. .item:hover:not(.inactive) {
  125. background-color: #292929;
  126. }
  127. .item.active:not(.inactive) {
  128. background-color: #1f1f1f;
  129. }
  130. .item.inactive {
  131. color: #7f7f7f;
  132. }
  133. .item:not(:last-child) {
  134. border-bottom: 1px solid rgba(255, 255, 255, 0.25);
  135. }
  136. .item img {
  137. width: 1.2rem;
  138. margin-left: 1rem;
  139. filter: invert(1);
  140. }
  141. .item.rotate img {
  142. transform: rotate(180deg);
  143. }
  144. .item.inactive img {
  145. opacity: 0.5;
  146. }
  147. .item span {
  148. margin: 1rem 4rem 1rem 0.75rem
  149. }
  150. .side-navigation.wide.collapsed .item {
  151. padding: 1rem 1rem 1rem 0;
  152. }
  153. .side-navigation.wide.collapsed .item span {
  154. display: none;
  155. }
  156. .overlay {
  157. flex-grow: 1;
  158. }
  159. </style>