Refine permissions dialog UI
This commit is contained in:
parent
9fe33bb67d
commit
33a8d845c1
@ -126,13 +126,21 @@ function get($update = 0, $load = false) {
|
|||||||
|
|
||||||
if($perms['post_wall']) {
|
if($perms['post_wall']) {
|
||||||
|
|
||||||
|
// I'm trying to make two points in this description text - warn about finality of wall
|
||||||
|
// post permissions, and try to clear up confusion that these permissions set who is
|
||||||
|
// *shown* the post, istead of who is able to see the post, i.e. make it clear that clicking
|
||||||
|
// the "Show" button on a group does not post it to the feed of people in that group, it
|
||||||
|
// mearly allows those people to view the post if they are viewing/following this channel.
|
||||||
|
$aclDesc = t('Post permissions <b>cannot be changed</b> after a post is sent.</br />These permissions set who is allowed to view the post.');
|
||||||
|
$aclContextHelpCmd = '';
|
||||||
|
|
||||||
$x = array(
|
$x = array(
|
||||||
'is_owner' => $is_owner,
|
'is_owner' => $is_owner,
|
||||||
'allow_location' => ((($is_owner || $observer) && (intval(get_pconfig(\App::$profile['profile_uid'],'system','use_browser_location')))) ? true : false),
|
'allow_location' => ((($is_owner || $observer) && (intval(get_pconfig(\App::$profile['profile_uid'],'system','use_browser_location')))) ? true : false),
|
||||||
'default_location' => (($is_owner) ? \App::$profile['channel_location'] : ''),
|
'default_location' => (($is_owner) ? \App::$profile['channel_location'] : ''),
|
||||||
'nickname' => \App::$profile['channel_address'],
|
'nickname' => \App::$profile['channel_address'],
|
||||||
'lockstate' => (((strlen(\App::$profile['channel_allow_cid'])) || (strlen(\App::$profile['channel_allow_gid'])) || (strlen(\App::$profile['channel_deny_cid'])) || (strlen(\App::$profile['channel_deny_gid']))) ? 'lock' : 'unlock'),
|
'lockstate' => (((strlen(\App::$profile['channel_allow_cid'])) || (strlen(\App::$profile['channel_allow_gid'])) || (strlen(\App::$profile['channel_deny_cid'])) || (strlen(\App::$profile['channel_deny_gid']))) ? 'lock' : 'unlock'),
|
||||||
'acl' => (($is_owner) ? populate_acl($channel_acl,true,((\App::$profile['channel_r_stream'] & PERMS_PUBLIC) ? t('Public') : '')) : ''),
|
'acl' => (($is_owner) ? populate_acl($channel_acl,true,((\App::$profile['channel_r_stream'] & PERMS_PUBLIC) ? t('Public') : ''), $aclDesc, $aclContextHelpCmd) : ''),
|
||||||
'showacl' => (($is_owner) ? 'yes' : ''),
|
'showacl' => (($is_owner) ? 'yes' : ''),
|
||||||
'bang' => '',
|
'bang' => '',
|
||||||
'visitor' => (($is_owner || $observer) ? true : false),
|
'visitor' => (($is_owner || $observer) ? true : false),
|
||||||
|
@ -155,6 +155,14 @@ class Network extends \Zotlabs\Web\Controller {
|
|||||||
|
|
||||||
nav_set_selected('network');
|
nav_set_selected('network');
|
||||||
|
|
||||||
|
// I'm trying to make two points in this description text - warn about finality of wall
|
||||||
|
// post permissions, and try to clear up confusion that these permissions set who is
|
||||||
|
// *shown* the post, istead of who is able to see the post, i.e. make it clear that clicking
|
||||||
|
// the "Show" button on a group does not post it to the feed of people in that group, it
|
||||||
|
// mearly allows those people to view the post if they are viewing/following this channel.
|
||||||
|
$aclDesc = t('Post permissions <b>cannot be changed</b> after a post is sent.</br />These permissions set who is allowed to view the post.');
|
||||||
|
$aclContextHelpCmd = '';
|
||||||
|
|
||||||
$channel_acl = array(
|
$channel_acl = array(
|
||||||
'allow_cid' => $channel['channel_allow_cid'],
|
'allow_cid' => $channel['channel_allow_cid'],
|
||||||
'allow_gid' => $channel['channel_allow_gid'],
|
'allow_gid' => $channel['channel_allow_gid'],
|
||||||
@ -170,7 +178,7 @@ class Network extends \Zotlabs\Web\Controller {
|
|||||||
'default_location' => $channel['channel_location'],
|
'default_location' => $channel['channel_location'],
|
||||||
'nickname' => $channel['channel_address'],
|
'nickname' => $channel['channel_address'],
|
||||||
'lockstate' => (($private_editing || $channel['channel_allow_cid'] || $channel['channel_allow_gid'] || $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 'lock' : 'unlock'),
|
'lockstate' => (($private_editing || $channel['channel_allow_cid'] || $channel['channel_allow_gid'] || $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 'lock' : 'unlock'),
|
||||||
'acl' => populate_acl((($private_editing) ? $def_acl : $channel_acl), true, (($channel['channel_r_stream'] & PERMS_PUBLIC) ? t('Public') : '')),
|
'acl' => populate_acl((($private_editing) ? $def_acl : $channel_acl), true, (($channel['channel_r_stream'] & PERMS_PUBLIC) ? t('Public') : ''), $aclDesc, $aclContextHelpCmd),
|
||||||
'bang' => (($private_editing) ? '!' : ''),
|
'bang' => (($private_editing) ? '!' : ''),
|
||||||
'visitor' => true,
|
'visitor' => true,
|
||||||
'profile_uid' => local_channel(),
|
'profile_uid' => local_channel(),
|
||||||
|
@ -210,12 +210,24 @@ function fixacl(&$item) {
|
|||||||
$item = str_replace(array('<','>'),array('',''),$item);
|
$item = str_replace(array('<','>'),array('',''),$item);
|
||||||
}
|
}
|
||||||
|
|
||||||
function populate_acl($defaults = null,$show_jotnets = true, $showall = '') {
|
/**
|
||||||
|
* Builds a modal dialog for editing permissions, using acl_selector.tpl as the template.
|
||||||
|
*
|
||||||
|
* @param array $default Optional access control list for the initial state of the dialog.
|
||||||
|
* @param boolean $show_jotnets Whether plugins for federated networks should be included in the permissions dialog
|
||||||
|
* @param string $showall_caption An optional caption to describe the scope of an unrestricted post. e.g. "Public"
|
||||||
|
* @param string $dialog_description Optional message to include at the top of the dialog. E.g. "Warning: Post permissions cannot be changed once sent".
|
||||||
|
* @param string $context_help Allows the dialog to present a context sensitive help icon. E.g. "photos/permissions"
|
||||||
|
* @param boolean $readonly Not implemented yet. When implemented, the dialog will use acl_readonly.tpl instead, so that permissions may be viewed for posts that can no longer have their permissions changed.
|
||||||
|
*
|
||||||
|
* @return string html modal dialog build from acl_selector.tpl
|
||||||
|
*/
|
||||||
|
function populate_acl($defaults = null,$show_jotnets = true, $showall_caption = '', $dialog_description = '', $context_help = '', $readonly = false) {
|
||||||
|
|
||||||
$allow_cid = $allow_gid = $deny_cid = $deny_gid = false;
|
$allow_cid = $allow_gid = $deny_cid = $deny_gid = false;
|
||||||
|
|
||||||
if(! $showall)
|
if(! $showall_caption)
|
||||||
$showall = t('Visible to your default audience');
|
$showall_caption = t('Visible to your default audience');
|
||||||
|
|
||||||
if(is_array($defaults)) {
|
if(is_array($defaults)) {
|
||||||
$allow_cid = ((strlen($defaults['allow_cid']))
|
$allow_cid = ((strlen($defaults['allow_cid']))
|
||||||
@ -239,9 +251,12 @@ function populate_acl($defaults = null,$show_jotnets = true, $showall = '') {
|
|||||||
|
|
||||||
$tpl = get_markup_template("acl_selector.tpl");
|
$tpl = get_markup_template("acl_selector.tpl");
|
||||||
$o = replace_macros($tpl, array(
|
$o = replace_macros($tpl, array(
|
||||||
'$showall' => $showall,
|
'$showall' => $showall_caption,
|
||||||
|
'$showlimited' => t("Limit access:"),
|
||||||
|
'$showlimitedDesc' => t('Select "Show" to allow access. "Don\'t show" lets you override and limit the scope of "Show".'),
|
||||||
'$show' => t("Show"),
|
'$show' => t("Show"),
|
||||||
'$hide' => t("Don't show"),
|
'$hide' => t("Don't show"),
|
||||||
|
'$search' => t("Search"),
|
||||||
'$allowcid' => json_encode($allow_cid),
|
'$allowcid' => json_encode($allow_cid),
|
||||||
'$allowgid' => json_encode($allow_gid),
|
'$allowgid' => json_encode($allow_gid),
|
||||||
'$denycid' => json_encode($deny_cid),
|
'$denycid' => json_encode($deny_cid),
|
||||||
@ -249,7 +264,9 @@ function populate_acl($defaults = null,$show_jotnets = true, $showall = '') {
|
|||||||
'$jnetModalTitle' => t('Other networks and post services'),
|
'$jnetModalTitle' => t('Other networks and post services'),
|
||||||
'$jotnets' => $jotnets,
|
'$jotnets' => $jotnets,
|
||||||
'$aclModalTitle' => t('Permissions'),
|
'$aclModalTitle' => t('Permissions'),
|
||||||
'$aclModalDismiss' => t('Close')
|
'$aclModalDesc' => $dialog_description,
|
||||||
|
'$aclModalDismiss' => t('Close'),
|
||||||
|
'$helpUrl' => (($context_help == '') ? '' : (z_root() . '/help?f=&cmd=' . $context_help))
|
||||||
));
|
));
|
||||||
|
|
||||||
return $o;
|
return $o;
|
||||||
|
@ -16,6 +16,7 @@ function ACL(backend_url, preset) {
|
|||||||
that.list_content = $("#acl-list-content");
|
that.list_content = $("#acl-list-content");
|
||||||
that.item_tpl = unescape($(".acl-list-item[rel=acl-template]").html());
|
that.item_tpl = unescape($(".acl-list-item[rel=acl-template]").html());
|
||||||
that.showall = $("#acl-showall");
|
that.showall = $("#acl-showall");
|
||||||
|
that.showlimited = $("#acl-showlimited");
|
||||||
|
|
||||||
// set the initial ACL lists in case the enclosing form gets submitted before the ajax loader completes.
|
// set the initial ACL lists in case the enclosing form gets submitted before the ajax loader completes.
|
||||||
that.on_submit();
|
that.on_submit();
|
||||||
@ -26,6 +27,7 @@ function ACL(backend_url, preset) {
|
|||||||
|
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
that.showall.click(that.on_showall);
|
that.showall.click(that.on_showall);
|
||||||
|
that.showlimited.click(that.on_showlimited);
|
||||||
$(document).on('click','.acl-button-show',that.on_button_show);
|
$(document).on('click','.acl-button-show',that.on_button_show);
|
||||||
$(document).on('click','.acl-button-hide',that.on_button_hide);
|
$(document).on('click','.acl-button-hide',that.on_button_hide);
|
||||||
$("#acl-search").keypress(that.on_search);
|
$("#acl-search").keypress(that.on_search);
|
||||||
@ -71,7 +73,8 @@ ACL.prototype.on_search = function(event) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
ACL.prototype.on_showall = function(event) {
|
ACL.prototype.on_showall = function(event) {
|
||||||
event.preventDefault();
|
|
||||||
|
// preventDefault() isn't called here as we want state changes from update_view() to be applied to the radiobutton
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
||||||
if (that.showall.hasClass("btn-warning")) {
|
if (that.showall.hasClass("btn-warning")) {
|
||||||
@ -87,9 +90,17 @@ ACL.prototype.on_showall = function(event) {
|
|||||||
that.update_view();
|
that.update_view();
|
||||||
that.on_submit();
|
that.on_submit();
|
||||||
|
|
||||||
return false;
|
return true; // return true so that state changes from update_view() will be applied
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ACL.prototype.on_showlimited = function(event) {
|
||||||
|
// Prevent the radiobutton from being selected, as the showlimited radiobutton
|
||||||
|
// option is selected only by selecting show or hide options on channels or groups.
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
ACL.prototype.on_selectall = function(event) {
|
ACL.prototype.on_selectall = function(event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
@ -188,18 +199,32 @@ ACL.prototype.set_deny = function(itemid) {
|
|||||||
that.update_view();
|
that.update_view();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ACL.prototype.update_radiobuttons = function(isPublic) {
|
||||||
|
|
||||||
|
that.showall.prop('checked', isPublic);
|
||||||
|
that.showlimited.prop('checked', !isPublic);
|
||||||
|
that.showlimited.prop('disabled', isPublic);
|
||||||
|
};
|
||||||
|
|
||||||
ACL.prototype.update_view = function() {
|
ACL.prototype.update_view = function() {
|
||||||
if (that.allow_gid.length === 0 && that.allow_cid.length === 0 &&
|
if (that.allow_gid.length === 0 && that.allow_cid.length === 0 &&
|
||||||
that.deny_gid.length === 0 && that.deny_cid.length === 0) {
|
that.deny_gid.length === 0 && that.deny_cid.length === 0) {
|
||||||
|
// btn-warning indicates that the permissions are public, it was chosen because
|
||||||
|
// that.showall used to be a normal button, which btn-warning is a bootstrap style for.
|
||||||
that.showall.removeClass("btn-default").addClass("btn-warning");
|
that.showall.removeClass("btn-default").addClass("btn-warning");
|
||||||
|
that.update_radiobuttons(true);
|
||||||
|
|
||||||
/* jot acl */
|
/* jot acl */
|
||||||
$('#jot-perms-icon').removeClass('fa-lock').addClass('fa-unlock');
|
$('#jot-perms-icon, #dialog-perms-icon').removeClass('fa-lock').addClass('fa-unlock');
|
||||||
$('#jot-public').show();
|
$('#jot-public').show();
|
||||||
$('.profile-jot-net input').attr('disabled', false);
|
$('.profile-jot-net input').attr('disabled', false);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
that.showall.removeClass("btn-warning").addClass("btn-default");
|
that.showall.removeClass("btn-warning").addClass("btn-default");
|
||||||
|
that.update_radiobuttons(false);
|
||||||
|
|
||||||
/* jot acl */
|
/* jot acl */
|
||||||
$('#jot-perms-icon').removeClass('fa-unlock').addClass('fa-lock');
|
$('#jot-perms-icon, #dialog-perms-icon').removeClass('fa-unlock').addClass('fa-lock');
|
||||||
$('#jot-public').hide();
|
$('#jot-public').hide();
|
||||||
$('.profile-jot-net input').attr('disabled', 'disabled');
|
$('.profile-jot-net input').attr('disabled', 'disabled');
|
||||||
|
|
||||||
|
@ -912,19 +912,43 @@ a.rconnect:hover, a.rateme:hover, div.rateme:hover {
|
|||||||
clear: both;
|
clear: both;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.modal-header .contextual-help-tool {
|
||||||
|
/* Mostly duplicating ".modal-header .close" and ".close" layout settings from bootstrap */
|
||||||
|
float: right;
|
||||||
|
font-size: 21px;
|
||||||
|
padding: 0;
|
||||||
|
margin-top: -4px;
|
||||||
|
margin-right: 15px;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
#acl-search {
|
#acl-search {
|
||||||
margin-top: 20px;
|
padding: 4px;
|
||||||
padding: 8px;
|
|
||||||
border: 1px solid #ccc;
|
border: 1px solid #ccc;
|
||||||
width: 100%;
|
width: 90%; /* fallback if browser does not support calc() */
|
||||||
|
width: calc(100% - 10px);
|
||||||
|
margin: 0px 0px 10px 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#acl-search::-webkit-input-placeholder {
|
#acl-search::-webkit-input-placeholder {
|
||||||
font-family: FontAwesome;
|
/* non-fontawesome fonts set a fallback for text parts of the placeholder*/
|
||||||
|
font-family: FontAwesome, sans-serif, arial, freesans;
|
||||||
}
|
}
|
||||||
|
|
||||||
#acl-search::-moz-placeholder {
|
#acl-search::-moz-placeholder {
|
||||||
font-family: FontAwesome;
|
/* non-fontawesome fonts set a fallback for text parts of the placeholder*/
|
||||||
|
font-family: FontAwesome, sans-serif, arial, freesans;
|
||||||
|
}
|
||||||
|
|
||||||
|
#acl-dialog-description {
|
||||||
|
font-size: 90%;
|
||||||
|
color: #888;
|
||||||
|
}
|
||||||
|
#acl-showlimited-description {
|
||||||
|
font-size: 90%;
|
||||||
|
color: #888;
|
||||||
|
margin-left: 10px;
|
||||||
|
margin-bottom: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#acl-list {
|
#acl-list {
|
||||||
@ -933,11 +957,11 @@ a.rconnect:hover, a.rateme:hover, div.rateme:hover {
|
|||||||
overflow: auto;
|
overflow: auto;
|
||||||
clear: both;
|
clear: both;
|
||||||
min-height: 62px;
|
min-height: 62px;
|
||||||
margin-top: 20px;
|
|
||||||
padding: 10px 10px 0px 0px;
|
padding: 10px 10px 0px 0px;
|
||||||
-webkit-border-radius: $radiuspx ;
|
-webkit-border-radius: $radiuspx ;
|
||||||
-moz-border-radius: $radiuspx;
|
-moz-border-radius: $radiuspx;
|
||||||
border-radius: $radiuspx;
|
border-radius: $radiuspx;
|
||||||
|
background-color: rgb(238,238,238);
|
||||||
}
|
}
|
||||||
|
|
||||||
#jotnets-wrapper, #jotnets-collapse {
|
#jotnets-wrapper, #jotnets-collapse {
|
||||||
@ -957,6 +981,7 @@ a.rconnect:hover, a.rateme:hover, div.rateme:hover {
|
|||||||
-webkit-border-radius: $radiuspx ;
|
-webkit-border-radius: $radiuspx ;
|
||||||
-moz-border-radius: $radiuspx;
|
-moz-border-radius: $radiuspx;
|
||||||
border-radius: $radiuspx;
|
border-radius: $radiuspx;
|
||||||
|
background-color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.acl-list-item.grouphide {
|
.acl-list-item.grouphide {
|
||||||
@ -995,6 +1020,26 @@ a.rconnect:hover, a.rateme:hover, div.rateme:hover {
|
|||||||
margin-left: 5px;
|
margin-left: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#acl-showlimited-caption,
|
||||||
|
#acl-showall-caption {
|
||||||
|
font-size: 115%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#acl-radiowrapper-showall {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
#acl-radiowrapper-showlimited {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#acl-showall + i {
|
||||||
|
font-size: 140%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#acl-showall-caption {
|
||||||
|
margin-left: 0.35em;
|
||||||
|
}
|
||||||
|
|
||||||
.contact-block-content {
|
.contact-block-content {
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
}
|
}
|
||||||
|
@ -3,9 +3,13 @@
|
|||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||||
<h4 class="modal-title">{{$aclModalTitle}}</h4>
|
{{if $helpUrl}}
|
||||||
|
<a type="button" target="hubzilla-help" href="{{$helpUrl}}" class="contextual-help-tool" title="Help and documentation"><i class="fa fa-question-circle-o"></i></a>
|
||||||
|
{{/if}}
|
||||||
|
<h4 class="modal-title"><i id="dialog-perms-icon" class="fa fa-fw"></i> {{$aclModalTitle}}</h4>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
|
<div id="acl-dialog-description">{{$aclModalDesc}}</div>
|
||||||
{{if $jotnets}}
|
{{if $jotnets}}
|
||||||
<div class="jotnets-wrapper" role="tab" id="jotnets-wrapper">
|
<div class="jotnets-wrapper" role="tab" id="jotnets-wrapper">
|
||||||
<a data-toggle="collapse" class="btn btn-block btn-default" href="#jotnets-collapse" aria-expanded="false" aria-controls="jotnets-collapse">{{$jnetModalTitle}} <span class="caret"></span></a>
|
<a data-toggle="collapse" class="btn btn-block btn-default" href="#jotnets-collapse" aria-expanded="false" aria-controls="jotnets-collapse">{{$jnetModalTitle}} <span class="caret"></span></a>
|
||||||
@ -16,11 +20,24 @@
|
|||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
<div id="acl-wrapper">
|
<div id="acl-wrapper">
|
||||||
<button id="acl-showall" class="btn btn-block btn-default"><i class="fa fa-globe"></i> {{$showall}}</button>
|
<div id="acl-radiowrapper-showall" class="radio">
|
||||||
<input type="text" id="acl-search" placeholder="">
|
<label>
|
||||||
|
<input id="acl-showall" type="radio" name="optionsRadios" value="option1" checked>
|
||||||
|
<i class="fa fa-globe"></i><span id=acl-showall-caption>{{$showall}}</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div id="acl-radiowrapper-showlimited" class="radio">
|
||||||
|
<label>
|
||||||
|
<input id="acl-showlimited" type="radio" name="optionsRadios" style="readonly" value="option2">
|
||||||
|
<span id=acl-showlimited-caption>{{$showlimited}}</span>
|
||||||
|
</label>
|
||||||
<div id="acl-list">
|
<div id="acl-list">
|
||||||
|
<input type="text" id="acl-search" placeholder=" {{$search}}">
|
||||||
|
<div id=acl-showlimited-description>{{$showlimitedDesc}}</div>
|
||||||
<div id="acl-list-content"></div>
|
<div id="acl-list-content"></div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<span id="acl-fields"></span>
|
<span id="acl-fields"></span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user