You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

173 lines
3.6 KiB

  1. <template lang="pug">
  2. .criterias
  3. transition-group(name='criterias-group', tag='div')
  4. .criterias-group(v-for='(group, g) in groups', :key='g')
  5. transition-group(name='criterias-item', tag='div')
  6. criterias-item(v-for='(item, i) in group', :key='i', :item='item', :group-index='g', :item-index='i', @update='updateItem', @remove='removeItem')
  7. .criterias-item-more
  8. v-btn.ml-0(@click='addItem(group)', small, color='blue-grey lighten-2', dark, depressed)
  9. v-icon(color='white', left) add
  10. | Add condition
  11. .criterias-group-more
  12. v-btn(@click='addGroup', small, color='blue-grey lighten-1', dark, depressed)
  13. v-icon(color='white', left) add
  14. | Add condition group
  15. </template>
  16. <script>
  17. import CriteriasItem from './criterias-item.vue'
  18. export default {
  19. components: {
  20. CriteriasItem
  21. },
  22. props: {
  23. value: {
  24. type: Array,
  25. default() { return [] }
  26. },
  27. types: {
  28. type: Array,
  29. default() {
  30. return ['country', 'path', 'date', 'time', 'group']
  31. }
  32. }
  33. },
  34. provide () {
  35. return {
  36. allowedCriteriaTypes: this.types
  37. }
  38. },
  39. data() {
  40. return {
  41. dataGroups: this.value || []
  42. }
  43. },
  44. computed: {
  45. groups: {
  46. get() { return this.dataGroups },
  47. set(grp) {
  48. this.dataGroups = grp
  49. }
  50. }
  51. },
  52. watch: {
  53. dataGroups(newValue, oldValue) {
  54. if (newValue !== oldValue) {
  55. this.$emit('input', newValue)
  56. }
  57. }
  58. },
  59. methods: {
  60. addGroup() {
  61. this.dataGroups.push([{}])
  62. },
  63. addItem(group) {
  64. group.push({})
  65. },
  66. updateItem(groupIndex, itemIndex, item) {
  67. console.info(item)
  68. this.$set(this.dataGroups[groupIndex], itemIndex, item)
  69. },
  70. removeItem(groupIndex, itemIndex) {
  71. this.dataGroups[groupIndex].splice(itemIndex, 1)
  72. if (this.dataGroups[groupIndex].length < 1) {
  73. this.dataGroups.splice(groupIndex, 1)
  74. }
  75. }
  76. }
  77. }
  78. </script>
  79. <style lang="scss">
  80. .criterias {
  81. &-group {
  82. background-color: mc('blue-grey', '100');
  83. border-radius: 4px;
  84. padding: 1rem;
  85. position: relative;
  86. &-enter-active, &-leave-active {
  87. transition: all .5s ease;
  88. }
  89. &-enter, &-leave-to {
  90. opacity: 0;
  91. }
  92. & + .criterias-group {
  93. margin-top: 1rem;
  94. &::before {
  95. content: 'OR';
  96. position: absolute;
  97. display: inline-flex;
  98. padding: 0 2rem;
  99. top: -1.25rem;
  100. left: 2rem;
  101. background-color: mc('blue-grey', '100');
  102. color: mc('blue-grey', '700');
  103. font-weight: 600;
  104. font-size: .9rem;
  105. }
  106. }
  107. &-more {
  108. margin: .5rem 0 0 .4rem;
  109. }
  110. }
  111. &-item {
  112. display: flex;
  113. background-color: mc('blue-grey', '200');
  114. border-radius: 4px;
  115. padding: .5rem;
  116. &-enter-active, &-leave-active {
  117. transition: all .5s ease;
  118. }
  119. &-enter, &-leave-to {
  120. opacity: 0;
  121. }
  122. & + .criterias-item {
  123. margin-top: .5rem;
  124. position: relative;
  125. &::before {
  126. content: 'AND';
  127. position: absolute;
  128. width: 2rem;
  129. height: 2rem;
  130. border-radius: 50%;
  131. display: flex;
  132. justify-content: center;
  133. align-items: center;
  134. font-weight: 600;
  135. color: mc('blue-grey', '700');
  136. font-size: .7rem;
  137. background-color: mc('blue-grey', '100');
  138. left: -2rem;
  139. top: -1.3rem;
  140. }
  141. }
  142. .input-group {
  143. &:nth-child(1) {
  144. flex: 0 1 350px;
  145. }
  146. &:nth-child(2) {
  147. flex: 0 1 250px;
  148. }
  149. & + * {
  150. margin-left: .5rem;
  151. }
  152. }
  153. &-more {
  154. margin-top: .15rem;
  155. }
  156. }
  157. }
  158. </style>