Grid.vue 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. <style lang="scss" scoped>
  2. @import '~/assets/styles/_colors.scss';
  3. .item-move {
  4. transition: all .25s cubic-bezier(.55,0,.1,1);
  5. -webkit-transition: all .25s cubic-bezier(.55,0,.1,1);
  6. }
  7. div.actions {
  8. opacity: 0;
  9. -webkit-transition: opacity 0.1s linear;
  10. -moz-transition: opacity 0.1s linear;
  11. -ms-transition: opacity 0.1s linear;
  12. -o-transition: opacity 0.1s linear;
  13. transition: opacity 0.1s linear;
  14. position: absolute;
  15. top: 0px;
  16. left: 0px;
  17. width: 100%;
  18. height: calc(100% - 6px);
  19. background: rgba(0, 0, 0, 0.5);
  20. display: flex;
  21. justify-content: center;
  22. align-items: center;
  23. span {
  24. padding: 3px;
  25. &:nth-child(1), &:nth-child(2) {
  26. align-items: flex-end;
  27. }
  28. &:nth-child(1), &:nth-child(3) {
  29. justify-content: flex-end;
  30. }
  31. a {
  32. width: 30px;
  33. height: 30px;
  34. color: white;
  35. justify-content: center;
  36. align-items: center;
  37. display: flex;
  38. &:before {
  39. content: '';
  40. width: 30px;
  41. height: 30px;
  42. border: 1px solid white;
  43. border-radius: 50%;
  44. position: absolute;
  45. }
  46. }
  47. }
  48. &.fixed {
  49. position: relative;
  50. opacity: 1;
  51. background: none;
  52. a {
  53. width: auto;
  54. height: auto;
  55. color: $defaultTextColor;
  56. &:before {
  57. display: none;
  58. }
  59. }
  60. }
  61. }
  62. </style>
  63. <style lang="scss">
  64. .waterfall-item:hover {
  65. div.actions {
  66. opacity: 1
  67. }
  68. }
  69. </style>
  70. <template>
  71. <Waterfall
  72. :gutterWidth="10"
  73. :gutterHeight="4">
  74. <WaterfallItem v-for="(item, index) in files"
  75. v-if="showWaterfall && item.thumb"
  76. :key="index"
  77. :width="width"
  78. move-class="item-move">
  79. <template v-if="isPublic">
  80. <a :href="`${item.url}`"
  81. target="_blank">
  82. <img :src="`${item.thumb}`">
  83. </a>
  84. </template>
  85. <template v-else>
  86. <img :src="`${item.thumb}`">
  87. <div v-if="!isPublic"
  88. :class="{ fixed }"
  89. class="actions">
  90. <b-tooltip label="Link"
  91. position="is-top">
  92. <a :href="`${item.url}`"
  93. target="_blank">
  94. <i class="icon-web-code" />
  95. </a>
  96. </b-tooltip>
  97. <b-tooltip label="Albums"
  98. position="is-top">
  99. <a @click="$parent.openAlbumModal(item)">
  100. <i class="icon-interface-window" />
  101. </a>
  102. </b-tooltip>
  103. <b-tooltip label="Tags"
  104. position="is-top">
  105. <a @click="manageTags(item)">
  106. <i class="icon-ecommerce-tag-c" />
  107. </a>
  108. </b-tooltip>
  109. <b-tooltip label="Delete"
  110. position="is-top">
  111. <a @click="deleteFile(item, index)">
  112. <i class="icon-editorial-trash-a-l" />
  113. </a>
  114. </b-tooltip>
  115. </div>
  116. </template>
  117. </WaterfallItem>
  118. </Waterfall>
  119. </template>
  120. <script>
  121. import Waterfall from './waterfall/Waterfall.vue';
  122. import WaterfallItem from './waterfall/WaterfallItem.vue';
  123. export default {
  124. components: {
  125. Waterfall,
  126. WaterfallItem
  127. },
  128. props: {
  129. files: {
  130. type: Array,
  131. default: null
  132. },
  133. fixed: {
  134. type: Boolean,
  135. default: false
  136. },
  137. isPublic: {
  138. type: Boolean,
  139. default: false
  140. },
  141. width: {
  142. type: Number,
  143. default: 150
  144. }
  145. },
  146. data() {
  147. return { showWaterfall: true };
  148. },
  149. computed: {
  150. config() {
  151. return this.$store.state.config;
  152. }
  153. },
  154. methods: {
  155. deleteFile(file, index) {
  156. this.$dialog.confirm({
  157. title: 'Deleting file',
  158. message: 'Are you sure you want to <b>delete</b> this file?',
  159. confirmText: 'Delete File',
  160. type: 'is-danger',
  161. hasIcon: true,
  162. onConfirm: async () => {
  163. try {
  164. const response = await this.$axios.$delete(`file/${file.id}`);
  165. this.showWaterfall = false;
  166. this.files.splice(index, 1);
  167. this.$nextTick(() => {
  168. this.showWaterfall = true;
  169. });
  170. return this.$toast.open(response.message);
  171. } catch (error) {
  172. return this.$onPromiseError(error);
  173. }
  174. }
  175. });
  176. }
  177. }
  178. };
  179. </script>