mirror of
https://github.com/flarum/framework.git
synced 2025-02-21 07:11:56 +08:00
Improve permissions page
- Introduce the concept of "required permissions" - basically a permission dependency tree. In order for a group to be granted one permission, they must also have another. - Improve redraw performance by not building dropdown menu contents until dropdown is opened ref #904
This commit is contained in:
parent
1177880483
commit
240aa9e83b
167
js/admin/dist/app.js
vendored
167
js/admin/dist/app.js
vendored
@ -16609,6 +16609,22 @@ System.register('flarum/app', ['flarum/App', 'flarum/initializers/store', 'flaru
|
||||
|
||||
app.extensionSettings = {};
|
||||
|
||||
app.getRequiredPermissions = function (permission) {
|
||||
var required = [];
|
||||
|
||||
if (permission === 'startDiscussion' || permission.indexOf('discussion.') === 0) {
|
||||
required.push('viewDiscussions');
|
||||
}
|
||||
if (permission === 'discussion.delete') {
|
||||
required.push('discussion.hide');
|
||||
}
|
||||
if (permission === 'discussion.deletePosts') {
|
||||
required.push('discussion.editPosts');
|
||||
}
|
||||
|
||||
return required;
|
||||
};
|
||||
|
||||
_export('default', app);
|
||||
}
|
||||
};
|
||||
@ -18080,13 +18096,18 @@ System.register('flarum/components/Dropdown', ['flarum/Component', 'flarum/helpe
|
||||
}
|
||||
|
||||
babelHelpers.createClass(Dropdown, [{
|
||||
key: 'init',
|
||||
value: function init() {
|
||||
this.showing = false;
|
||||
}
|
||||
}, {
|
||||
key: 'view',
|
||||
value: function view() {
|
||||
var items = this.props.children ? listItems(this.props.children) : [];
|
||||
|
||||
return m(
|
||||
'div',
|
||||
{ className: 'ButtonGroup Dropdown dropdown ' + this.props.className + ' itemCount' + items.length },
|
||||
{ className: 'ButtonGroup Dropdown dropdown ' + this.props.className + ' itemCount' + items.length + (this.showing ? ' open' : '') },
|
||||
this.getButton(),
|
||||
this.getMenu(items)
|
||||
);
|
||||
@ -18102,25 +18123,32 @@ System.register('flarum/components/Dropdown', ['flarum/Component', 'flarum/helpe
|
||||
// bottom of the viewport. If it does, we will apply class to make it show
|
||||
// above the toggle button instead of below it.
|
||||
this.$().on('shown.bs.dropdown', function () {
|
||||
_this2.showing = true;
|
||||
|
||||
if (_this2.props.onshow) {
|
||||
_this2.props.onshow();
|
||||
}
|
||||
|
||||
m.redraw();
|
||||
|
||||
var $menu = _this2.$('.Dropdown-menu');
|
||||
var isRight = $menu.hasClass('Dropdown-menu--right');
|
||||
|
||||
$menu.removeClass('Dropdown-menu--top Dropdown-menu--right');
|
||||
|
||||
$menu.toggleClass('Dropdown-menu--top', $menu.offset().top + $menu.height() > $(window).scrollTop() + $(window).height());
|
||||
|
||||
$menu.toggleClass('Dropdown-menu--right', isRight || $menu.offset().left + $menu.width() > $(window).scrollLeft() + $(window).width());
|
||||
|
||||
if (_this2.props.onshow) {
|
||||
_this2.props.onshow();
|
||||
m.redraw();
|
||||
}
|
||||
});
|
||||
|
||||
this.$().on('hidden.bs.dropdown', function () {
|
||||
_this2.showing = false;
|
||||
|
||||
if (_this2.props.onhide) {
|
||||
_this2.props.onhide();
|
||||
m.redraw();
|
||||
}
|
||||
|
||||
m.redraw();
|
||||
});
|
||||
}
|
||||
}, {
|
||||
@ -19513,8 +19541,8 @@ System.register('flarum/components/Page', ['flarum/Component'], function (_expor
|
||||
});;
|
||||
'use strict';
|
||||
|
||||
System.register('flarum/components/PermissionDropdown', ['flarum/components/Dropdown', 'flarum/components/Button', 'flarum/components/Separator', 'flarum/models/Group', 'flarum/components/GroupBadge'], function (_export, _context) {
|
||||
var Dropdown, Button, Separator, Group, GroupBadge, PermissionDropdown;
|
||||
System.register('flarum/components/PermissionDropdown', ['flarum/components/Dropdown', 'flarum/components/Button', 'flarum/components/Separator', 'flarum/models/Group', 'flarum/components/Badge', 'flarum/components/GroupBadge'], function (_export, _context) {
|
||||
var Dropdown, Button, Separator, Group, Badge, GroupBadge, PermissionDropdown;
|
||||
|
||||
|
||||
function badgeForId(id) {
|
||||
@ -19523,6 +19551,30 @@ System.register('flarum/components/PermissionDropdown', ['flarum/components/Drop
|
||||
return group ? GroupBadge.component({ group: group, label: null }) : '';
|
||||
}
|
||||
|
||||
function filterByRequiredPermissions(groupIds, permission) {
|
||||
app.getRequiredPermissions(permission).forEach(function (required) {
|
||||
var restrictToGroupIds = app.data.permissions[required] || [];
|
||||
|
||||
if (restrictToGroupIds.indexOf(Group.GUEST_ID) !== -1) {
|
||||
// do nothing
|
||||
} else if (restrictToGroupIds.indexOf(Group.MEMBER_ID) !== -1) {
|
||||
groupIds = groupIds.filter(function (id) {
|
||||
return id !== Group.GUEST_ID;
|
||||
});
|
||||
} else if (groupIds.indexOf(Group.MEMBER_ID) !== -1) {
|
||||
groupIds = restrictToGroupIds;
|
||||
} else {
|
||||
groupIds = restrictToGroupIds.filter(function (id) {
|
||||
return groupIds.indexOf(id) !== -1;
|
||||
});
|
||||
}
|
||||
|
||||
groupIds = filterByRequiredPermissions(groupIds, required);
|
||||
});
|
||||
|
||||
return groupIds;
|
||||
}
|
||||
|
||||
return {
|
||||
setters: [function (_flarumComponentsDropdown) {
|
||||
Dropdown = _flarumComponentsDropdown.default;
|
||||
@ -19532,6 +19584,8 @@ System.register('flarum/components/PermissionDropdown', ['flarum/components/Drop
|
||||
Separator = _flarumComponentsSeparator.default;
|
||||
}, function (_flarumModelsGroup) {
|
||||
Group = _flarumModelsGroup.default;
|
||||
}, function (_flarumComponentsBadge) {
|
||||
Badge = _flarumComponentsBadge.default;
|
||||
}, function (_flarumComponentsGroupBadge) {
|
||||
GroupBadge = _flarumComponentsGroupBadge.default;
|
||||
}],
|
||||
@ -19552,56 +19606,64 @@ System.register('flarum/components/PermissionDropdown', ['flarum/components/Drop
|
||||
this.props.children = [];
|
||||
|
||||
var groupIds = app.data.permissions[this.props.permission] || [];
|
||||
|
||||
groupIds = filterByRequiredPermissions(groupIds, this.props.permission);
|
||||
|
||||
var everyone = groupIds.indexOf(Group.GUEST_ID) !== -1;
|
||||
var members = groupIds.indexOf(Group.MEMBER_ID) !== -1;
|
||||
var adminGroup = app.store.getById('groups', Group.ADMINISTRATOR_ID);
|
||||
|
||||
if (everyone) {
|
||||
this.props.label = app.translator.trans('core.admin.permissions_controls.everyone_button');
|
||||
this.props.label = Badge.component({ icon: 'globe' });
|
||||
} else if (members) {
|
||||
this.props.label = app.translator.trans('core.admin.permissions_controls.members_button');
|
||||
this.props.label = Badge.component({ icon: 'user' });
|
||||
} else {
|
||||
this.props.label = [badgeForId(Group.ADMINISTRATOR_ID), groupIds.map(badgeForId)];
|
||||
}
|
||||
|
||||
if (this.props.allowGuest) {
|
||||
if (this.showing) {
|
||||
if (this.props.allowGuest) {
|
||||
this.props.children.push(Button.component({
|
||||
children: [Badge.component({ icon: 'globe' }), ' ', app.translator.trans('core.admin.permissions_controls.everyone_button')],
|
||||
icon: everyone ? 'check' : true,
|
||||
onclick: function onclick() {
|
||||
return _this2.save([Group.GUEST_ID]);
|
||||
},
|
||||
disabled: this.isGroupDisabled(Group.GUEST_ID)
|
||||
}));
|
||||
}
|
||||
|
||||
this.props.children.push(Button.component({
|
||||
children: app.translator.trans('core.admin.permissions_controls.everyone_button'),
|
||||
icon: everyone ? 'check' : true,
|
||||
children: [Badge.component({ icon: 'user' }), ' ', app.translator.trans('core.admin.permissions_controls.members_button')],
|
||||
icon: members ? 'check' : true,
|
||||
onclick: function onclick() {
|
||||
return _this2.save([Group.GUEST_ID]);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
this.props.children.push(Button.component({
|
||||
children: app.translator.trans('core.admin.permissions_controls.members_button'),
|
||||
icon: members ? 'check' : true,
|
||||
onclick: function onclick() {
|
||||
return _this2.save([Group.MEMBER_ID]);
|
||||
}
|
||||
}), Separator.component(), Button.component({
|
||||
children: [GroupBadge.component({ group: adminGroup, label: null }), ' ', adminGroup.namePlural()],
|
||||
icon: !everyone && !members ? 'check' : true,
|
||||
disabled: !everyone && !members,
|
||||
onclick: function onclick(e) {
|
||||
if (e.shiftKey) e.stopPropagation();
|
||||
_this2.save([]);
|
||||
}
|
||||
}));
|
||||
|
||||
[].push.apply(this.props.children, app.store.all('groups').filter(function (group) {
|
||||
return [Group.ADMINISTRATOR_ID, Group.GUEST_ID, Group.MEMBER_ID].indexOf(group.id()) === -1;
|
||||
}).map(function (group) {
|
||||
return Button.component({
|
||||
children: [GroupBadge.component({ group: group, label: null }), ' ', group.namePlural()],
|
||||
icon: groupIds.indexOf(group.id()) !== -1 ? 'check' : true,
|
||||
return _this2.save([Group.MEMBER_ID]);
|
||||
},
|
||||
disabled: this.isGroupDisabled(Group.MEMBER_ID)
|
||||
}), Separator.component(), Button.component({
|
||||
children: [badgeForId(adminGroup.id()), ' ', adminGroup.namePlural()],
|
||||
icon: !everyone && !members ? 'check' : true,
|
||||
disabled: !everyone && !members,
|
||||
onclick: function onclick(e) {
|
||||
if (e.shiftKey) e.stopPropagation();
|
||||
_this2.toggle(group.id());
|
||||
_this2.save([]);
|
||||
}
|
||||
});
|
||||
}));
|
||||
}));
|
||||
|
||||
[].push.apply(this.props.children, app.store.all('groups').filter(function (group) {
|
||||
return [Group.ADMINISTRATOR_ID, Group.GUEST_ID, Group.MEMBER_ID].indexOf(group.id()) === -1;
|
||||
}).map(function (group) {
|
||||
return Button.component({
|
||||
children: [badgeForId(group.id()), ' ', group.namePlural()],
|
||||
icon: groupIds.indexOf(group.id()) !== -1 ? 'check' : true,
|
||||
onclick: function onclick(e) {
|
||||
if (e.shiftKey) e.stopPropagation();
|
||||
_this2.toggle(group.id());
|
||||
},
|
||||
disabled: _this2.isGroupDisabled(group.id()) && _this2.isGroupDisabled(Group.MEMBER_ID) && _this2.isGroupDisabled(Group.GUEST_ID)
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
return babelHelpers.get(Object.getPrototypeOf(PermissionDropdown.prototype), 'view', this).call(this);
|
||||
}
|
||||
@ -19638,6 +19700,11 @@ System.register('flarum/components/PermissionDropdown', ['flarum/components/Drop
|
||||
|
||||
this.save(groupIds);
|
||||
}
|
||||
}, {
|
||||
key: 'isGroupDisabled',
|
||||
value: function isGroupDisabled(id) {
|
||||
return filterByRequiredPermissions([id], this.props.permission).indexOf(id) === -1;
|
||||
}
|
||||
}], [{
|
||||
key: 'initProps',
|
||||
value: function initProps(props) {
|
||||
@ -19749,7 +19816,7 @@ System.register('flarum/components/PermissionGrid', ['flarum/Component', 'flarum
|
||||
m(
|
||||
'th',
|
||||
null,
|
||||
child.icon ? icon(child.icon) : '',
|
||||
icon(child.icon),
|
||||
child.label
|
||||
),
|
||||
permissionCells(child),
|
||||
@ -19871,10 +19938,10 @@ System.register('flarum/components/PermissionGrid', ['flarum/Component', 'flarum
|
||||
value: function moderateItems() {
|
||||
var items = new ItemList();
|
||||
|
||||
items.add('viewPostIps', {
|
||||
items.add('viewIpsPosts', {
|
||||
icon: 'bullseye',
|
||||
label: app.translator.trans('core.admin.permissions.view_post_ips_label'),
|
||||
permission: 'discussion.viewPostIps'
|
||||
permission: 'discussion.viewIpsPosts'
|
||||
}, 110);
|
||||
|
||||
items.add('renameDiscussions', {
|
||||
@ -23100,11 +23167,13 @@ System.register('flarum/utils/string', [], function (_export, _context) {
|
||||
_export('slug', slug);
|
||||
|
||||
function getPlainContent(string) {
|
||||
var dom = $('<div/>').html(string.replace(/(<\/p>|<br>)/g, '$1 '));
|
||||
var html = string.replace(/(<\/p>|<br>)/g, '$1 ').replace(/<img\b[^>]*>/ig, ' ');
|
||||
|
||||
var dom = $('<div/>').html(html);
|
||||
|
||||
dom.find(getPlainContent.removeSelectors.join(',')).remove();
|
||||
|
||||
return dom.text();
|
||||
return dom.text().replace(/\s+/g, ' ').trim();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -14,4 +14,20 @@ app.initializers.add('boot', boot, -100);
|
||||
|
||||
app.extensionSettings = {};
|
||||
|
||||
app.getRequiredPermissions = function(permission) {
|
||||
const required = [];
|
||||
|
||||
if (permission === 'startDiscussion' || permission.indexOf('discussion.') === 0) {
|
||||
required.push('viewDiscussions');
|
||||
}
|
||||
if (permission === 'discussion.delete') {
|
||||
required.push('discussion.hide');
|
||||
}
|
||||
if (permission === 'discussion.deletePosts') {
|
||||
required.push('discussion.editPosts');
|
||||
}
|
||||
|
||||
return required;
|
||||
};
|
||||
|
||||
export default app;
|
||||
|
@ -2,6 +2,7 @@ import Dropdown from 'flarum/components/Dropdown';
|
||||
import Button from 'flarum/components/Button';
|
||||
import Separator from 'flarum/components/Separator';
|
||||
import Group from 'flarum/models/Group';
|
||||
import Badge from 'flarum/components/Badge';
|
||||
import GroupBadge from 'flarum/components/GroupBadge';
|
||||
|
||||
function badgeForId(id) {
|
||||
@ -10,6 +11,27 @@ function badgeForId(id) {
|
||||
return group ? GroupBadge.component({group, label: null}) : '';
|
||||
}
|
||||
|
||||
function filterByRequiredPermissions(groupIds, permission) {
|
||||
app.getRequiredPermissions(permission)
|
||||
.forEach(required => {
|
||||
const restrictToGroupIds = app.data.permissions[required] || [];
|
||||
|
||||
if (restrictToGroupIds.indexOf(Group.GUEST_ID) !== -1) {
|
||||
// do nothing
|
||||
} else if (restrictToGroupIds.indexOf(Group.MEMBER_ID) !== -1) {
|
||||
groupIds = groupIds.filter(id => id !== Group.GUEST_ID);
|
||||
} else if (groupIds.indexOf(Group.MEMBER_ID) !== -1) {
|
||||
groupIds = restrictToGroupIds;
|
||||
} else {
|
||||
groupIds = restrictToGroupIds.filter(id => groupIds.indexOf(id) !== -1);
|
||||
}
|
||||
|
||||
groupIds = filterByRequiredPermissions(groupIds, required);
|
||||
});
|
||||
|
||||
return groupIds;
|
||||
}
|
||||
|
||||
export default class PermissionDropdown extends Dropdown {
|
||||
static initProps(props) {
|
||||
super.initProps(props);
|
||||
@ -21,15 +43,18 @@ export default class PermissionDropdown extends Dropdown {
|
||||
view() {
|
||||
this.props.children = [];
|
||||
|
||||
const groupIds = app.data.permissions[this.props.permission] || [];
|
||||
let groupIds = app.data.permissions[this.props.permission] || [];
|
||||
|
||||
groupIds = filterByRequiredPermissions(groupIds, this.props.permission);
|
||||
|
||||
const everyone = groupIds.indexOf(Group.GUEST_ID) !== -1;
|
||||
const members = groupIds.indexOf(Group.MEMBER_ID) !== -1;
|
||||
const adminGroup = app.store.getById('groups', Group.ADMINISTRATOR_ID);
|
||||
|
||||
if (everyone) {
|
||||
this.props.label = app.translator.trans('core.admin.permissions_controls.everyone_button');
|
||||
this.props.label = Badge.component({icon: 'globe'});
|
||||
} else if (members) {
|
||||
this.props.label = app.translator.trans('core.admin.permissions_controls.members_button');
|
||||
this.props.label = Badge.component({icon: 'user'});
|
||||
} else {
|
||||
this.props.label = [
|
||||
badgeForId(Group.ADMINISTRATOR_ID),
|
||||
@ -37,50 +62,55 @@ export default class PermissionDropdown extends Dropdown {
|
||||
];
|
||||
}
|
||||
|
||||
if (this.props.allowGuest) {
|
||||
if (this.showing) {
|
||||
if (this.props.allowGuest) {
|
||||
this.props.children.push(
|
||||
Button.component({
|
||||
children: [Badge.component({icon: 'globe'}), ' ', app.translator.trans('core.admin.permissions_controls.everyone_button')],
|
||||
icon: everyone ? 'check' : true,
|
||||
onclick: () => this.save([Group.GUEST_ID]),
|
||||
disabled: this.isGroupDisabled(Group.GUEST_ID)
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
this.props.children.push(
|
||||
Button.component({
|
||||
children: app.translator.trans('core.admin.permissions_controls.everyone_button'),
|
||||
icon: everyone ? 'check' : true,
|
||||
onclick: () => this.save([Group.GUEST_ID])
|
||||
children: [Badge.component({icon: 'user'}), ' ', app.translator.trans('core.admin.permissions_controls.members_button')],
|
||||
icon: members ? 'check' : true,
|
||||
onclick: () => this.save([Group.MEMBER_ID]),
|
||||
disabled: this.isGroupDisabled(Group.MEMBER_ID)
|
||||
}),
|
||||
|
||||
Separator.component(),
|
||||
|
||||
Button.component({
|
||||
children: [badgeForId(adminGroup.id()), ' ', adminGroup.namePlural()],
|
||||
icon: !everyone && !members ? 'check' : true,
|
||||
disabled: !everyone && !members,
|
||||
onclick: e => {
|
||||
if (e.shiftKey) e.stopPropagation();
|
||||
this.save([]);
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
[].push.apply(
|
||||
this.props.children,
|
||||
app.store.all('groups')
|
||||
.filter(group => [Group.ADMINISTRATOR_ID, Group.GUEST_ID, Group.MEMBER_ID].indexOf(group.id()) === -1)
|
||||
.map(group => Button.component({
|
||||
children: [badgeForId(group.id()), ' ', group.namePlural()],
|
||||
icon: groupIds.indexOf(group.id()) !== -1 ? 'check' : true,
|
||||
onclick: (e) => {
|
||||
if (e.shiftKey) e.stopPropagation();
|
||||
this.toggle(group.id());
|
||||
},
|
||||
disabled: this.isGroupDisabled(group.id()) && this.isGroupDisabled(Group.MEMBER_ID) && this.isGroupDisabled(Group.GUEST_ID)
|
||||
}))
|
||||
);
|
||||
}
|
||||
|
||||
this.props.children.push(
|
||||
Button.component({
|
||||
children: app.translator.trans('core.admin.permissions_controls.members_button'),
|
||||
icon: members ? 'check' : true,
|
||||
onclick: () => this.save([Group.MEMBER_ID])
|
||||
}),
|
||||
|
||||
Separator.component(),
|
||||
|
||||
Button.component({
|
||||
children: [GroupBadge.component({group: adminGroup, label: null}), ' ', adminGroup.namePlural()],
|
||||
icon: !everyone && !members ? 'check' : true,
|
||||
disabled: !everyone && !members,
|
||||
onclick: e => {
|
||||
if (e.shiftKey) e.stopPropagation();
|
||||
this.save([]);
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
[].push.apply(
|
||||
this.props.children,
|
||||
app.store.all('groups')
|
||||
.filter(group => [Group.ADMINISTRATOR_ID, Group.GUEST_ID, Group.MEMBER_ID].indexOf(group.id()) === -1)
|
||||
.map(group => Button.component({
|
||||
children: [GroupBadge.component({group, label: null}), ' ', group.namePlural()],
|
||||
icon: groupIds.indexOf(group.id()) !== -1 ? 'check' : true,
|
||||
onclick: (e) => {
|
||||
if (e.shiftKey) e.stopPropagation();
|
||||
this.toggle(group.id());
|
||||
}
|
||||
}))
|
||||
);
|
||||
|
||||
return super.view();
|
||||
}
|
||||
|
||||
@ -112,4 +142,8 @@ export default class PermissionDropdown extends Dropdown {
|
||||
|
||||
this.save(groupIds);
|
||||
}
|
||||
|
||||
isGroupDisabled(id) {
|
||||
return filterByRequiredPermissions([id], this.props.permission).indexOf(id) === -1;
|
||||
}
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ export default class PermissionGrid extends Component {
|
||||
</tr>
|
||||
{section.children.map(child => (
|
||||
<tr className="PermissionGrid-child">
|
||||
<th>{child.icon ? icon(child.icon) : ''}{child.label}</th>
|
||||
<th>{icon(child.icon)}{child.label}</th>
|
||||
{permissionCells(child)}
|
||||
<td/>
|
||||
</tr>
|
||||
|
26
js/forum/dist/app.js
vendored
26
js/forum/dist/app.js
vendored
@ -21457,13 +21457,18 @@ System.register('flarum/components/Dropdown', ['flarum/Component', 'flarum/helpe
|
||||
}
|
||||
|
||||
babelHelpers.createClass(Dropdown, [{
|
||||
key: 'init',
|
||||
value: function init() {
|
||||
this.showing = false;
|
||||
}
|
||||
}, {
|
||||
key: 'view',
|
||||
value: function view() {
|
||||
var items = this.props.children ? listItems(this.props.children) : [];
|
||||
|
||||
return m(
|
||||
'div',
|
||||
{ className: 'ButtonGroup Dropdown dropdown ' + this.props.className + ' itemCount' + items.length },
|
||||
{ className: 'ButtonGroup Dropdown dropdown ' + this.props.className + ' itemCount' + items.length + (this.showing ? ' open' : '') },
|
||||
this.getButton(),
|
||||
this.getMenu(items)
|
||||
);
|
||||
@ -21479,25 +21484,32 @@ System.register('flarum/components/Dropdown', ['flarum/Component', 'flarum/helpe
|
||||
// bottom of the viewport. If it does, we will apply class to make it show
|
||||
// above the toggle button instead of below it.
|
||||
this.$().on('shown.bs.dropdown', function () {
|
||||
_this2.showing = true;
|
||||
|
||||
if (_this2.props.onshow) {
|
||||
_this2.props.onshow();
|
||||
}
|
||||
|
||||
m.redraw();
|
||||
|
||||
var $menu = _this2.$('.Dropdown-menu');
|
||||
var isRight = $menu.hasClass('Dropdown-menu--right');
|
||||
|
||||
$menu.removeClass('Dropdown-menu--top Dropdown-menu--right');
|
||||
|
||||
$menu.toggleClass('Dropdown-menu--top', $menu.offset().top + $menu.height() > $(window).scrollTop() + $(window).height());
|
||||
|
||||
$menu.toggleClass('Dropdown-menu--right', isRight || $menu.offset().left + $menu.width() > $(window).scrollLeft() + $(window).width());
|
||||
|
||||
if (_this2.props.onshow) {
|
||||
_this2.props.onshow();
|
||||
m.redraw();
|
||||
}
|
||||
});
|
||||
|
||||
this.$().on('hidden.bs.dropdown', function () {
|
||||
_this2.showing = false;
|
||||
|
||||
if (_this2.props.onhide) {
|
||||
_this2.props.onhide();
|
||||
m.redraw();
|
||||
}
|
||||
|
||||
m.redraw();
|
||||
});
|
||||
}
|
||||
}, {
|
||||
|
@ -29,11 +29,15 @@ export default class Dropdown extends Component {
|
||||
props.caretIcon = typeof props.caretIcon !== 'undefined' ? props.caretIcon : 'caret-down';
|
||||
}
|
||||
|
||||
init() {
|
||||
this.showing = false;
|
||||
}
|
||||
|
||||
view() {
|
||||
const items = this.props.children ? listItems(this.props.children) : [];
|
||||
|
||||
return (
|
||||
<div className={'ButtonGroup Dropdown dropdown ' + this.props.className + ' itemCount' + items.length}>
|
||||
<div className={'ButtonGroup Dropdown dropdown ' + this.props.className + ' itemCount' + items.length + (this.showing ? ' open' : '')}>
|
||||
{this.getButton()}
|
||||
{this.getMenu(items)}
|
||||
</div>
|
||||
@ -47,8 +51,17 @@ export default class Dropdown extends Component {
|
||||
// bottom of the viewport. If it does, we will apply class to make it show
|
||||
// above the toggle button instead of below it.
|
||||
this.$().on('shown.bs.dropdown', () => {
|
||||
this.showing = true;
|
||||
|
||||
if (this.props.onshow) {
|
||||
this.props.onshow();
|
||||
}
|
||||
|
||||
m.redraw();
|
||||
|
||||
const $menu = this.$('.Dropdown-menu');
|
||||
const isRight = $menu.hasClass('Dropdown-menu--right');
|
||||
|
||||
$menu.removeClass('Dropdown-menu--top Dropdown-menu--right');
|
||||
|
||||
$menu.toggleClass(
|
||||
@ -60,18 +73,16 @@ export default class Dropdown extends Component {
|
||||
'Dropdown-menu--right',
|
||||
isRight || $menu.offset().left + $menu.width() > $(window).scrollLeft() + $(window).width()
|
||||
);
|
||||
|
||||
if (this.props.onshow) {
|
||||
this.props.onshow();
|
||||
m.redraw();
|
||||
}
|
||||
});
|
||||
|
||||
this.$().on('hidden.bs.dropdown', () => {
|
||||
this.showing = false;
|
||||
|
||||
if (this.props.onhide) {
|
||||
this.props.onhide();
|
||||
m.redraw();
|
||||
}
|
||||
|
||||
m.redraw();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,7 @@
|
||||
white-space: nowrap;
|
||||
|
||||
td, th {
|
||||
padding: 10px 0;
|
||||
padding: 5px;
|
||||
text-align: left;
|
||||
}
|
||||
td {
|
||||
@ -65,11 +65,6 @@
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
tr:last-child {
|
||||
td, th {
|
||||
padding-bottom: 15px !important;
|
||||
}
|
||||
}
|
||||
.Dropdown {
|
||||
display: block;
|
||||
|
||||
@ -79,12 +74,15 @@
|
||||
text-align: left;
|
||||
float: none;
|
||||
}
|
||||
.Dropdown-menu {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
.Button {
|
||||
text-decoration: none;
|
||||
|
||||
.Badge {
|
||||
margin: -3px 0;
|
||||
margin: -3px 2px -3px 0;
|
||||
vertical-align: 0;
|
||||
}
|
||||
}
|
||||
@ -113,15 +111,17 @@
|
||||
}
|
||||
.PermissionGrid-section {
|
||||
td, th {
|
||||
padding-top: 15px;
|
||||
border-top: 1px solid @control-bg;
|
||||
padding-top: 20px;
|
||||
}
|
||||
}
|
||||
.PermissionGrid-child {
|
||||
td, th {
|
||||
padding: 5px 0;
|
||||
position: relative;
|
||||
}
|
||||
th {
|
||||
font-weight: normal;
|
||||
}
|
||||
&:hover {
|
||||
background: lighten(@control-bg, 3%);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user