project-creation-window.vue 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. <template>
  2. <div class="project-creation-window">
  3. <h1 class="title">Create Project</h1>
  4. <div class="content">
  5. <text-input placeholder="Name"
  6. v-model="name"
  7. :error="nameError"
  8. @clearError="nameError = false">
  9. Name
  10. </text-input>
  11. <textarea-input placeholder="Description"
  12. v-model="description"
  13. :error="descriptionError"
  14. @clearError="descriptionError = false">
  15. Description
  16. </textarea-input>
  17. <select-input :values="models"
  18. v-model="model">
  19. Model
  20. </select-input>
  21. <div class="features">
  22. This model supports:
  23. <ul>
  24. <li v-for="(feature, key) in current.supports"
  25. v-bind:key="key">
  26. {{ feature }}
  27. </li>
  28. </ul>
  29. </div>
  30. </div>
  31. <button-row class="footer">
  32. <button-input @click="create" type="primary">
  33. Create Project
  34. </button-input>
  35. <button-input @click="$emit('cancel', null)">
  36. Cancel
  37. </button-input>
  38. </button-row>
  39. </div>
  40. </template>
  41. <script>
  42. import TextInput from "@/components/base/text-input";
  43. import TextareaInput from "@/components/base/textarea-input";
  44. import SelectInput from "@/components/base/select-input";
  45. import ButtonInput from "@/components/base/button-input";
  46. import ButtonRow from "@/components/base/button-row";
  47. export default {
  48. name: "project-creation-window",
  49. components: {ButtonRow, ButtonInput, SelectInput, TextareaInput, TextInput},
  50. props: ['status', 'socket'],
  51. data: function () {
  52. return {
  53. name: '',
  54. nameError: false,
  55. description: '',
  56. descriptionError: false,
  57. model: null
  58. }
  59. },
  60. computed: {
  61. models: function () {
  62. const supported = {
  63. 'bounding-boxes': 'bounding boxes',
  64. 'labeled-bounding-boxes': 'labeled bounding boxes',
  65. 'labeled-images': 'labeled images',
  66. };
  67. let result = [];
  68. for (let o in this.status.models) {
  69. result.push({
  70. 'id': this.status.models[o].id,
  71. 'name': this.status.models[o].name,
  72. 'value': this.status.models[o].id,
  73. 'supports': this.status.models[o].supports
  74. .map(k => k in supported ? supported[k] : 'unknown feature')
  75. }
  76. );
  77. }
  78. return result;
  79. },
  80. current: function () {
  81. for (let model of this.models) {
  82. if (model.id === this.model) {
  83. return model;
  84. }
  85. }
  86. return false;
  87. }
  88. },
  89. created: function () {
  90. this.model = this.models[0].value;
  91. },
  92. methods: {
  93. create: function () {
  94. this.nameError = !this.name;
  95. this.descriptionError = !this.description;
  96. if (this.nameError || this.descriptionError)
  97. return;
  98. // TODO then / error
  99. this.socket.post('/projects', {
  100. name: this.name,
  101. description: this.description,
  102. model: this.model
  103. });
  104. this.$emit('cancel', null);
  105. }
  106. }
  107. }
  108. </script>
  109. <style scoped>
  110. .project-creation-window {
  111. display: flex;
  112. flex-direction: column;
  113. }
  114. .title {
  115. margin: 0;
  116. padding: 2rem;
  117. border-bottom: 1px solid rgba(0, 0, 0, 0.2);
  118. flex-grow: 0;
  119. display: flex;
  120. }
  121. .content {
  122. overflow: auto;
  123. padding: 1rem;
  124. flex-grow: 1;
  125. }
  126. .content > * {
  127. margin-bottom: 0.6rem;
  128. }
  129. /deep/ .content textarea {
  130. height: 4rem;
  131. }
  132. .features {
  133. font-size: 80%;
  134. }
  135. .features ul {
  136. margin-top: 0.4rem;
  137. }
  138. .footer {
  139. flex-grow: 0;
  140. padding: 2rem;
  141. display: flex;
  142. flex-direction: row;
  143. justify-content: flex-end;
  144. }
  145. </style>