core&ui: add manage user priv (#433)

This commit is contained in:
panda authored and GitHub committed 2022-10-06 21:22:24 +08:00
1 parent b36adcdf13
commit a5494b1345
13 files changed
+274 -11

No files matched your search

+4
View File
@@ -475,6 +475,7 @@ manage_join_applications: 加域申请
manage_module: 管理模块
manage_script: 脚本管理
manage_setting: 系统设置
manage_user_priv: 用户权限
manage: 管理
Manage: 管理
Manager: 管理
@@ -594,6 +595,7 @@ Pretest Data: 自测数据
Pretest Your Code: 使用自定义数据测试
Pretest: 自测
Pretest?: 自测?
Privilege: 权限
Privacy: 隐私
Problem {1} not found.: 题目 {1} 不存在。
Problem Data: 题目数据
@@ -727,6 +729,7 @@ Send Verification Email: 发送验证邮件
Send: 发送
Seperated with ',': 用 ',' 分隔
Service Status: 服务状态
Set Privilege: 设置权限
Set Role: 设置角色
Set Roles for Selected User: 设置所选用户的角色
Set Roles for selected users: 为所选用户设置角色
@@ -881,6 +884,7 @@ User-defined role: 用户定义的角色
User: 用户
Username / UID: 用户名或 UID
Username: 用户名
User Privilege: 用户权限
Users with those roles will be removed from the domain.: 拥有这些角色的用户将从此域中移除。
Users: 用户
Using your {0} universal account: 使用您的 {0} 通用账户
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@hydrooj/ui-default",
"version": "4.41.4",
"version": "4.41.5",
"author": "undefined <i@undefined.moe>",
"license": "AGPL-3.0",
"main": "index.ts",
@@ -0,0 +1,61 @@
import $ from 'jquery';
import { ActionDialog } from 'vj/components/dialog';
import Notification from 'vj/components/notification';
import selectUser from 'vj/components/selectUser';
import { NamedPage } from 'vj/misc/Page';
import i18n from 'vj/utils/i18n';
import pjax from 'vj/utils/pjax';
import request from 'vj/utils/request';
const page = new NamedPage('manage_user_priv', () => {
const setPrivDialog = new ActionDialog({
$body: $('.dialog__body--set-priv > div'),
});
setPrivDialog.clear = function (priv) {
this.$dom.find('input.priv[type=checkbox]:hidden').each((i, e) => {
e.checked = priv & e.value;
});
return this;
};
async function changeUserPriv(uid, priv) {
try {
const res = await request.post('', uid !== 'default' ? {
uid,
priv,
} : { priv });
if (res.url && res.url !== window.location.href) window.location.href = res.url;
else {
Notification.success(i18n('Priv has been updated to {0}.', priv));
pjax.request({ push: false });
}
} catch (error) {
Notification.error(error.message);
}
}
async function handleOpenUserPrivDialog(ev) {
const uid = ev.target ? $(ev.target).data('uid') : ev._id;
const priv = ev.target ? $(ev.target).data('priv') : ev.priv;
await setPrivDialog.clear(priv);
const action = await setPrivDialog.open();
if (action !== 'ok') return;
let userPriv = 0;
setPrivDialog.$dom.find('input.priv[type=checkbox]').each((i, e) => {
if (e.checked) userPriv |= e.value;
});
changeUserPriv(uid, userPriv);
}
async function handleClickSelectUser() {
const target = await selectUser();
if (!target) return;
const user = await request.get(`/user/${target._id}`);
handleOpenUserPrivDialog(user.udoc);
}
$('[name="select_user"]').on('click', () => handleClickSelectUser());
$('[name="set_priv"]').on('click', (ev) => handleOpenUserPrivDialog(ev));
});
export default page;
@@ -0,0 +1,18 @@
.page--manage_user_priv
.col--uid
width: 100px
.col--priv
width: 100px
.col--actions
width: 100px
.priv_plus
color: green
.priv_minus
color: red
.col--p
width: 30px
@@ -15,6 +15,7 @@
{{ sidemenu.render_item(null, 'manage_dashboard') }}
{{ sidemenu.render_item(null, 'manage_script') }}
{{ sidemenu.render_item(null, 'manage_user_import') }}
{{ sidemenu.render_item(null, 'manage_user_priv') }}
{{ sidemenu.render_item(null, 'manage_setting') }}
{{ sidemenu.render_item(null, 'manage_config') }}
</ol>
@@ -0,0 +1,76 @@
{% extends "manage_base.html" %}
{% block manage_content %}
<div style="display: none" class="dialog__body--set-priv">
<div>
<div class="row"><div class="columns">
<h1>{{ _('Set Privilege') }}</h1>
</div></div>
{% set _mark = Math.ceil(Object.keys(Priv).length/3) %}
{% macro col(PRIVS) %}
<div class="medium-4 columns">
<table class="data-table priv_table">
<colgroup>
<col class="col--description">
<col class="col--p">
</colgroup>
<thead>
<tr>
<th class="col--description">{{ _('Name') }}</th>
<th class="col--p">{{ _('Privilege') }}</th>
</tr>
</thead>
<tbody>
{%- for p in PRIVS -%}
<tr>
<td class="col--description">
{{ _(p) }}
</td>
<td class="col--p">
<label class="compact checkbox">
<input class="priv" name="{{ p }}" data-checkbox-group="priv" data-checkbox-range value="{{ Priv[p] }}" type="checkbox">
</label>
</td>
</tr>
{%- endfor -%}
</tbody>
</table>
</div>
{% endmacro %}
<div class="row">
{{ col(Object.keys(Priv).slice(0, _mark)) }}
{{ col(Object.keys(Priv).slice(_mark, _mark*2)) }}
{{ col(Object.keys(Priv).slice(_mark*2, _mark*3)) }}
</div>
</div>
</div>
<div class="section">
<div class="section__header">
<h1 class="section__title">{{ _('User Privilege') }}</h1>
<div class="section__tools">
<button class="primary rounded button" name="select_user"><span class="icon icon-search"></span>{{ _('Select User') }}</button>
</div>
</div>
{{ noscript_note.render() }}
<div class="section__body no-padding">
<table class="data-table">
<colgroup>
<col class="col--uid">
<col class="col--user">
<col class="col--priv_info">
<col class="col--priv">
<col class="col--actions">
</colgroup>
<thead>
<tr>
<th class="col--uid">{{ _('User ID') }}</th>
<th class="col--user">{{ _('Username') }}</th>
<td class="col--priv_info">{{ _('Privilege') }}</th>
<th class="col--priv">{{ _('Value') }}</th>
<th class="col--actions">{{ _('Actions') }}</th>
</tr>
</thead>
{% include "partials/manage_user_priv.html" %}
</table>
</div>
</div>
{% endblock %}
@@ -0,0 +1,55 @@
{% import "components/user.html" as user with context %}
<tbody data-fragment-id="user_priv-tbody">
<tr data-uid="{{ udoc._id }}">
<td class="col--uid">
#
</td>
<td class="col--user">
Default Privilege
</td>
<td class="col--priv_info">
{%- for name, priv in Priv -%}
{%- if defaultPriv|bitand(priv) -%}
{{ name }}<br>
{%- endif -%}
{%- endfor -%}
</td>
<td class="col--priv" title="{{ defaultPriv }}">
{{ defaultPriv }}
</td>
<td class="col--actions">
<a name="set_priv" data-uid="default" data-priv="{{ defaultPriv }}">{{ _('Edit') }}</a>
</td>
</tr>
{%- for udoc in udocs -%}
<tr data-uid="{{ udoc._id }}">
<td class="col--uid">
{{ udoc._id }}
</td>
<td class="col--user">
{{ user.render_inline(udoc, badge=false) }}
</td>
<td class="col--priv_info">
{%- if udoc.priv == 0 -%}
PRIV_NONE
{%- elif udoc.priv == -1 -%}
PRIV_ALL
{%- else -%}
{%- for name, priv in Priv -%}
{%- if priv|bitand(udoc.priv) and not priv|bitand(defaultPriv) -%}
<p class="priv_plus">+{{ name }}</p>
{%- elif priv|bitand(defaultPriv) and not priv|bitand(udoc.priv) -%}
<p class="priv_minus">-{{ name }}</p>
{%- endif -%}
{%- endfor -%}
{%- endif -%}
</td>
<td class="col--priv" title="{{ udoc.priv }}">
{{ udoc.priv }}
</td>
<td class="col--actions">
<a name="set_priv" data-uid="{{ udoc._id }}" data-priv="{{ udoc.priv }}">{{ _('Edit') }}</a>
</td>
</tr>
{%- endfor -%}
</tbody>