Skip to content

Commit 1e8d224

Browse files
committed
Merge branch 'master' into next
2 parents f9ce664 + 2438fb7 commit 1e8d224

File tree

15 files changed

+267
-78
lines changed

15 files changed

+267
-78
lines changed

frontend/express/public/core/user-management/javascripts/countly.views.js

+136-49
Original file line numberDiff line numberDiff line change
@@ -1,71 +1,114 @@
11
/*global countlyAuth, app, countlyGlobal, $, groupsModel, CV, countlyVue, countlyUserManagement, countlyCommon, CountlyHelpers */
22
(function() {
3+
var isGroupPluginEnabled = countlyGlobal.plugins.includes("groups");
34

45
var DataTable = countlyVue.views.create({
56
template: CV.T("/core/user-management/templates/data-table.html"),
67
mixins: [countlyVue.mixins.commonFormatters],
78
props: {
89
rows: Array,
9-
loading: Boolean
10+
loading: Boolean,
11+
groupMap: Object
1012
},
1113
data: function() {
14+
var roleMap = {};
15+
// 'value' is used as map key here to make it easier to convert currentFilter into filterSummary
16+
roleMap.global_admin = CV.i18n("management-users.global-admin");
17+
roleMap.admin = CV.i18n("management-users.admin");
18+
roleMap.user = CV.i18n("management-users.user");
19+
var tableDynamicCols = [
20+
{
21+
value: "full_name",
22+
label: CV.i18n('management-users.user'),
23+
default: true
24+
},
25+
{
26+
value: "username",
27+
label: CV.i18n('management-users.username'),
28+
default: false
29+
},
30+
{
31+
value: "role",
32+
label: CV.i18n('management-users.role'),
33+
default: true
34+
},
35+
{
36+
value: "email",
37+
label: CV.i18n('management-users.email'),
38+
default: true
39+
},
40+
{
41+
value: "group",
42+
label: CV.i18n('management-users.group'),
43+
default: true
44+
},
45+
{
46+
value: "created_at",
47+
label: CV.i18n('management-users.created'),
48+
default: false
49+
},
50+
{
51+
value: "last_login",
52+
label: CV.i18n('management-users.last_login'),
53+
default: true
54+
}
55+
];
56+
57+
if (!isGroupPluginEnabled) {
58+
tableDynamicCols.splice(4, 1);
59+
}
60+
1261
return {
13-
tableFilter: null,
62+
currentFilter: {
63+
role: null,
64+
group: null
65+
},
66+
roleMap: roleMap,
1467
showLogs: countlyGlobal.plugins.indexOf('systemlogs') > -1,
15-
tableDynamicCols: [
16-
{
17-
value: "full_name",
18-
label: CV.i18n('management-users.user'),
19-
default: true
20-
},
21-
{
22-
value: "username",
23-
label: CV.i18n('management-users.username'),
24-
default: true
25-
},
26-
{
27-
value: "email",
28-
label: CV.i18n('management-users.email'),
29-
default: true
30-
},
31-
{
32-
value: "role",
33-
label: CV.i18n('management-users.role'),
34-
default: true
35-
},
36-
{
37-
value: "created_at",
38-
label: CV.i18n('management-users.created'),
39-
default: true
40-
},
41-
{
42-
value: "last_login",
43-
label: CV.i18n('management-users.last_login'),
44-
default: true
45-
}
46-
],
47-
userManagementPersistKey: 'userManagement_table_' + countlyCommon.ACTIVE_APP_ID
68+
tableDynamicCols: tableDynamicCols,
69+
userManagementPersistKey: 'userManagement_table_' + countlyCommon.ACTIVE_APP_ID,
70+
isGroupPluginEnabled: isGroupPluginEnabled,
71+
isResetting: false
4872
};
4973
},
5074
computed: {
5175
filteredRows: function() {
52-
var self = this;
53-
if (this.tableFilter) {
76+
if (this.currentFilter.group || this.currentFilter.role) {
77+
var currentGroup = this.currentFilter.group;
78+
var currentRole = this.currentFilter.role;
79+
5480
return this.rows.filter(function(row) {
55-
if (self.tableFilter === 'global_admin') {
56-
return row.global_admin;
81+
var filterGroup = true;
82+
var filterRole = true;
83+
84+
if (currentGroup) {
85+
filterGroup = row.group_id && (row.group_id[0] === currentGroup);
5786
}
58-
else if (self.tableFilter === 'admin') {
59-
return !row.global_admin && (row.permission && row.permission._.a.length > 0);
87+
88+
if (currentRole === "global_admin") {
89+
filterRole = row.global_admin;
6090
}
61-
else {
62-
return !row.global_admin && (row.permission && row.permission._.a.length === 0);
91+
else if (currentRole === "admin") {
92+
filterRole = !row.global_admin && (row.permission && row.permission._.a.length > 0);
93+
}
94+
else if (currentRole === "user") {
95+
filterRole = !row.global_admin && (row.permission && row.permission._.a.length === 0);
6396
}
97+
98+
return filterGroup && filterRole;
6499
});
65100
}
66101
else {
67102
return this.rows;
68103
}
104+
},
105+
filterSummary: function() {
106+
var summary = [
107+
this.roleMap[this.currentFilter.role] || CV.i18n("management-users.all-roles"),
108+
this.groupMap[this.currentFilter.group] || CV.i18n("management-users.all-groups")
109+
];
110+
111+
return summary.join(", ");
69112
}
70113
},
71114
methods: {
@@ -96,6 +139,32 @@
96139
window.location.hash = "#/manage/logs/systemlogs/query/" + JSON.stringify({"user_id": index});
97140
break;
98141
}
142+
},
143+
handleSubmitFilter: function(newFilter) {
144+
this.currentFilter = newFilter;
145+
this.$refs.filterDropdown.doClose();
146+
},
147+
handleCancelFilterClick: function() {
148+
this.$refs.filterDropdown.doClose();
149+
this.reloadFilterValues();
150+
},
151+
handleResetFilterClick: function() {
152+
this.isResetting = true;
153+
this.reloadFilterValues();
154+
this.isResetting = false;
155+
},
156+
handleBeforeCopy: function(copied) {
157+
if (this.isResetting) {
158+
return {
159+
group: null,
160+
role: null
161+
};
162+
}
163+
164+
return copied;
165+
},
166+
reloadFilterValues: function() {
167+
this.$refs.filterForm.reload();
99168
}
100169
}
101170
});
@@ -648,16 +717,25 @@
648717
loading: true
649718
};
650719
},
720+
computed: {
721+
groupMap: function() {
722+
var map = {};
723+
724+
groupsModel.data().forEach(function(group) {
725+
map[group._id] = group.name;
726+
});
727+
728+
return map;
729+
}
730+
},
651731
methods: {
652732
refresh: function() {
653733
var self = this;
654734
countlyUserManagement.fetchUsers()
655735
.then(function() {
656736
var usersObj = countlyUserManagement.getUsers();
657737
self.users = [];
658-
for (var user in usersObj) {
659-
self.users.push(usersObj[user]);
660-
}
738+
self.fillOutUsers(usersObj);
661739
})
662740
.catch(function() {});
663741
},
@@ -676,15 +754,24 @@
676754
}
677755
self.openDrawer("user", self.user);
678756
});
757+
},
758+
fillOutUsers: function(usersObj) {
759+
for (var userId in usersObj) {
760+
var user = usersObj[userId];
761+
762+
if (user.group_id) {
763+
user.groupName = this.groupMap[user.group_id[0]];
764+
}
765+
766+
this.users.push(user);
767+
}
679768
}
680769
},
681770
mounted: function() {
682771
var self = this;
683772
$.when(countlyUserManagement.fetchUsers(), countlyUserManagement.fetchFeatures()).then(function() {
684773
var usersObj = countlyUserManagement.getUsers();
685-
for (var user in usersObj) {
686-
self.users.push(usersObj[user]);
687-
}
774+
self.fillOutUsers(usersObj);
688775
self.loading = false;
689776
self.features = countlyUserManagement.getFeatures().sort();
690777
});

frontend/express/public/core/user-management/stylesheets/_main.scss

+4
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,8 @@
99
.manage-users-action-btn {
1010
background-color: #12af51;
1111
}
12+
}
13+
14+
.no-bg-hover:hover {
15+
background-color: transparent;
1216
}

frontend/express/public/core/user-management/templates/data-table.html

+66-14
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,70 @@
55
:available-dynamic-cols="tableDynamicCols"
66
:persist-key="userManagementPersistKey">
77
<template v-slot:header-left="selectScope">
8-
<el-select placement="bottom-start" v-model="tableFilter" :placeholder="i18n('management-users.all-roles')">
9-
<el-option key="0" :label="i18n('management-users.all-roles')" :value="null"></el-option>
10-
<el-option key="1" :label="i18n('management-users.global-admin')" value="global_admin"></el-option>
11-
<el-option key="2" :label="i18n('management-users.admin')" value="admin"></el-option>
12-
<el-option key="3" :label="i18n('management-users.user')" value="user"></el-option>
13-
</el-select>
8+
<cly-dropdown ref="filterDropdown" @hide="reloadFilterValues">
9+
<template v-slot:trigger="dropdown">
10+
<cly-input-dropdown-trigger
11+
v-tooltip="filterSummary"
12+
:selected-options="filterSummary"
13+
:focused="dropdown.focused"
14+
:opened="dropdown.visible"
15+
:adaptive-length="true">
16+
</cly-input-dropdown-trigger>
17+
</template>
18+
<template>
19+
<cly-form
20+
:initial-edited-object="currentFilter"
21+
:before-copy-fn="handleBeforeCopy"
22+
class="user-management-filter-form"
23+
ref="filterForm"
24+
@submit="handleSubmitFilter">
25+
<template v-slot="formScope">
26+
<cly-form-step id="filter-form-step">
27+
<div class="bu-m-4">
28+
<div class="bu-level">
29+
<div class="bu-level-left">
30+
<div class="bu-level-item">
31+
<h4>{{i18n('management-users.view-title')}}</h4>
32+
</div>
33+
</div>
34+
<div class="bu-level-right">
35+
<div class="bu-level-item">
36+
<el-button type="text" class="bu-has-text-danger no-bg-hover" @click="handleResetFilterClick">{{i18n('management-users.reset-filters')}}</el-button>
37+
</div>
38+
</div>
39+
</div>
40+
<cly-form-field :label="i18n('management-users.role')">
41+
<el-select placement="bottom-start" v-model="formScope.editedObject.role" :placeholder="i18n('management-users.all-roles')">
42+
<el-option key="0" :label="i18n('management-users.all-roles')" :value="null"></el-option>
43+
<el-option v-for="(value, key, idx) in roleMap" :key="idx + 1" :label="value" :value="key"></el-option>
44+
</el-select>
45+
</cly-form-field>
46+
<cly-form-field v-if="isGroupPluginEnabled" :label="i18n('management-users.group')">
47+
<el-select placement="bottom-start" v-model="formScope.editedObject.group" :placeholder="i18n('management-users.all-groups')">
48+
<el-option key="0" :label="i18n('management-users.all-groups')" :value="null"></el-option>
49+
<el-option v-for="(value, key, idx) in groupMap" :key="idx + 1" :label="value" :value="key"></el-option>
50+
</el-select>
51+
</cly-form-field>
52+
<div class="bu-has-text-right bu-pt-3">
53+
<el-button type="secondary" @click="handleCancelFilterClick">{{i18n('common.cancel')}}</el-button>
54+
<el-button type="success" @click="formScope.submit()">{{i18n('common.apply')}}</el-button>
55+
</div>
56+
</div>
57+
</cly-form-step>
58+
</template>
59+
</cly-form>
60+
</template>
61+
</cly-dropdown>
1462
</template>
1563
<template v-slot="scope">
1664
<template v-for="(col, idx) in scope.dynamicCols">
17-
<el-table-column
18-
v-if="col.value === 'username'"
19-
sortable="true" prop="username" :label="i18n('management-users.username')">
20-
</el-table-column>
2165
<el-table-column
22-
v-if="col.value === 'full_name'"
66+
v-if="col.value === 'full_name'"
2367
sortable="true" prop="full_name" :label="i18n('management-users.user')">
2468
</el-table-column>
2569
<el-table-column
26-
v-if="col.value === 'email'"
27-
sortable="true" prop="email" :label="i18n('management-users.email')">
70+
v-if="col.value === 'username'"
71+
sortable="true" prop="username" :label="i18n('management-users.username')">
2872
</el-table-column>
2973
<el-table-column
3074
v-if="col.value === 'role'"
@@ -36,6 +80,14 @@
3680
</span>
3781
</template>
3882
</el-table-column>
83+
<el-table-column
84+
v-if="col.value === 'email'"
85+
sortable="true" prop="email" :label="i18n('management-users.email')">
86+
</el-table-column>
87+
<el-table-column
88+
v-if="col.value === 'group'"
89+
sortable="true" prop="groupName" :label="i18n('management-users.group')">
90+
</el-table-column>
3991
<el-table-column
4092
v-if="col.value === 'created_at'"
4193
sortable="true"
@@ -65,6 +117,6 @@
65117
</cly-more-options>
66118
</template>
67119
</el-table-column>
68-
</template>
120+
</template>
69121
</cly-datatable-n>
70122
</div>

frontend/express/public/core/user-management/templates/user-management.html

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22
<cly-header :title="i18n('management-users.view-title')">
33
<template v-slot:header-right>
44
<div class="bu-level-item">
5-
<el-button class="manage-users-action-btn" @click="createUser()" type="success" size="small" icon="el-icon-circle-plus">
5+
<el-button class="manage-users-action-btn" @click="createUser()" type="success" size="small" icon="el-icon-circle-plus">
66
{{ i18n('management-users.create-user') }}
77
</el-button>
88
</div>
99
</template>
1010
</cly-header>
11-
<data-table :loading="loading" @refresh-table="refresh" @edit-user="onEditUser" :rows="users"></data-table>
11+
<data-table :loading="loading" @refresh-table="refresh" @edit-user="onEditUser" :rows="users" :group-map="groupMap"></data-table>
1212
<drawer @refresh-table="refresh" :user="user" :features="features" :settings="drawerSettings" :controls="drawers.user"></drawer>
1313
</div>

frontend/express/public/localization/dashboard/dashboard.properties

+3
Original file line numberDiff line numberDiff line change
@@ -905,6 +905,9 @@ management-users.view-user-logs = View user logs
905905
management-users.this-will-delete-user = This will permanently delete the user. Continue?
906906
management-users.warning = Warning
907907
management-users.future-plugins = User will have this access type to all additional features that might be enabled in the future.
908+
management-users.all-groups = All groups
909+
management-users.group = Group
910+
management-users.reset-filters = Reset Filters
908911

909912
#user-settings
910913
user-settings.username = Username

0 commit comments

Comments
 (0)