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.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. <template>
  2. <div
  3. class="row"
  4. :class="{'disabled': loading.delete || loading.disable}"
  5. :data-id="user.id">
  6. <div class="avatar" :class="{'icon-loading-small': loading.delete || loading.disable || loading.wipe}">
  7. <img v-if="!loading.delete && !loading.disable && !loading.wipe"
  8. alt=""
  9. width="32"
  10. height="32"
  11. :src="generateAvatar(user.id, 32)"
  12. :srcset="generateAvatar(user.id, 64)+' 2x, '+generateAvatar(user.id, 128)+' 4x'">
  13. </div>
  14. <!-- dirty hack to ellipsis on two lines -->
  15. <div class="name">
  16. {{ user.id }}
  17. <div class="displayName subtitle">
  18. <div v-tooltip="user.displayname.length > 20 ? user.displayname : ''" class="cellText">
  19. {{ user.displayname }}
  20. </div>
  21. </div>
  22. </div>
  23. <div />
  24. <div class="mailAddress">
  25. <div v-tooltip="user.email !== null && user.email.length > 20 ? user.email : ''" class="cellText">
  26. {{ user.email }}
  27. </div>
  28. </div>
  29. <div class="groups">
  30. {{ userGroupsLabels }}
  31. </div>
  32. <div v-if="subAdminsGroups.length > 0 && settings.isAdmin" class="subAdminsGroups">
  33. {{ userSubAdminsGroupsLabels }}
  34. </div>
  35. <div class="userQuota">
  36. <div class="quota">
  37. {{ userQuota }} ({{ usedSpace }})
  38. <progress
  39. class="quota-user-progress"
  40. :class="{'warn': usedQuota > 80}"
  41. :value="usedQuota"
  42. max="100" />
  43. </div>
  44. </div>
  45. <div v-if="showConfig.showLanguages" class="languages">
  46. {{ userLanguage.name }}
  47. </div>
  48. <div v-if="showConfig.showUserBackend || showConfig.showStoragePath" class="userBackend">
  49. <div v-if="showConfig.showUserBackend" class="userBackend">
  50. {{ user.backend }}
  51. </div>
  52. <div v-if="showConfig.showStoragePath" v-tooltip="user.storageLocation" class="storageLocation subtitle">
  53. {{ user.storageLocation }}
  54. </div>
  55. </div>
  56. <div v-if="showConfig.showLastLogin" v-tooltip.auto="userLastLoginTooltip" class="lastLogin">
  57. {{ userLastLogin }}
  58. </div>
  59. <div class="userActions">
  60. <div v-if="canEdit && !loading.all" class="toggleUserActions">
  61. <Actions>
  62. <ActionButton icon="icon-rename" @click="toggleEdit">
  63. {{ t('settings', 'Edit User') }}
  64. </ActionButton>
  65. </Actions>
  66. <div class="userPopoverMenuWrapper">
  67. <div v-click-outside="hideMenu" class="icon-more" @click="$emit('toggleMenu')" />
  68. <div class="popovermenu" :class="{ 'open': openedMenu }">
  69. <PopoverMenu :menu="userActions" />
  70. </div>
  71. </div>
  72. </div>
  73. <div class="feedback" :style="{opacity: feedbackMessage !== '' ? 1 : 0}">
  74. <div class="icon-checkmark" />
  75. {{ feedbackMessage }}
  76. </div>
  77. </div>
  78. </div>
  79. </template>
  80. <script>
  81. import { PopoverMenu, Actions, ActionButton } from '@nextcloud/vue'
  82. import ClickOutside from 'vue-click-outside'
  83. import { getCurrentUser } from '@nextcloud/auth'
  84. import UserRowMixin from '../../mixins/UserRowMixin'
  85. export default {
  86. name: 'UserRowSimple',
  87. components: {
  88. PopoverMenu,
  89. ActionButton,
  90. Actions,
  91. },
  92. directives: {
  93. ClickOutside,
  94. },
  95. mixins: [UserRowMixin],
  96. props: {
  97. user: {
  98. type: Object,
  99. required: true,
  100. },
  101. loading: {
  102. type: Object,
  103. required: true,
  104. },
  105. showConfig: {
  106. type: Object,
  107. required: true,
  108. },
  109. userActions: {
  110. type: Array,
  111. required: true,
  112. },
  113. openedMenu: {
  114. type: Boolean,
  115. required: true,
  116. },
  117. feedbackMessage: {
  118. type: String,
  119. required: true,
  120. },
  121. subAdminsGroups: {
  122. type: Array,
  123. required: true,
  124. },
  125. settings: {
  126. type: Object,
  127. required: true,
  128. },
  129. },
  130. computed: {
  131. userGroupsLabels() {
  132. return this.userGroups
  133. .map(group => group.name)
  134. .join(', ')
  135. },
  136. userSubAdminsGroupsLabels() {
  137. return this.userSubAdminsGroups
  138. .map(group => group.name)
  139. .join(', ')
  140. },
  141. usedSpace() {
  142. if (this.user.quota.used) {
  143. return t('settings', '{size} used', { size: OC.Util.humanFileSize(this.user.quota.used) })
  144. }
  145. return t('settings', '{size} used', { size: OC.Util.humanFileSize(0) })
  146. },
  147. canEdit() {
  148. return getCurrentUser().uid !== this.user.id && this.user.id !== 'admin'
  149. },
  150. userQuota() {
  151. if (this.user.quota.quota === 'none') {
  152. return t('settings', 'Unlimited')
  153. }
  154. if (this.user.quota.quota >= 0) {
  155. return OC.Util.humanFileSize(this.user.quota.quota)
  156. }
  157. return OC.Util.humanFileSize(0)
  158. },
  159. },
  160. methods: {
  161. hideMenu() {
  162. this.$emit('hideMenu')
  163. },
  164. toggleEdit() {
  165. this.$emit('update:editing', true)
  166. },
  167. },
  168. }
  169. </script>
  170. <style scoped>
  171. .cellText {
  172. overflow: hidden;
  173. text-overflow: ellipsis;
  174. white-space: nowrap;
  175. }
  176. </style>