diff --git a/src/components/list/list.js b/src/components/list/list.js
index 600ad8802..61002c21b 100644
--- a/src/components/list/list.js
+++ b/src/components/list/list.js
@@ -1,5 +1,3 @@
-import { isEmpty } from 'lodash'
-
import Checkbox from 'src/components/checkbox/checkbox.vue'
const List = {
@@ -10,7 +8,7 @@ const List = {
},
items: {
type: Array,
- default: () => [],
+ default: [],
},
fetchFunction: {
type: Function,
@@ -40,28 +38,37 @@ const List = {
type: Boolean,
default: false,
},
+ loading: {
+ type: Boolean,
+ default: true,
+ },
+ bottomedOut: {
+ type: Boolean,
+ default: false,
+ },
+ error: {
+ type: String,
+ default: null,
+ },
},
+ emits: ['fetchRequested'],
components: {
Checkbox,
},
data() {
return {
- loading: false,
- bottomedOut: false,
- error: false,
- dynamicItems: this.itemsFunction ? [] : null,
selected: [],
}
},
computed: {
allKeys() {
- return this.actualItems.map(this.getKey)
+ return this.items.map(this.getKey)
},
filteredSelected() {
return this.allKeys.filter((key) => this.selected.indexOf(key) !== -1)
},
allSelected() {
- return this.filteredSelected.length === this.actualItems.length
+ return this.filteredSelected.length === this.items.length
},
noneSelected() {
return this.filteredSelected.length === 0
@@ -69,54 +76,26 @@ const List = {
someSelected() {
return !this.allSelected && !this.noneSelected
},
- actualItems() {
- return this.dynamicItems || this.actualItems
- },
},
created() {
- if (this.fetchFunction) {
- window.addEventListener('scroll', this.scrollLoad)
+ window.addEventListener('scroll', this.scrollLoad)
- if (this.dynamicItems.length === 0) {
- this.fetchEntries()
- }
+ if (this.items.length === 0) {
+ this.fetchEntries()
}
},
unmounted() {
window.removeEventListener('scroll', this.scrollLoad)
},
methods: {
- // Entries is not a computed because computed can't track the dynamic
- // selector for changes and won't trigger after fetch.
- updateEntries(newEntries) {
- this.dynamicItems = this.itemsFunction(newEntries)
- },
fetchEntries() {
- if (!this.loading) {
- this.loading = true
- this.error = false
- this.fetchFunction()
- .then((newEntries) => {
- this.loading = false
- this.bottomedOut = isEmpty(newEntries)
- return newEntries
- })
- .catch((error) => {
- this.loading = false
- this.error = error
- })
- .finally((newEntries) => {
- this.updateEntries(newEntries)
- })
- }
+ this.$emit('fetchRequested')
},
scrollLoad(e) {
if (this.fetchFunction) {
const bodyBRect = document.body.getBoundingClientRect()
const height = Math.max(bodyBRect.height, -bodyBRect.y)
if (
- this.loading === false &&
- this.bottomedOut === false &&
this.$el.offsetHeight > 0 &&
window.innerHeight + window.pageYOffset >= height - 750
) {
@@ -128,7 +107,6 @@ const List = {
return this.filteredSelected.indexOf(this.getKey(item)) !== -1
},
toggle(checked, item) {
- console.log('TOGGLE', checked, item)
const key = this.getKey(item)
const oldChecked = this.isSelected(key)
if (checked !== oldChecked) {
@@ -138,6 +116,7 @@ const List = {
this.selected.splice(this.selected.indexOf(key), 1)
}
}
+ this.$emit('selected', this.selected)
},
toggleAll(value) {
if (value) {
@@ -145,6 +124,7 @@ const List = {
} else {
this.selected = []
}
+ this.$emit('selected', this.selected)
},
},
}
diff --git a/src/components/list/list.vue b/src/components/list/list.vue
index 5703e2b0d..ab916dfe6 100644
--- a/src/components/list/list.vue
+++ b/src/components/list/list.vue
@@ -28,7 +28,7 @@
role="list"
>
diff --git a/src/components/page_list/page_list.js b/src/components/page_list/page_list.js
deleted file mode 100644
index 3030b0a4a..000000000
--- a/src/components/page_list/page_list.js
+++ /dev/null
@@ -1,87 +0,0 @@
-import SelectableList from 'src/components/selectable_list/selectable_list.vue'
-
-const PageList = {
- components: {
- SelectableList,
- },
- props: {
- /**
- * only make the checkbox clickable to toggle, not the whole area
- */
- boxOnly: {
- type: Boolean,
- default: false,
- },
- /**
- * how many entries to fetch at once
- */
- pageSize: {
- type: Number,
- default: 50,
- },
- /**
- * the function/callback used to fetch new entries (one page)
- */
- fetchPage: {
- type: Function,
- default: async () => [],
- },
- /**
- * wether or not this is a single page list (so it won't allow fetching more pages)
- */
- singlePage: {
- type: Boolean,
- default: false,
- },
- },
- data() {
- return {
- pageIndex: 1,
- items: [],
- canLoadMore: true,
- isLoading: false,
- }
- },
- methods: {
- /**
- * reset and load first page
- */
- reset() {
- this.canLoadMore = true
- this.pageIndex = 1
- this.items = []
- this.isLoading = false
- this.loadMore() // load one page
- },
- /**
- * load another page
- */
- loadMore() {
- if (!this.isLoading && this.canLoadMore) {
- this.isLoading = true
- console.log('is loading = true')
- this.fetchPage(this.$store, {
- page: this.pageIndex++,
- pageSize: this.pageSize,
- }).then((items) => {
- this.items = [...this.items, ...items]
- this.isLoading = false
- })
- }
- },
- /**
- * get currently selected elements
- * @returns {Array}
- */
- getSelected() {
- return this.$refs.list.selected
- },
- },
- /**
- * auto-load first page when mounted
- */
- mounted() {
- this.loadMore()
- },
-}
-export default PageList
diff --git a/src/components/page_list/page_list.vue b/src/components/page_list/page_list.vue
deleted file mode 100644
index 6e5e1d164..000000000
--- a/src/components/page_list/page_list.vue
+++ /dev/null
@@ -1,83 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/components/selectable_list/selectable_list.js b/src/components/selectable_list/selectable_list.js
deleted file mode 100644
index a6abae982..000000000
--- a/src/components/selectable_list/selectable_list.js
+++ /dev/null
@@ -1,70 +0,0 @@
-import Checkbox from 'src/components/checkbox/checkbox.vue'
-import List from 'src/components/list/list.vue'
-
-const SelectableList = {
- components: {
- List,
- Checkbox,
- },
- props: {
- boxOnly: {
- type: Boolean,
- default: false,
- },
- items: {
- type: Array,
- default: () => [],
- },
- getKey: {
- type: Function,
- default: (item) => item.id,
- },
- },
- data() {
- return {
- selected: [],
- }
- },
- computed: {
- allKeys() {
- return this.items.map(this.getKey)
- },
- filteredSelected() {
- return this.allKeys.filter((key) => this.selected.indexOf(key) !== -1)
- },
- allSelected() {
- return this.filteredSelected.length === this.items.length
- },
- noneSelected() {
- return this.filteredSelected.length === 0
- },
- someSelected() {
- return !this.allSelected && !this.noneSelected
- },
- },
- methods: {
- isSelected(item) {
- return this.filteredSelected.indexOf(this.getKey(item)) !== -1
- },
- toggle(checked, item) {
- const key = this.getKey(item)
- const oldChecked = this.isSelected(key)
- if (checked !== oldChecked) {
- if (checked) {
- this.selected.push(key)
- } else {
- this.selected.splice(this.selected.indexOf(key), 1)
- }
- }
- },
- toggleAll(value) {
- if (value) {
- this.selected = this.allKeys.slice(0)
- } else {
- this.selected = []
- }
- },
- },
-}
-
-export default SelectableList
diff --git a/src/components/selectable_list/selectable_list.vue b/src/components/selectable_list/selectable_list.vue
deleted file mode 100644
index b760508d1..000000000
--- a/src/components/selectable_list/selectable_list.vue
+++ /dev/null
@@ -1,119 +0,0 @@
-
-
-
-
-
-
-
- toggle(checked, item)"
- @click.stop
- />
-
-
-
-
-
- toggle(checked, item)"
- @click.stop
- />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/components/settings_modal/admin_tabs/users_tab.js b/src/components/settings_modal/admin_tabs/users_tab.js
index 6dcfbb488..47e7f8fb4 100644
--- a/src/components/settings_modal/admin_tabs/users_tab.js
+++ b/src/components/settings_modal/admin_tabs/users_tab.js
@@ -1,7 +1,9 @@
+import { isEmpty } from 'lodash'
+
import BasicUserCard from 'src/components/basic_user_card/basic_user_card.vue'
import Checkbox from 'src/components/checkbox/checkbox.vue'
import GenericConfirm from 'src/components/confirm_modal/generic_confirm.vue'
-import PageList from 'src/components/page_list/page_list.vue'
+import List from 'src/components/list/list.vue'
import Popover from 'src/components/popover/popover.vue'
import ProgressButton from 'src/components/progress_button/progress_button.vue'
import Select from 'src/components/select/select.vue'
@@ -17,7 +19,6 @@ const UsersTab = {
},
data() {
return {
- init: false,
filtersOrigin: 'local',
filtersActivity: 'all',
filtersPrivileges: 'all',
@@ -28,6 +29,11 @@ const UsersTab = {
filtersEmail: '',
expandedUser: null,
loading: false,
+ error: null,
+ bottomedOut: false,
+ users: [],
+ page: 1,
+ total: null,
}
},
computed: {
@@ -79,26 +85,7 @@ const UsersTab = {
filtersExternal() {
return this.filtersOrigin === 'external'
},
- },
- components: {
- Checkbox,
- Select,
- BasicUserCard,
- PageList,
- ProgressButton,
- AdminCard,
- TabSwitcher,
- Popover,
- GenericConfirm,
- },
- methods: {
- /**
- * fetch a new page of users via admin-api
- * @param {object} store
- * @param {object} opts
- */
- fetchPage(store, opts) {
- if (!this.init) return new Promise(() => [])
+ fetchOptions() {
const filters = {
isAdmin: this.filtersIsAdmin,
isModerator: this.filtersIsModerator,
@@ -109,22 +96,51 @@ const UsersTab = {
needApproval: this.filtersNeedApproval,
unconfirmed: this.filtersUnconfirmeUnconfirmed,
}
- const nopts = {
- ...opts,
- ...{
- query: this.filtersQuery,
- filters,
- name: this.filtersName,
- email: this.filtersEmail,
- },
+
+ return {
+ query: this.filtersQuery,
+ name: this.filtersName,
+ email: this.filtersEmail,
+ pageSize: 50,
+ filters,
}
- return store.dispatch('fetchAdminUsers', nopts)
},
- /**
- * reset the userlist explicitly
- */
- reset() {
- this.$refs.userList.reset()
+ },
+ components: {
+ Checkbox,
+ Select,
+ BasicUserCard,
+ List,
+ ProgressButton,
+ AdminCard,
+ TabSwitcher,
+ Popover,
+ GenericConfirm,
+ },
+ methods: {
+ fetchPage() {
+ if (this.loading) return
+
+ this.loading = true
+ this.error = null
+
+ this.$store
+ .dispatch('fetchAdminUsers', {
+ ...this.fetchOptions,
+ page: this.page,
+ })
+ .then((result) => {
+ console.log('RESULT', result)
+ this.loading = false
+ this.bottomedOut = isEmpty(result.users)
+ this.page += 1
+ this.total = result.count
+ this.users.push(...result.users)
+ })
+ .catch((error) => {
+ this.loading = false
+ this.error = error
+ })
},
/**
* show the confirmation box for bulk actions.
@@ -147,20 +163,18 @@ const UsersTab = {
u.id !== this.$store.state.users.currentUser.id
) {
const uf = this.$store.getters.findUser(u.id)
- console.log('user: ', uf)
this.$store.dispatch(action, this.$store.getters.findUser(u.id))
}
})
- this.reset()
},
},
- /**
- * mark as initialized and reset user list
- */
- mounted() {
- this.init = true
- this.reset()
- },
+ watch: {
+ fetchOptions () {
+ this.page = 1
+ this.users = []
+ this.fetchPage()
+ }
+ }
}
export default UsersTab
diff --git a/src/components/settings_modal/admin_tabs/users_tab.scss b/src/components/settings_modal/admin_tabs/users_tab.scss
index 892abb02c..537e43d09 100644
--- a/src/components/settings_modal/admin_tabs/users_tab.scss
+++ b/src/components/settings_modal/admin_tabs/users_tab.scss
@@ -1,6 +1,6 @@
.UsersTab {
max-height: 100%;
- display: grid;
+ display: flex;
flex-direction: column;
overflow-y: hidden;
diff --git a/src/components/settings_modal/admin_tabs/users_tab.vue b/src/components/settings_modal/admin_tabs/users_tab.vue
index 970bf5609..77006f61c 100644
--- a/src/components/settings_modal/admin_tabs/users_tab.vue
+++ b/src/components/settings_modal/admin_tabs/users_tab.vue
@@ -14,7 +14,6 @@
@@ -43,7 +40,6 @@
-