ui: better domain_user page performance

This commit is contained in:
undefined committed 2024-12-11 18:20:28 +08:00
1 parent f52186750d
commit 00392f1272
7 files changed
+35 -15

No files matched your search

+1 -1
View File
@@ -4,7 +4,7 @@
"license": "MIT", "license": "MIT",
"main": "react.yaml", "main": "react.yaml",
"dependencies": { "dependencies": {
"@stylistic/eslint-plugin": "^2.11.0", "@stylistic/eslint-plugin": "^2.12.0",
"@typescript-eslint/eslint-plugin": "^8.17.0", "@typescript-eslint/eslint-plugin": "^8.17.0",
"@typescript-eslint/parser": "^8.17.0", "@typescript-eslint/parser": "^8.17.0",
"eslint-config-airbnb": "^19.0.4", "eslint-config-airbnb": "^19.0.4",
+8 -9
View File
@@ -96,7 +96,8 @@ class DomainDashboardHandler extends ManageHandler {
class DomainUserHandler extends ManageHandler { class DomainUserHandler extends ManageHandler {
@requireSudo @requireSudo
async get({ domainId }) { @param('format', Types.Range(['default', 'raw']), true)
async get({ domainId }, format = 'default') {
const rudocs = {}; const rudocs = {};
const [dudocs, roles] = await Promise.all([ const [dudocs, roles] = await Promise.all([
domain.getMultiUserInDomain(domainId, { domain.getMultiUserInDomain(domainId, {
@@ -107,15 +108,13 @@ class DomainUserHandler extends ManageHandler {
}).toArray(), }).toArray(),
domain.getRoles(domainId), domain.getRoles(domainId),
]); ]);
const uids = dudocs.map((dudoc) => dudoc.uid); // TODO: switch to getListForRender for better performance
const udict = await user.getList(domainId, uids); const udict = await user.getList(domainId, dudocs.map((dudoc) => dudoc.uid));
for (const role of roles) rudocs[role._id] = []; const users = dudocs.filter((dudoc) => udict[dudoc.uid].priv & PRIV.PRIV_USER_PROFILE);
for (const dudoc of dudocs) { for (const role of roles) {
const udoc = udict[dudoc.uid]; rudocs[role._id] = users.filter((dudoc) => dudoc.role === role._id).map((i) => udict[i.uid]);
if (!(udoc.priv & PRIV.PRIV_USER_PROFILE)) continue;
rudocs[udoc.role || 'default'].push(udoc);
} }
this.response.template = 'domain_user.html'; this.response.template = format === 'raw' ? 'domain_user_raw.html' : 'domain_user.html';
this.response.body = { this.response.body = {
roles, rudocs, udict, domain: this.domain, roles, rudocs, udict, domain: this.domain,
}; };
@@ -166,6 +166,7 @@ env.addGlobal('platformIcon', (platform) => {
}); });
const render = (name: string, state: any) => new Promise<string>((resolve, reject) => { const render = (name: string, state: any) => new Promise<string>((resolve, reject) => {
const start = Date.now();
env.render(name, { env.render(name, {
page_name: name.split('.')[0], page_name: name.split('.')[0],
...state, ...state,
@@ -180,6 +181,8 @@ const render = (name: string, state: any) => new Promise<string>((resolve, rejec
STATUS, STATUS,
UiContext: state.handler?.UiContext || {}, UiContext: state.handler?.UiContext || {},
}, (err, res) => { }, (err, res) => {
const end = Date.now();
if (end - start > 5000) console.error(`Render of ${name} took ${end - start}ms`);
if (err) reject(err); if (err) reject(err);
else resolve(res); else resolve(res);
}); });
+2 -2
View File
@@ -88,11 +88,11 @@
"prop-types": "^15.8.1", "prop-types": "^15.8.1",
"qface": "^1.4.1", "qface": "^1.4.1",
"qrcode": "^1.5.4", "qrcode": "^1.5.4",
"react": "^19.0.0", "react": "^18.3.1",
"react-colorful": "^5.6.1", "react-colorful": "^5.6.1",
"react-dnd": "^16.0.1", "react-dnd": "^16.0.1",
"react-dnd-html5-backend": "^16.0.1", "react-dnd-html5-backend": "^16.0.1",
"react-dom": "^19.0.0", "react-dom": "^18.3.1",
"react-query": "^3.39.3", "react-query": "^3.39.3",
"react-redux": "^9.1.2", "react-redux": "^9.1.2",
"reconnecting-websocket": "^4.4.0", "reconnecting-websocket": "^4.4.0",
@@ -73,7 +73,7 @@ const page = new NamedPage('domain_user', () => {
function ensureAndGetSelectedUsers() { function ensureAndGetSelectedUsers() {
const users = _.map( const users = _.map(
$('.domain-users tbody [type="checkbox"]:checked'), $('.domain-users tbody [type="checkbox"]:checked'),
(ch) => $(ch).closest('tr').attr('data-uid'), (ch) => $(ch).attr('data-uid') || $(ch).closest('tr').attr('data-uid'),
); );
if (users.length === 0) { if (users.length === 0) {
Notification.error(i18n('Please select at least one user to perform this operation.')); Notification.error(i18n('Please select at least one user to perform this operation.'));
+15 -2
View File
@@ -75,8 +75,20 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{%- for role in roles -%} {%- for role, udocs in rudocs -%}
{%- for rudoc in rudocs[role._id] -%} {%- if udocs|length > 50 -%}
<tr>
<td colspan="3" style="text-wrap: wrap;"><div style="max-height: 300px; overflow-y: auto">
{%- for udoc in udocs -%}
{% set is_disabled=(rudoc._id == handler.user._id) %}
<input type="checkbox" data-uid="{{udoc._id}}" data-checkbox-group="user" {% if is_disabled %}disabled{% else %}data-checkbox-range{% endif %}>
[{{udoc._id}}]{{ user.render_inline(udoc, avatar=false, badge=false) }}&nbsp;&nbsp;&nbsp;
{%- endfor -%}
</div></td>
<td>{{ role }}</td>
</tr>
{%- else -%}
{%- for rudoc in udocs -%}
{% set is_disabled=(rudoc._id == handler.user._id) %} {% set is_disabled=(rudoc._id == handler.user._id) %}
<tr data-uid="{{ rudoc._id }}"> <tr data-uid="{{ rudoc._id }}">
<td class="col--checkbox"> <td class="col--checkbox">
@@ -101,6 +113,7 @@
</td> </td>
</tr> </tr>
{%- endfor -%} {%- endfor -%}
{%- endif -%}
{%- endfor -%} {%- endfor -%}
</tbody> </tbody>
</table> </table>
@@ -0,0 +1,5 @@
<pre>
{%- for role in roles -%}{%- for rudoc in rudocs[role._id] -%}
{{ rudoc._id }},{{ rudoc.role }},{{ udict[rudoc._id].uname }},{{ udict[rudoc._id].displayName}}
{% endfor -%}{%- endfor -%}
</pre>