DeviceGroups.vue 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. <template>
  2. <div class="l-flex--col c-device-groups">
  3. <div class="l-flex__none l-flex--row c-device-groups__header u-bold has-bottom-padding--sm has-bottom-border">
  4. <el-dropdown
  5. class="l-flex__none c-sibling-item"
  6. trigger="click"
  7. @command="onCommand"
  8. >
  9. <div class="l-flex--row inline has-active">
  10. <i
  11. class="c-sibling-item u-font-size--md"
  12. :class="icon"
  13. />
  14. <span class="c-sibling-item near u-font-size">{{ title }}</span>
  15. </div>
  16. <el-dropdown-menu slot="dropdown">
  17. <el-dropdown-item
  18. icon="el-icon-s-grid"
  19. command="tile"
  20. >
  21. 网格
  22. </el-dropdown-item>
  23. <el-dropdown-item
  24. icon="el-icon-s-operation"
  25. command="level"
  26. >
  27. 层级
  28. </el-dropdown-item>
  29. <el-dropdown-item
  30. icon="el-icon-menu"
  31. command="rect"
  32. >
  33. 方块图
  34. </el-dropdown-item>
  35. <el-dropdown-item
  36. v-if="isTenantAdmin"
  37. icon="el-icon-star-off"
  38. command="attention"
  39. >
  40. 我的关注
  41. </el-dropdown-item>
  42. </el-dropdown-menu>
  43. </el-dropdown>
  44. <div
  45. v-if="hasData && isMaintainer"
  46. class="l-flex__none l-flex--row inline c-sibling-item u-pointer"
  47. @click="onVolume"
  48. >
  49. <svg-icon
  50. class="u-font-size--lg"
  51. icon-class="volume"
  52. />
  53. </div>
  54. <slot />
  55. <div class="l-flex__fill" />
  56. <div
  57. v-if="supportCardStyle"
  58. class="l-flex__none l-flex--row u-color--blue u-font-size--sm has-active"
  59. @click="onSwitchCardStyle"
  60. >
  61. {{ tip }}
  62. </div>
  63. </div>
  64. <component
  65. :is="activeComponent"
  66. class="l-flex__self c-device-groups__content u-overflow-y--auto"
  67. :card-style="cardStyle"
  68. v-bind="$attrs"
  69. @change="onChange"
  70. />
  71. <volume-drawer ref="drawer" />
  72. </div>
  73. </template>
  74. <script>
  75. import { mapGetters } from 'vuex'
  76. import DeviceGroupTile from './DeviceGroupTile.vue'
  77. import DeviceGroupLevel from './DeviceGroupLevel.vue'
  78. import DeviceGroupRect from './DeviceGroupRect.vue'
  79. import DeviceGroupAttention from './DeviceGroupAttention.vue'
  80. import VolumeDrawer from './DrawerVolumeSettings.vue'
  81. const groupStyleCommands = ['tile', 'level', 'rect']
  82. const cardStyleCommands = ['big', 'medium']
  83. export default {
  84. name: 'DeviceGroups',
  85. components: {
  86. DeviceGroupTile,
  87. DeviceGroupLevel,
  88. DeviceGroupRect,
  89. DeviceGroupAttention,
  90. VolumeDrawer
  91. },
  92. data () {
  93. let options = {
  94. groupStyle: groupStyleCommands[0],
  95. cardStyle: cardStyleCommands[0]
  96. }
  97. try {
  98. options = {
  99. ...options,
  100. ...JSON.parse(localStorage.getItem(`MSR_DASHBOARD__STYLE__${this.$store.getters.account}`))
  101. }
  102. } catch (e) {
  103. console.log(e)
  104. }
  105. return {
  106. groupStyle: groupStyleCommands.includes(options.groupStyle) ? options.groupStyle : groupStyleCommands[0],
  107. cardStyle: cardStyleCommands.includes(options.cardStyle) ? options.cardStyle : cardStyleCommands[0],
  108. groups: []
  109. }
  110. },
  111. computed: {
  112. ...mapGetters(['isMaintainer', 'isTenantAdmin', 'account']),
  113. title () {
  114. switch (this.groupStyle) {
  115. case 'attention':
  116. return '我的关注'
  117. case 'rect':
  118. return '方块图'
  119. default:
  120. return '设备列表'
  121. }
  122. },
  123. icon () {
  124. switch (this.groupStyle) {
  125. case 'tile':
  126. return 'el-icon-s-grid'
  127. case 'rect':
  128. return 'el-icon-menu'
  129. case 'attention':
  130. return 'el-icon-star-off'
  131. default:
  132. return 'el-icon-s-operation'
  133. }
  134. },
  135. activeComponent () {
  136. switch (this.groupStyle) {
  137. case 'tile':
  138. return 'DeviceGroupTile'
  139. case 'rect':
  140. return 'DeviceGroupRect'
  141. case 'attention':
  142. return 'DeviceGroupAttention'
  143. default:
  144. return 'DeviceGroupLevel'
  145. }
  146. },
  147. hasData () {
  148. return this.groups.some(({ children }) => children.some(({ onlineStatus }) => onlineStatus === 1))
  149. },
  150. supportCardStyle () {
  151. switch (this.groupStyle) {
  152. case 'rect':
  153. return false
  154. default:
  155. return true
  156. }
  157. },
  158. tip () {
  159. if (this.cardStyle === 'big') {
  160. return '切换至简洁模式'
  161. }
  162. return '切换至详情模式'
  163. }
  164. },
  165. methods: {
  166. onCommand (groupStyle) {
  167. this.groupStyle = groupStyle
  168. this.saveOptions(groupStyleCommands.includes(groupStyle) ? groupStyle : '', this.cardStyle)
  169. },
  170. onVolume () {
  171. this.$refs.drawer.show(this.groups)
  172. },
  173. onChange (groups) {
  174. this.groups = groups
  175. },
  176. onSwitchCardStyle () {
  177. const next = this.cardStyle === 'big' ? 'medium' : 'big'
  178. this.cardStyle = next
  179. this.saveOptions(this.groupStyle, cardStyleCommands.includes(next) ? next : '')
  180. },
  181. saveOptions (groupStyle, cardStyle) {
  182. localStorage.setItem(`MSR_DASHBOARD__STYLE__${this.account}`, JSON.stringify({ groupStyle, cardStyle }))
  183. }
  184. }
  185. }
  186. </script>
  187. <style lang="scss" scoped>
  188. .c-device-groups {
  189. padding: $spacing 0 $spacing--3xs;
  190. &__header {
  191. margin: 0 $spacing;
  192. }
  193. &__content {
  194. padding: $spacing;
  195. }
  196. }
  197. </style>