CardGrid.vue 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. <template lang="pug">
  2. .card-grid-wrapper
  3. .card-grid-loading(v-if='loading')
  4. spinner(type='wave')
  5. .card-grid(v-else)
  6. add-card(v-if='canAdd' @onClickAdd='onClickAdd')
  7. card(v-for='item in items' :key='item.id' :title='item.name' :image='item.imageMedium' :isSelected='item.id === selectedId' :details='computeDetails(item)' :options='defaultOptions.currency' @onClick='onClickCard(item)')
  8. </template>
  9. <script>
  10. import AddCard from '@/components/common/AddCard'
  11. import Card from '@/components/common/Card'
  12. import Spinner from '@/components/common/Spinner'
  13. export default {
  14. props: {
  15. items: {
  16. type: Array,
  17. default: []
  18. },
  19. canAdd: {
  20. type: Boolean,
  21. default: false
  22. },
  23. details: {
  24. type: Array,
  25. default: []
  26. },
  27. loading: {
  28. type: Boolean,
  29. default: false
  30. },
  31. options: {
  32. type: Object,
  33. default: {}
  34. }
  35. },
  36. components: {
  37. AddCard,
  38. Card,
  39. Spinner
  40. },
  41. watch: {
  42. options(value) {
  43. this.computeOptions(value)
  44. }
  45. },
  46. methods: {
  47. computeDetails(item) {
  48. if (!this.details) {
  49. return []
  50. }
  51. if (this.details.length === 0) {
  52. return []
  53. }
  54. let results = []
  55. let computableDetails = this.details.map(item => item.split(/:/))
  56. for (let detail of computableDetails) {
  57. for (let field in item) {
  58. if (field === detail[0]) {
  59. results.push({
  60. value: item[field],
  61. format: (() => {
  62. if (!detail[1] || detail[1] === 's') {
  63. return 'string'
  64. }
  65. if (detail[1] === 'c') {
  66. return 'currency'
  67. }
  68. if (detail[1] === 'd') {
  69. return 'date'
  70. }
  71. return 'string'
  72. })()
  73. })
  74. break
  75. }
  76. }
  77. }
  78. return results
  79. },
  80. computeOptions(value) {
  81. if (!value) {
  82. return
  83. }
  84. for(let key in value) {
  85. if(!this.defaultOptions.currency[key]) {
  86. continue
  87. }
  88. this.defaultOptions.currency[key] = value[key]
  89. }
  90. },
  91. onClickAdd() {
  92. this.$emit('onAdd')
  93. },
  94. onClickCard(item) {
  95. this.selectedId = item.id
  96. this.$emit('onSelect', item)
  97. }
  98. },
  99. data() {
  100. return {
  101. selectedId: -1,
  102. defaultOptions: {
  103. currency: {
  104. symbol: '$',
  105. position: 'before',
  106. thousandsSeparator: '.',
  107. decimalPlaces: 2,
  108. decimalSeparator: ','
  109. },
  110. }
  111. }
  112. }
  113. }
  114. </script>
  115. <style lang="sass">
  116. .card-grid-wrapper
  117. width: 100%
  118. height: calc(100% - 50px)
  119. margin-top: 10px
  120. overflow-y: auto
  121. .card-grid-loading
  122. width: 100%
  123. height: 100%
  124. display: flex
  125. align-items: center
  126. justify-content: center
  127. .card-grid
  128. width: 100%
  129. </style>