App.vue 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. <template>
  2. <div id="app">
  3. <!-- loading screen -->
  4. <loading-overlay v-if="!connected"/>
  5. <!-- top navigation bar -->
  6. <top-navigation-bar :window="window"
  7. :current-project="currentProject"
  8. v-on:side="window.menu = !window.menu"></top-navigation-bar>
  9. <!-- bottom content -->
  10. <div class="bottom">
  11. <!-- side navigation bar -->
  12. <side-navigation-bar :window="window"
  13. :socket="socket"
  14. :status="status"
  15. :current-project="currentProject"
  16. v-on:close="window.menu = false"/>
  17. <!-- actual content -->
  18. <div class="content">
  19. <project-open-window v-if="window.content === 'projects'"
  20. :projects="projects"
  21. :status="status"
  22. :socket="socket"
  23. :window="window"
  24. v-on:open="openProject"/>
  25. <project-settings-window v-if="window.content === 'settings'"
  26. :current-project="currentProject"
  27. :status="status"
  28. :socket="socket"
  29. v-on:close="closeProject"/>
  30. <project-data-add-window v-if="window.content === 'add_data'"
  31. :current-project="currentProject"
  32. :socket="socket"/>
  33. <project-labels-window v-if="window.content === 'labels'"
  34. :current-project="currentProject"
  35. :socket="socket"/>
  36. <project-data-view-window v-if="window.content === 'view_data'"
  37. :current-project="currentProject"
  38. :status="status"
  39. :socket="socket"/>
  40. <project-model-interaction-window v-if="window.content === 'model_interaction'"
  41. :current-project="currentProject"
  42. :socket="socket"/>
  43. <about-window v-if="window.content === 'about'"/>
  44. </div>
  45. </div>
  46. </div>
  47. </template>
  48. <script>
  49. import io from "socket.io-client";
  50. import ProjectOpenWindow from "@/components/projects/project-open-window";
  51. import TopNavigationBar from "@/components/window/top-navigation-bar";
  52. import SideNavigationBar from "@/components/window/side-navigation-bar";
  53. import ProjectSettingsWindow from "@/components/projects/project-settings-window";
  54. import AboutWindow from "@/components/other/about-window";
  55. import ProjectDataAddWindow from "@/components/projects/project-data-add-window";
  56. import ProjectDataViewWindow from "@/components/projects/project-data-view-window";
  57. import LoadingOverlay from "@/components/other/loading-overlay";
  58. import ProjectLabelsWindow from "@/components/projects/project-labels-window";
  59. import ProjectModelInteractionWindow from "@/components/projects/project-model-interaction-window";
  60. export default {
  61. name: 'App',
  62. components: {
  63. ProjectModelInteractionWindow,
  64. ProjectLabelsWindow,
  65. LoadingOverlay,
  66. ProjectDataAddWindow,
  67. ProjectDataViewWindow,
  68. AboutWindow,
  69. ProjectSettingsWindow,
  70. SideNavigationBar,
  71. TopNavigationBar,
  72. ProjectOpenWindow
  73. },
  74. data: function () {
  75. return {
  76. connected: false,
  77. socket: {
  78. baseurl: window.location.protocol + '//' + window.location.hostname + ':5000',
  79. // initialize socket.io connection
  80. io: io(window.location.protocol + '//' + window.location.hostname + ':5000'),
  81. // http methods
  82. post: function (name, value) {
  83. if (!name.startsWith('http'))
  84. name = this.baseurl + name;
  85. return fetch(name, {
  86. method: 'POST',
  87. body: JSON.stringify(value)
  88. });
  89. },
  90. upload: function (name, file) {
  91. const form = new FormData();
  92. form.append('file', file);
  93. return fetch(this.baseurl + name, {
  94. method: 'POST',
  95. body: form
  96. });
  97. },
  98. media: function (projectId, fileId) {
  99. return this.baseurl + '/projects/' + projectId + '/data/' + fileId;
  100. }
  101. },
  102. status: null,
  103. window: {
  104. wide: true,
  105. menu: false,
  106. content: 'projects',
  107. project: null
  108. }
  109. }
  110. },
  111. computed: {
  112. projects: function () {
  113. if (this.status == null)
  114. return [];
  115. return Object.keys(this.status.projects).map(key => this.status.projects[key]);
  116. },
  117. currentProject: function () {
  118. for (let i = 0; i < this.projects.length; i++)
  119. if (this.projects[i].id === this.window.project)
  120. return this.projects[i];
  121. return false;
  122. }
  123. },
  124. methods: {
  125. resize: function () {
  126. this.window.wide = (document.body.offsetWidth > 1024);
  127. },
  128. show: function (value) {
  129. this.window.content = value;
  130. },
  131. openProject: function (project) {
  132. this.window.project = project.id;
  133. this.show('settings');
  134. },
  135. closeProject: function () {
  136. this.window.project = null;
  137. this.show('projects');
  138. }
  139. },
  140. created: function () {
  141. this.socket.io.on('app_status', data => {
  142. if (data.keys.length === 0) {
  143. this.status = data.value;
  144. this.connected = true;
  145. return;
  146. }
  147. const last = data.keys.pop();
  148. let target = this.status;
  149. for (let key of data.keys) {
  150. target = target[key];
  151. }
  152. target[last] = data.value;
  153. });
  154. setInterval(() => this.connected = this.socket.io.connected, 2000);
  155. window.addEventListener('resize', this.resize);
  156. this.resize();
  157. },
  158. destroyed: function () {
  159. window.removeEventListener('resize', this.resize);
  160. }
  161. }
  162. </script>
  163. <style scoped>
  164. #app {
  165. width: 100%;
  166. height: 100%;
  167. display: flex;
  168. flex-direction: column;
  169. }
  170. .bottom {
  171. display: flex;
  172. flex-grow: 1;
  173. flex-direction: row;
  174. width: 100%;
  175. position: relative;
  176. }
  177. .content {
  178. flex-grow: 1;
  179. overflow: hidden;
  180. }
  181. .content > * {
  182. width: 100%;
  183. height: 100%;
  184. }
  185. </style>