6
0

project-data-add-window.vue 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. <template>
  2. <div class="project-data-add-window">
  3. <!-- TODO use valid url -->
  4. <file-input :socket="socket" :name="'/projects/' + currentProject.id + '/data'"></file-input>
  5. <template v-if="uploads.length > 0">
  6. <h1>Uploads</h1>
  7. <div class="uploads">
  8. <template v-for="up in uploads">
  9. <div :key="up.id + '-div'">{{ up.filename }}</div>
  10. <progress-bar :key="up.id + '-progress'" :progress="up.progress"></progress-bar>
  11. </template>
  12. </div>
  13. </template>
  14. <template v-if="this.data.length > 0">
  15. <h1>Data</h1>
  16. <div class="wrapper">
  17. <div class="data">
  18. <div v-for="d in this.data"
  19. v-bind:key="d.id"
  20. class="element">
  21. <img alt="media" class="media"
  22. :src="d.src"
  23. :srcset="d.srcset" :sizes="d.sizes">
  24. <img alt="remove" class="remove"
  25. @click="removeMedia(d.src)"
  26. src="@/assets/icons/x-circle.svg">
  27. </div>
  28. </div>
  29. </div>
  30. </template>
  31. </div>
  32. </template>
  33. <script>
  34. import FileInput from "@/components/base/file-input";
  35. import ProgressBar from "@/components/base/progress-bar";
  36. export default {
  37. name: "project-data-add-window",
  38. components: {ProgressBar, FileInput},
  39. props: ['socket', 'currentProject'],
  40. data: function () {
  41. return {
  42. sizes: [400, 700, 1000]
  43. }
  44. },
  45. computed: {
  46. uploads: function () {
  47. const filtered = Object.keys(this.currentProject.jobs)
  48. .map(e => this.currentProject.jobs[e])
  49. .filter(e => e.type === 'upload');
  50. filtered.sort(this.sortUploads);
  51. return filtered;
  52. },
  53. data: function () {
  54. return Object.keys(this.currentProject.data).map(key => {
  55. const data = this.currentProject.data[key];
  56. const src = this.socket.media(this.currentProject.id, data.id);
  57. return Object.assign({
  58. src: src,
  59. srcset: this.sizes.map(e => src + '/' + e + ' ' + e + 'w').join(','),
  60. sizes: '10rem'
  61. }, data);
  62. });
  63. }
  64. },
  65. methods: {
  66. sortUploads: function (u, v) {
  67. if (u.created < v.created)
  68. return 1;
  69. else
  70. return -1;
  71. },
  72. removeMedia: function (src) {
  73. this.socket.post(src, {delete: true})
  74. }
  75. }
  76. }
  77. </script>
  78. <style scoped>
  79. .project-data-add-window {
  80. padding: 1rem;
  81. display: flex;
  82. flex-direction: column;
  83. }
  84. h1 {
  85. margin-bottom: 1rem;
  86. }
  87. .uploads {
  88. display: grid;
  89. grid-template-columns: auto 1fr;
  90. }
  91. .progress-bar {
  92. margin-left: 1rem;
  93. }
  94. .wrapper {
  95. flex-basis: 0;
  96. flex-grow: 1;
  97. overflow-y: auto;
  98. }
  99. .data {
  100. display: grid;
  101. grid-template-columns: repeat(auto-fill, 10rem);
  102. }
  103. .element {
  104. display: flex;
  105. justify-content: center;
  106. align-items: center;
  107. position: relative;
  108. }
  109. .media {
  110. max-height: 7rem;
  111. }
  112. .remove {
  113. position: absolute;
  114. top: 0.2rem;
  115. right: 0.2rem;
  116. background-color: rgba(255, 255, 255, 0.5);
  117. padding: 0.4rem;
  118. border-radius: 0.2rem;
  119. filter: invert(1);
  120. }
  121. </style>