Skip to content

Commit

Permalink
ui: better domain_user page performance
Browse files Browse the repository at this point in the history
  • Loading branch information
undefined-moe committed Dec 11, 2024
1 parent f521867 commit 00392f1
Show file tree
Hide file tree
Showing 7 changed files with 35 additions and 15 deletions.
2 changes: 1 addition & 1 deletion framework/eslint-config/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"license": "MIT",
"main": "react.yaml",
"dependencies": {
"@stylistic/eslint-plugin": "^2.11.0",
"@stylistic/eslint-plugin": "^2.12.0",
"@typescript-eslint/eslint-plugin": "^8.17.0",
"@typescript-eslint/parser": "^8.17.0",
"eslint-config-airbnb": "^19.0.4",
Expand Down
17 changes: 8 additions & 9 deletions packages/hydrooj/src/handler/domain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ class DomainDashboardHandler extends ManageHandler {

class DomainUserHandler extends ManageHandler {
@requireSudo
async get({ domainId }) {
@param('format', Types.Range(['default', 'raw']), true)
async get({ domainId }, format = 'default') {
const rudocs = {};
const [dudocs, roles] = await Promise.all([
domain.getMultiUserInDomain(domainId, {
Expand All @@ -107,15 +108,13 @@ class DomainUserHandler extends ManageHandler {
}).toArray(),
domain.getRoles(domainId),
]);
const uids = dudocs.map((dudoc) => dudoc.uid);
const udict = await user.getList(domainId, uids);
for (const role of roles) rudocs[role._id] = [];
for (const dudoc of dudocs) {
const udoc = udict[dudoc.uid];
if (!(udoc.priv & PRIV.PRIV_USER_PROFILE)) continue;
rudocs[udoc.role || 'default'].push(udoc);
// TODO: switch to getListForRender for better performance
const udict = await user.getList(domainId, dudocs.map((dudoc) => dudoc.uid));
const users = dudocs.filter((dudoc) => udict[dudoc.uid].priv & PRIV.PRIV_USER_PROFILE);
for (const role of roles) {
rudocs[role._id] = users.filter((dudoc) => dudoc.role === role._id).map((i) => udict[i.uid]);
}
this.response.template = 'domain_user.html';
this.response.template = format === 'raw' ? 'domain_user_raw.html' : 'domain_user.html';
this.response.body = {
roles, rudocs, udict, domain: this.domain,
};
Expand Down
3 changes: 3 additions & 0 deletions packages/ui-default/backendlib/template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ env.addGlobal('platformIcon', (platform) => {
});

const render = (name: string, state: any) => new Promise<string>((resolve, reject) => {
const start = Date.now();
env.render(name, {
page_name: name.split('.')[0],
...state,
Expand All @@ -180,6 +181,8 @@ const render = (name: string, state: any) => new Promise<string>((resolve, rejec
STATUS,
UiContext: state.handler?.UiContext || {},
}, (err, res) => {
const end = Date.now();
if (end - start > 5000) console.error(`Render of ${name} took ${end - start}ms`);
if (err) reject(err);
else resolve(res);
});
Expand Down
4 changes: 2 additions & 2 deletions packages/ui-default/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,11 @@
"prop-types": "^15.8.1",
"qface": "^1.4.1",
"qrcode": "^1.5.4",
"react": "^19.0.0",
"react": "^18.3.1",
"react-colorful": "^5.6.1",
"react-dnd": "^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-redux": "^9.1.2",
"reconnecting-websocket": "^4.4.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/ui-default/pages/domain_user.page.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ const page = new NamedPage('domain_user', () => {
function ensureAndGetSelectedUsers() {
const users = _.map(
$('.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) {
Notification.error(i18n('Please select at least one user to perform this operation.'));
Expand Down
17 changes: 15 additions & 2 deletions packages/ui-default/templates/domain_user.html
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,20 @@ <h1 class="section__title">{{ _('{0}: Users').format(domain.name) }}</h1>
</tr>
</thead>
<tbody>
{%- for role in roles -%}
{%- for rudoc in rudocs[role._id] -%}
{%- for role, udocs in rudocs -%}
{%- 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) %}
<tr data-uid="{{ rudoc._id }}">
<td class="col--checkbox">
Expand All @@ -101,6 +113,7 @@ <h1 class="section__title">{{ _('{0}: Users').format(domain.name) }}</h1>
</td>
</tr>
{%- endfor -%}
{%- endif -%}
{%- endfor -%}
</tbody>
</table>
Expand Down
5 changes: 5 additions & 0 deletions packages/ui-default/templates/domain_user_raw.html
Original file line number Diff line number Diff line change
@@ -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>

0 comments on commit 00392f1

Please sign in to comment.