mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-20 01:38:19 +08:00
拆分域管理与系统管理
This commit is contained in:
1 parent
385e46ae42
commit
faec4744d7
24 files changed
+249
-168
No files matched your search
@@ -11,7 +11,7 @@ jobs:
|
|||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- uses: actions/setup-node@v1
|
- uses: actions/setup-node@v1
|
||||||
with:
|
with:
|
||||||
node_version: '13.x'
|
node-version: '13.x'
|
||||||
- run: cd ui && yarn && yarn build:production && cd ..
|
- run: cd ui && yarn && yarn build:production && cd ..
|
||||||
- uses: actions/upload-artifact@v1
|
- uses: actions/upload-artifact@v1
|
||||||
with:
|
with:
|
||||||
|
|||||||
@@ -0,0 +1,147 @@
|
|||||||
|
const user = require('../model/user');
|
||||||
|
const domain = require('../model/domain');
|
||||||
|
const { Route, Handler } = require('../service/server');
|
||||||
|
const { PERM_MANAGE } = require('../permission');
|
||||||
|
const { RoleAlreadyExistError, ValidationError } = require('../error');
|
||||||
|
|
||||||
|
class ManageHandler extends Handler {
|
||||||
|
async prepare({ domainId }) {
|
||||||
|
this.checkPerm(PERM_MANAGE);
|
||||||
|
this.domain = await domain.get(domainId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DomainEditHandler extends ManageHandler {
|
||||||
|
async get() {
|
||||||
|
const path = [
|
||||||
|
['Hydro', '/'],
|
||||||
|
['domain', '/domain'],
|
||||||
|
['domain_edit', null],
|
||||||
|
];
|
||||||
|
this.response.template = 'domain_edit.html';
|
||||||
|
this.response.body = { domain: this.domain, path };
|
||||||
|
}
|
||||||
|
|
||||||
|
async post({
|
||||||
|
domainId, name, gravatar, bulletin,
|
||||||
|
}) {
|
||||||
|
await domain.edit(domainId, { name, gravatar, bulletin });
|
||||||
|
this.response.redirect = '/domain/dashboard';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DomainDashboardHandler extends ManageHandler {
|
||||||
|
async get() {
|
||||||
|
const path = [
|
||||||
|
['Hydro', '/'],
|
||||||
|
['domain', '/domain'],
|
||||||
|
['domain_dashboard', null],
|
||||||
|
];
|
||||||
|
this.response.template = 'domain_dashboard.html';
|
||||||
|
this.response.body = { domain: this.domain, path };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DomainUserHandler extends ManageHandler {
|
||||||
|
async get({ domainId }) {
|
||||||
|
const uids = [];
|
||||||
|
const rudocs = {};
|
||||||
|
const [udocs, roles] = await Promise.all([
|
||||||
|
user.getInDomain(domainId),
|
||||||
|
user.getRoles(domainId),
|
||||||
|
]);
|
||||||
|
for (const role of roles) rudocs[role._id] = [];
|
||||||
|
for (const udoc of udocs) {
|
||||||
|
uids.push(udoc.uid);
|
||||||
|
// TODO Improve here
|
||||||
|
// eslint-disable-next-line no-await-in-loop
|
||||||
|
const ud = await user.getById(domainId, udoc.uid);
|
||||||
|
rudocs[udoc.role].push({ ...ud, role: udoc.role });
|
||||||
|
}
|
||||||
|
const rolesSelect = roles.map((role) => [role._id, role._id]);
|
||||||
|
const udict = await user.getList(domainId, uids);
|
||||||
|
const path = [
|
||||||
|
['Hydro', '/'],
|
||||||
|
['domain', '/domain'],
|
||||||
|
['domain_user', null],
|
||||||
|
];
|
||||||
|
this.response.template = 'domain_user.html';
|
||||||
|
this.response.body = {
|
||||||
|
roles, rolesSelect, rudocs, udict, path, domain: this.domain,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async postSetUser({ domainId, uid, role }) {
|
||||||
|
await user.setRole(domainId, uid, role);
|
||||||
|
this.back();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DomainPermissionHandler extends ManageHandler {
|
||||||
|
async get({ domainId }) {
|
||||||
|
const roles = await user.getRoles(domainId);
|
||||||
|
const path = [
|
||||||
|
['Hydro', '/'],
|
||||||
|
['domain', '/domain'],
|
||||||
|
['domain_permission', null],
|
||||||
|
];
|
||||||
|
this.response.template = 'domain_permission.html';
|
||||||
|
this.response.body = { roles, domain: this.domain, path };
|
||||||
|
}
|
||||||
|
|
||||||
|
async post({ domainId }) {
|
||||||
|
const roles = {};
|
||||||
|
for (const role in this.request.body) {
|
||||||
|
if (this.request.body[role] instanceof Array) {
|
||||||
|
roles[role] = this.request.body[role].join('');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await user.setRoles(domainId, roles);
|
||||||
|
this.back();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DomainRoleHandler extends ManageHandler {
|
||||||
|
async get({ domainId }) {
|
||||||
|
const roles = await user.getRoles(domainId);
|
||||||
|
const path = [
|
||||||
|
['Hydro', '/'],
|
||||||
|
['domain', '/domain'],
|
||||||
|
['domain_role', null],
|
||||||
|
];
|
||||||
|
this.response.template = 'domain_role.html';
|
||||||
|
this.response.body = { roles, domain: this.domain, path };
|
||||||
|
}
|
||||||
|
|
||||||
|
async postAdd({ domainId, role }) {
|
||||||
|
const [r, u] = await Promise.all([
|
||||||
|
user.getRole(domainId, role),
|
||||||
|
user.getRole(domainId, 'default'),
|
||||||
|
]);
|
||||||
|
if (r) throw new RoleAlreadyExistError(role);
|
||||||
|
await user.addRole(domainId, role, u.perm);
|
||||||
|
this.back();
|
||||||
|
}
|
||||||
|
|
||||||
|
async postDelete({ roles }) {
|
||||||
|
for (const role of roles) {
|
||||||
|
if (['root', 'default', 'guest'].includes(role)) {
|
||||||
|
throw new ValidationError('role');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await user.deleteRoles(roles);
|
||||||
|
this.back();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function apply() {
|
||||||
|
Route('/domain/dashboard', DomainDashboardHandler);
|
||||||
|
Route('/domain/edit', DomainEditHandler);
|
||||||
|
Route('/domain/user', DomainUserHandler);
|
||||||
|
Route('/domain/permission', DomainPermissionHandler);
|
||||||
|
Route('/domain/role', DomainRoleHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
global.Hydro.handler.domain = module.exports = {
|
||||||
|
apply,
|
||||||
|
};
|
||||||
+1
-128
@@ -1,4 +1,3 @@
|
|||||||
const user = require('../model/user');
|
|
||||||
const domain = require('../model/domain');
|
const domain = require('../model/domain');
|
||||||
const setting = require('../model/setting');
|
const setting = require('../model/setting');
|
||||||
const system = require('../model/system');
|
const system = require('../model/system');
|
||||||
@@ -6,7 +5,7 @@ const { Route, Handler } = require('../service/server');
|
|||||||
const { PERM_MANAGE } = require('../permission');
|
const { PERM_MANAGE } = require('../permission');
|
||||||
const hpm = require('../lib/hpm');
|
const hpm = require('../lib/hpm');
|
||||||
const loader = require('../loader');
|
const loader = require('../loader');
|
||||||
const { RoleAlreadyExistError, ValidationError, PermissionError } = require('../error');
|
const { PermissionError } = require('../error');
|
||||||
|
|
||||||
class ManageHandler extends Handler {
|
class ManageHandler extends Handler {
|
||||||
async prepare({ domainId }) {
|
async prepare({ domainId }) {
|
||||||
@@ -33,124 +32,6 @@ class ManageDashboardHandler extends ManageHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ManageEditHandler extends ManageHandler {
|
|
||||||
async get() {
|
|
||||||
const path = [
|
|
||||||
['Hydro', '/'],
|
|
||||||
['manage', '/manage'],
|
|
||||||
['manage_edit', null],
|
|
||||||
];
|
|
||||||
this.response.template = 'manage_edit.html';
|
|
||||||
this.response.body = { domain: this.domain, path };
|
|
||||||
}
|
|
||||||
|
|
||||||
async post({
|
|
||||||
domainId, name, gravatar, bulletin,
|
|
||||||
}) {
|
|
||||||
await domain.edit(domainId, { name, gravatar, bulletin });
|
|
||||||
this.response.redirect = '/manage/dashboard';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ManageUserHandler extends ManageHandler {
|
|
||||||
async get({ domainId }) {
|
|
||||||
// FIXME(masnn) UPDATE CODE
|
|
||||||
const uids = [];
|
|
||||||
const rudocs = {};
|
|
||||||
const [udocs, roles] = await Promise.all([
|
|
||||||
user.getInDomain(domainId),
|
|
||||||
user.getRoles(domainId),
|
|
||||||
]);
|
|
||||||
for (const role of roles) rudocs[role._id] = [];
|
|
||||||
for (const udoc of udocs) {
|
|
||||||
uids.push(udoc.uid);
|
|
||||||
// TODO Improve here
|
|
||||||
// eslint-disable-next-line no-await-in-loop
|
|
||||||
const ud = await user.getById(domainId, udoc.uid);
|
|
||||||
rudocs[udoc.role].push({ ...ud, role: udoc.role });
|
|
||||||
}
|
|
||||||
const rolesSelect = roles.map((role) => [role._id, role._id]);
|
|
||||||
const udict = await user.getList(domainId, uids);
|
|
||||||
const path = [
|
|
||||||
['Hydro', '/'],
|
|
||||||
['manage', '/manage'],
|
|
||||||
['manage_user', null],
|
|
||||||
];
|
|
||||||
this.response.template = 'manage_user.html';
|
|
||||||
this.response.body = {
|
|
||||||
roles, rolesSelect, rudocs, udict, path,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
async postSetUser({ domainId, uid, role }) {
|
|
||||||
await user.setRole(domainId, uid, role);
|
|
||||||
this.back();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ManagePermissionHandler extends ManageHandler {
|
|
||||||
async get({ domainId }) {
|
|
||||||
const [roles, d] = await Promise.all([
|
|
||||||
user.getRoles(domainId),
|
|
||||||
domain.get(domainId),
|
|
||||||
]);
|
|
||||||
const path = [
|
|
||||||
['Hydro', '/'],
|
|
||||||
['manage', '/manage'],
|
|
||||||
['manage_permission', null],
|
|
||||||
];
|
|
||||||
this.response.template = 'manage_permission.html';
|
|
||||||
this.response.body = { roles, domain: d, path };
|
|
||||||
}
|
|
||||||
|
|
||||||
async post({ domainId }) {
|
|
||||||
const roles = {};
|
|
||||||
for (const role in this.request.body) {
|
|
||||||
if (this.request.body[role] instanceof Array) {
|
|
||||||
roles[role] = this.request.body[role].join('');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
await user.setRoles(domainId, roles);
|
|
||||||
this.back();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ManageRoleHandler extends ManageHandler {
|
|
||||||
async get({ domainId }) {
|
|
||||||
const [roles, d] = await Promise.all([
|
|
||||||
user.getRoles(domainId),
|
|
||||||
domain.get(domainId),
|
|
||||||
]);
|
|
||||||
const path = [
|
|
||||||
['Hydro', '/'],
|
|
||||||
['manage', '/manage'],
|
|
||||||
['manage_role', null],
|
|
||||||
];
|
|
||||||
this.response.template = 'manage_role.html';
|
|
||||||
this.response.body = { roles, domain: d, path };
|
|
||||||
}
|
|
||||||
|
|
||||||
async postAdd({ domainId, role }) {
|
|
||||||
const [r, u] = await Promise.all([
|
|
||||||
user.getRole(domainId, role),
|
|
||||||
user.getRole(domainId, 'default'),
|
|
||||||
]);
|
|
||||||
if (r) throw new RoleAlreadyExistError(role);
|
|
||||||
await user.addRole(domainId, role, u.perm);
|
|
||||||
this.back();
|
|
||||||
}
|
|
||||||
|
|
||||||
async postDelete({ roles }) {
|
|
||||||
for (const role of roles) {
|
|
||||||
if (['root', 'default', 'guest'].includes(role)) {
|
|
||||||
throw new ValidationError('role');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
await user.deleteRoles(roles);
|
|
||||||
this.back();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class SystemHandler extends Handler {
|
class SystemHandler extends Handler {
|
||||||
async prepare() {
|
async prepare() {
|
||||||
if (!this.user.priv) throw new PermissionError('???');
|
if (!this.user.priv) throw new PermissionError('???');
|
||||||
@@ -210,10 +91,6 @@ class SystemSettingHandler extends SystemHandler {
|
|||||||
async function apply() {
|
async function apply() {
|
||||||
Route('/manage', module.exports.ManageMainHandler);
|
Route('/manage', module.exports.ManageMainHandler);
|
||||||
Route('/manage/dashboard', module.exports.ManageDashboardHandler);
|
Route('/manage/dashboard', module.exports.ManageDashboardHandler);
|
||||||
Route('/manage/edit', module.exports.ManageEditHandler);
|
|
||||||
Route('/manage/user', module.exports.ManageUserHandler);
|
|
||||||
Route('/manage/permission', module.exports.ManagePermissionHandler);
|
|
||||||
Route('/manage/role', module.exports.ManageRoleHandler);
|
|
||||||
Route('/manage/module', SystemModuleHandler);
|
Route('/manage/module', SystemModuleHandler);
|
||||||
Route('/manage/setting', SystemSettingHandler);
|
Route('/manage/setting', SystemSettingHandler);
|
||||||
}
|
}
|
||||||
@@ -221,10 +98,6 @@ async function apply() {
|
|||||||
global.Hydro.handler.manage = module.exports = {
|
global.Hydro.handler.manage = module.exports = {
|
||||||
ManageMainHandler,
|
ManageMainHandler,
|
||||||
ManageDashboardHandler,
|
ManageDashboardHandler,
|
||||||
ManageEditHandler,
|
|
||||||
ManageUserHandler,
|
|
||||||
ManagePermissionHandler,
|
|
||||||
ManageRoleHandler,
|
|
||||||
SystemModuleHandler,
|
SystemModuleHandler,
|
||||||
SystemSettingHandler,
|
SystemSettingHandler,
|
||||||
apply,
|
apply,
|
||||||
|
|||||||
@@ -32,7 +32,13 @@ class StatusHandler extends Handler {
|
|||||||
class StatusUpdateHandler extends Handler {
|
class StatusUpdateHandler extends Handler {
|
||||||
async post(args) {
|
async post(args) {
|
||||||
this.checkPerm(PERM_JUDGE);
|
this.checkPerm(PERM_JUDGE);
|
||||||
await coll.updateOne({ _id: args._id }, { $set: args }, { upsert: true });
|
await coll.updateOne({ _id: args._id }, { $set: { ...args, type: 'judger' } }, { upsert: true });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SwitchLanguageHandler extends Handler {
|
||||||
|
async get({ lang }) {
|
||||||
|
this.session.language = lang;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,6 +47,7 @@ async function apply() {
|
|||||||
Route('/fs/:id/:name/:secret', FileDownloadHandler);
|
Route('/fs/:id/:name/:secret', FileDownloadHandler);
|
||||||
Route('/status', StatusHandler);
|
Route('/status', StatusHandler);
|
||||||
Route('/status/update', StatusUpdateHandler);
|
Route('/status/update', StatusUpdateHandler);
|
||||||
|
Route('/language/:lang', SwitchLanguageHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
global.Hydro.handler.misc = module.exports = {
|
global.Hydro.handler.misc = module.exports = {
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ class UserRegisterHandler extends Handler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async post({ mail }) {
|
async post({ mail }) {
|
||||||
if (await user.getByEmail(mail, true)) throw new UserAlreadyExistError(mail);
|
if (await user.getByEmail('system', mail, true)) throw new UserAlreadyExistError(mail);
|
||||||
this.limitRate('send_mail', 3600, 30);
|
this.limitRate('send_mail', 3600, 30);
|
||||||
const t = await token.add(
|
const t = await token.add(
|
||||||
token.TYPE_REGISTRATION,
|
token.TYPE_REGISTRATION,
|
||||||
@@ -62,7 +62,9 @@ class UserRegisterHandler extends Handler {
|
|||||||
{ mail },
|
{ mail },
|
||||||
);
|
);
|
||||||
if (await system.get('smtp.user')) {
|
if (await system.get('smtp.user')) {
|
||||||
const m = await this.renderHTML('user_register_mail', { url: `/register/${t[0]}` });
|
const m = await this.renderHTML('user_register_mail.html', {
|
||||||
|
url: `${await system.get('baseurl')}/register/${t[0]}`,
|
||||||
|
});
|
||||||
await sendMail(mail, 'Sign Up', 'user_register_mail', m);
|
await sendMail(mail, 'Sign Up', 'user_register_mail', m);
|
||||||
this.response.template = 'user_register_mail_sent.html';
|
this.response.template = 'user_register_mail_sent.html';
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+1
-1
@@ -14,6 +14,6 @@ Item('/t', 'training_main', 'training', permission.PERM_VIEW_TRAINING);
|
|||||||
Item('/homework', 'homework_main', 'homework', permission.PERM_VIEW_HOMEWORK);
|
Item('/homework', 'homework_main', 'homework', permission.PERM_VIEW_HOMEWORK);
|
||||||
Item('/discuss', 'discussion_main', 'discussion', permission.PERM_VIEW_DISCUSSION);
|
Item('/discuss', 'discussion_main', 'discussion', permission.PERM_VIEW_DISCUSSION);
|
||||||
Item('/c', 'contest_main', 'contest', permission.PERM_VIEW_CONTEST);
|
Item('/c', 'contest_main', 'contest', permission.PERM_VIEW_CONTEST);
|
||||||
Item('/manage', 'manage', 'manage', permission.PERM_MANAGE);
|
Item('/domain', 'domain_dashboard', 'domain', permission.PERM_MANAGE);
|
||||||
|
|
||||||
global.Hydro.lib.nav = module.exports = Item;
|
global.Hydro.lib.nav = module.exports = Item;
|
||||||
+1
-1
@@ -252,7 +252,7 @@ async function load() {
|
|||||||
const builtinHandler = [
|
const builtinHandler = [
|
||||||
'home', 'problem', 'record', 'judge', 'user',
|
'home', 'problem', 'record', 'judge', 'user',
|
||||||
'contest', 'training', 'discussion', 'manage', 'import',
|
'contest', 'training', 'discussion', 'manage', 'import',
|
||||||
'misc', 'homework',
|
'misc', 'homework', 'domain',
|
||||||
];
|
];
|
||||||
for (const i of builtinHandler) require(`./handler/${i}`);
|
for (const i of builtinHandler) require(`./handler/${i}`);
|
||||||
await model();
|
await model();
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ const SETTINGS_BY_KEY = {};
|
|||||||
for (const setting in SETTINGS) SETTINGS_BY_KEY[setting.key] = setting;
|
for (const setting in SETTINGS) SETTINGS_BY_KEY[setting.key] = setting;
|
||||||
|
|
||||||
const SYSTEM_SETTINGS = [
|
const SYSTEM_SETTINGS = [
|
||||||
|
Setting('setting_basic', 'user.register', null, false, 'checkbox', 'Allow register'),
|
||||||
Setting('setting_smtp', 'smtp.user', null, null, 'text', 'SMTP Username'),
|
Setting('setting_smtp', 'smtp.user', null, null, 'text', 'SMTP Username'),
|
||||||
Setting('setting_smtp', 'smtp.pass', null, null, 'password', 'SMTP Password'),
|
Setting('setting_smtp', 'smtp.pass', null, null, 'password', 'SMTP Password'),
|
||||||
Setting('setting_smtp', 'smtp.host', null, null, 'text', 'SMTP Server Host'),
|
Setting('setting_smtp', 'smtp.host', null, null, 'text', 'SMTP Server Host'),
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ async function postInit() {
|
|||||||
const info = await sysinfo.get();
|
const info = await sysinfo.get();
|
||||||
await coll.updateOne(
|
await coll.updateOne(
|
||||||
{ _id: info._id },
|
{ _id: info._id },
|
||||||
{ $set: { ...info, updateAt: new Date() } },
|
{ $set: { ...info, updateAt: new Date(), type: 'server' } },
|
||||||
{ upsert: true },
|
{ upsert: true },
|
||||||
);
|
);
|
||||||
setInterval(update, 3 * 60 * 1000);
|
setInterval(update, 3 * 60 * 1000);
|
||||||
|
|||||||
@@ -1,26 +1,27 @@
|
|||||||
const { DocumentNotFoundError } = global.Hydro.error;
|
const { DocumentNotFoundError } = global.Hydro.error;
|
||||||
const { db } = global.Hydro.service;
|
const { document } = global.Hydro.model;
|
||||||
|
|
||||||
const coll = db.collection('pastebin');
|
document.TYPE_PASTE = 101;
|
||||||
|
|
||||||
async function add({
|
function add({
|
||||||
owner, language, expire, password, title, content,
|
owner, language, expire, password, title, content,
|
||||||
}) {
|
}) {
|
||||||
const doc = {
|
return document.add(
|
||||||
owner, password, expire, language, title, content,
|
'system', content, owner, document.TYPE_PASTE, null, null, null,
|
||||||
};
|
{
|
||||||
const res = await coll.insertOne(doc);
|
language, expire, title, password,
|
||||||
return res.insertedId;
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function get(_id) {
|
async function get(_id) {
|
||||||
const doc = await coll.findOne({ _id });
|
const doc = await document.get('system', document.TYPE_PASTE, _id);
|
||||||
if (!doc) throw new DocumentNotFoundError(_id);
|
if (!doc) throw new DocumentNotFoundError(_id);
|
||||||
return doc;
|
return doc;
|
||||||
}
|
}
|
||||||
|
|
||||||
function del(_id) {
|
function del(_id) {
|
||||||
return coll.deleteOne({ _id });
|
return document.deleteOne('system', document.TYPE_PASTE, _id);
|
||||||
}
|
}
|
||||||
|
|
||||||
global.Hydro.model.pastebin = module.exports = { add, get, del };
|
global.Hydro.model.pastebin = module.exports = { add, get, del };
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
{% extends "layout/basic.html" %}
|
||||||
|
{% block content %}
|
||||||
|
<div class="row" data-sticky-parent>
|
||||||
|
<div class="medium-9 columns">
|
||||||
|
{% block domain_content %}{% endblock %}
|
||||||
|
</div>
|
||||||
|
<div class="medium-3 columns"><div data-sticky="large">
|
||||||
|
<div class="section side">
|
||||||
|
<ol class="menu">
|
||||||
|
<li class="menu__item">
|
||||||
|
<div class="menu__link expandable">
|
||||||
|
<span class="icon icon-info"></span> {{ _('Properties') }}
|
||||||
|
</div>
|
||||||
|
<ol class="menu collapsed">
|
||||||
|
{{ sidemenu.render_item(null, 'domain_dashboard', '/domain/dashboard') }}
|
||||||
|
{{ sidemenu.render_item(null, 'domain_edit', '/domain/edit') }}
|
||||||
|
</ol>
|
||||||
|
</li>
|
||||||
|
<li class="menu__item">
|
||||||
|
<div class="menu__link expandable">
|
||||||
|
<span class="icon icon-user"></span> {{ _('Access Control') }}
|
||||||
|
</div>
|
||||||
|
<ol class="menu collapsed">
|
||||||
|
{{ sidemenu.render_item(null, 'domain_role', '/domain/role') }}
|
||||||
|
{{ sidemenu.render_item(null, 'domain_user', '/domain/user') }}
|
||||||
|
{{ sidemenu.render_item(null, 'domain_permission', '/domain/permission') }}
|
||||||
|
</ol>
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
</div></div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
{% import "components/user.html" as user %}
|
||||||
|
{% extends "domain_base.html" %}
|
||||||
|
{% block domain_content %}
|
||||||
|
{% if domain.bulletin %}
|
||||||
|
<div class="section">
|
||||||
|
<div class="section__body typo">
|
||||||
|
{{ domain.bulletin|markdown|safe }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
<div class="section">
|
||||||
|
<div class="section__header">
|
||||||
|
<h1 class="section__title" data-heading>{{ _('Information') }}</h1>
|
||||||
|
</div>
|
||||||
|
<div class="section__body typo">
|
||||||
|
<dl class="large horizontal">
|
||||||
|
<dt>{{ _('Gravatar') }}</dt><dd><img src="{{ gravatar(domain.gravatar) }}" width="32" height="32"></dd>
|
||||||
|
<dt>{{ _('Name') }}</dt><dd>{{ domain.name }}</dd>
|
||||||
|
</dl>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
{% import "components/form.html" as form with context %}
|
{% extends "domain_base.html" %}
|
||||||
{% extends "manage_base.html" %}
|
{% block domain_content %}
|
||||||
{% block manage_content %}
|
|
||||||
<div class="section">
|
<div class="section">
|
||||||
<div class="section__body">
|
<div class="section__body">
|
||||||
<form method="post">
|
<form method="post">
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
{% extends "manage_base.html" %}
|
{% extends "domain_base.html" %}
|
||||||
{% block manage_content %}
|
{% block domain_content %}
|
||||||
<form method="post">
|
<form method="post">
|
||||||
<div class="section">
|
<div class="section">
|
||||||
<div class="section__header">
|
<div class="section__header">
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
{% extends "manage_base.html" %}
|
{% extends "domain_base.html" %}
|
||||||
{% block manage_content %}
|
{% block domain_content %}
|
||||||
<div style="display: none" class="dialog__body--create-role">
|
<div style="display: none" class="dialog__body--create-role">
|
||||||
<div>
|
<div>
|
||||||
<div class="row"><div class="columns">
|
<div class="row"><div class="columns">
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
{% extends "manage_base.html" %}
|
{% extends "domain_base.html" %}
|
||||||
{% block manage_content %}
|
{% block domain_content %}
|
||||||
<div style="display: none" class="dialog__body--add-user">
|
<div style="display: none" class="dialog__body--add-user">
|
||||||
<div>
|
<div>
|
||||||
<div class="row"><div class="columns">
|
<div class="row"><div class="columns">
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
{% if handler.has_priv(vj4.model.builtin.PRIV_CREATE_FILE) %}
|
{% if handler.has_priv(vj4.model.builtin.PRIV_CREATE_FILE) %}
|
||||||
<a class="primary rounded button" href="{{ reverse_url('fs_upload') }}" target="_blank"><span class="icon icon-add"></span> {{ _('Upload File') }}</a>
|
<a class="primary rounded button" href="{{ reverse_url('fs_upload') }}" target="_blank"><span class="icon icon-add"></span> {{ _('Upload File') }}</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<a class="tool-button" href="/wiki/help#file"><span class="icon icon-help"></span> {{ _('What\'s file?') }}</a>
|
<a class="tool-button" href="/wiki/help#file"><span class="icon icon-help"></span> {{ _("What's file?") }}</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="section__body no-padding">
|
<div class="section__body no-padding">
|
||||||
|
|||||||
@@ -13,21 +13,10 @@
|
|||||||
</div>
|
</div>
|
||||||
<ol class="menu collapsed">
|
<ol class="menu collapsed">
|
||||||
{{ sidemenu.render_item(null, 'manage_dashboard', '/manage/dashboard') }}
|
{{ sidemenu.render_item(null, 'manage_dashboard', '/manage/dashboard') }}
|
||||||
{{ sidemenu.render_item(null, 'manage_edit', '/manage/edit') }}
|
|
||||||
{{ sidemenu.render_item(null, 'manage_module', '/manage/module') }}
|
{{ sidemenu.render_item(null, 'manage_module', '/manage/module') }}
|
||||||
{{ sidemenu.render_item(null, 'manage_setting', '/manage/setting') }}
|
{{ sidemenu.render_item(null, 'manage_setting', '/manage/setting') }}
|
||||||
</ol>
|
</ol>
|
||||||
</li>
|
</li>
|
||||||
<li class="menu__item">
|
|
||||||
<div class="menu__link expandable">
|
|
||||||
<span class="icon icon-user"></span> {{ _('Access Control') }}
|
|
||||||
</div>
|
|
||||||
<ol class="menu collapsed">
|
|
||||||
{{ sidemenu.render_item(null, 'manage_role', '/manage/role') }}
|
|
||||||
{{ sidemenu.render_item(null, 'manage_user', '/manage/user') }}
|
|
||||||
{{ sidemenu.render_item(null, 'manage_permission', '/manage/permission') }}
|
|
||||||
</ol>
|
|
||||||
</li>
|
|
||||||
</ol>
|
</ol>
|
||||||
</div>
|
</div>
|
||||||
</div></div>
|
</div></div>
|
||||||
|
|||||||
@@ -53,6 +53,13 @@
|
|||||||
value:current[setting.key] or setting.value,
|
value:current[setting.key] or setting.value,
|
||||||
markdown:true
|
markdown:true
|
||||||
}) }}
|
}) }}
|
||||||
|
{% elif setting.ui == 'checkbox' %}
|
||||||
|
{{ form.form_checkbox({
|
||||||
|
label:setting.name,
|
||||||
|
help_text:setting.desc,
|
||||||
|
name:setting.key,
|
||||||
|
value:current[setting.key] or setting.value
|
||||||
|
})}}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
File renamed without changes.
@@ -9,7 +9,7 @@ import tpl from 'vj/utils/tpl';
|
|||||||
import delay from 'vj/utils/delay';
|
import delay from 'vj/utils/delay';
|
||||||
import i18n from 'vj/utils/i18n';
|
import i18n from 'vj/utils/i18n';
|
||||||
|
|
||||||
const page = new NamedPage('manage_role', () => {
|
const page = new NamedPage('domain_role', () => {
|
||||||
const createRoleDialog = new ActionDialog({
|
const createRoleDialog = new ActionDialog({
|
||||||
$body: $('.dialog__body--create-role > div'),
|
$body: $('.dialog__body--create-role > div'),
|
||||||
onDispatch(action) {
|
onDispatch(action) {
|
||||||
File renamed without changes.
@@ -10,7 +10,7 @@ import tpl from 'vj/utils/tpl';
|
|||||||
import delay from 'vj/utils/delay';
|
import delay from 'vj/utils/delay';
|
||||||
import i18n from 'vj/utils/i18n';
|
import i18n from 'vj/utils/i18n';
|
||||||
|
|
||||||
const page = new NamedPage('manage_user', () => {
|
const page = new NamedPage('domain_user', () => {
|
||||||
const addUserSelector = UserSelectAutoComplete.getOrConstruct($('.dialog__body--add-user [name="user"]'));
|
const addUserSelector = UserSelectAutoComplete.getOrConstruct($('.dialog__body--add-user [name="user"]'));
|
||||||
const addUserDialog = new ActionDialog({
|
const addUserDialog = new ActionDialog({
|
||||||
$body: $('.dialog__body--add-user > div'),
|
$body: $('.dialog__body--add-user > div'),
|
||||||
File renamed without changes.
Reference in new issue
Block a user