project-labels-window.vue 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. <template>
  2. <div class="project-labels-window">
  3. <div class="label" v-for="label in labels" :key="label.id">
  4. <h2>
  5. <img alt="delete" src="@/assets/icons/x-circle.svg" @click="removeLabel(label.id)">
  6. {{ label.name }}
  7. </h2>
  8. <media-selector v-if="labeledImages[label.id].length > 0"
  9. :project-id="currentProject.id"
  10. :media="labeledImages[label.id]"
  11. current="-1"
  12. :socket="socket"></media-selector>
  13. <div v-else
  14. class="no-elements">
  15. No labeled images found...
  16. </div>
  17. </div>
  18. <div class="label">
  19. <text-input placeholder="New Label"
  20. v-model="createLabelValue"
  21. @change="createLabel"
  22. @enter="createLabel"/>
  23. </div>
  24. </div>
  25. </template>
  26. <script>
  27. import TextInput from "@/components/base/text-input";
  28. import MediaSelector from "@/components/media/media-selector";
  29. export default {
  30. name: "project-labels-window",
  31. components: {MediaSelector, TextInput},
  32. props: ['currentProject', 'socket'],
  33. data: function () {
  34. return {
  35. createLabelValue: ''
  36. }
  37. },
  38. computed: {
  39. labels: function () {
  40. let labels = Object.keys(this.currentProject.labels)
  41. .map(e => this.currentProject.labels[e]);
  42. labels.sort((a, b) => a.name < b.name ? -1 : +1);
  43. return labels;
  44. },
  45. labeledImages: function () {
  46. const result = {};
  47. for (let label of this.labels)
  48. result[label.id] = [];
  49. for (let image of Object.values(this.currentProject.data)) {
  50. for (let prediction of Object.values(image['predictionResults'])) {
  51. if ('label' in prediction && !result[prediction.label].includes(image)) {
  52. result[prediction.label].push(image);
  53. }
  54. }
  55. }
  56. return result;
  57. }
  58. },
  59. methods: {
  60. createLabel: function (value) {
  61. if (!this.createLabelValue)
  62. return;
  63. this.socket.post('/projects/' + this.currentProject.id + '/labels', {name: value});
  64. this.createLabelValue = '';
  65. },
  66. removeLabel: function (id) {
  67. this.socket.post('/projects/' + this.currentProject.id + '/labels/' + id, {delete: true});
  68. }
  69. }
  70. }
  71. </script>
  72. <style scoped>
  73. .project-labels-window {
  74. padding: 1rem;
  75. }
  76. .label {
  77. margin-bottom: 1rem;
  78. }
  79. h2 {
  80. display: flex;
  81. align-items: center;
  82. margin: 0;
  83. }
  84. img {
  85. width: 1.5rem;
  86. margin-right: 0.75rem;
  87. }
  88. /deep/ .element {
  89. border: none;
  90. }
  91. /deep/ .element:not(:first-child) {
  92. margin-left: 0.1rem;
  93. }
  94. /deep/ .element:not(:last-child) {
  95. margin-right: 0.1rem;
  96. }
  97. .no-elements {
  98. margin-top: 0.5rem;
  99. }
  100. </style>