Compare commits
42 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ab1148872e | |||
| 717096df8a | |||
| ca49b76cb0 | |||
| dc1ca5c14c | |||
| c95d4708a8 | |||
| 8cc8448e18 | |||
| f143ef9732 | |||
| 606154ff24 | |||
| 8cf7370cae | |||
| bf2a772566 | |||
| ddb7e645a0 | |||
| 544b4fab13 | |||
| 74dd06a36c | |||
| b3b4c19e6d | |||
| 7fab295b6f | |||
| dead350676 | |||
| f3af94a285 | |||
| daa4e78a27 | |||
| 1e0f2017f6 | |||
| cd12ac72c7 | |||
| 0f5140d01f | |||
| 85b1cec060 | |||
| 7f9d329295 | |||
| b54945cad6 | |||
| 522718f7ee | |||
| 0ca0f83ac4 | |||
| fe03ad58af | |||
| 577ebd0377 | |||
| 58a1b2d316 | |||
| de85fd6e47 | |||
| 85175f2ead | |||
| 3a097fabca | |||
| 8ee58f53be | |||
| 6afe2e0be4 | |||
| fc47f23615 | |||
| b7d15dc25e | |||
| 3d21ab4950 | |||
| d9d7bfdd3c | |||
| 5bbceeac9a | |||
| b8cb04cd14 | |||
| cbf6b916c3 | |||
| c99a277e2a |
@@ -1,8 +1,15 @@
|
|||||||
|
.user-organisation-button {
|
||||||
|
font-size: 12pt;
|
||||||
|
background-color: #275D8B;
|
||||||
|
font-weight: bolder;
|
||||||
|
}
|
||||||
|
|
||||||
.organisation-admin {
|
.organisation-admin {
|
||||||
color: #56d773 !important;
|
color: #8BE49F !important;
|
||||||
|
/* color: #56d773 !important; */
|
||||||
}
|
}
|
||||||
.organisation-pending {
|
.organisation-pending {
|
||||||
background-color: #6c757d !important;
|
background-color: #CED2D4 !important;
|
||||||
}
|
}
|
||||||
.membership-pending {
|
.membership-pending {
|
||||||
color: #ffd24a !important;
|
color: #ffd24a !important;
|
||||||
|
|||||||
@@ -137,6 +137,33 @@ function bindMemberButtons(el, options) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// Reset member password button
|
||||||
|
el.find('.js-member-password').click(function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
var userName = $(this).data('user_name');
|
||||||
|
$("body").ufModal({
|
||||||
|
sourceUrl: site.uri.public + '/modals/organisations/o/' + $(this).data('slug') + '/members/reset-password',
|
||||||
|
ajaxParams: {
|
||||||
|
slug: $(this).data('slug'),
|
||||||
|
user_name: $(this).data('user_name')
|
||||||
|
},
|
||||||
|
msgTarget: $("#alerts-page")
|
||||||
|
});
|
||||||
|
|
||||||
|
$("body").on('renderSuccess.ufModal', function() {
|
||||||
|
var modal = $(this).ufModal('getModal');
|
||||||
|
var form = modal.find('.js-form');
|
||||||
|
|
||||||
|
form.ufForm()
|
||||||
|
.on("submitSuccess.ufForm", function() {
|
||||||
|
// Navigate or reload page on success
|
||||||
|
window.location.reload();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// function bindMemberCreationButton(el) {
|
// function bindMemberCreationButton(el) {
|
||||||
|
|||||||
@@ -189,6 +189,13 @@ function bindOrganisationButtons(el, options) {
|
|||||||
var options = {
|
var options = {
|
||||||
ajax: {
|
ajax: {
|
||||||
url: site.uri.public + '/api/organisations',
|
url: site.uri.public + '/api/organisations',
|
||||||
|
data: function (params) {
|
||||||
|
return {
|
||||||
|
filters: {
|
||||||
|
info : params.term
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
processResults: function (data) {
|
processResults: function (data) {
|
||||||
var items = data.rows.filter((i) => i.slug != organisation_slug);
|
var items = data.rows.filter((i) => i.slug != organisation_slug);
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -15,9 +15,7 @@
|
|||||||
* SMTP server password: SMTP_PASSWORD
|
* SMTP server password: SMTP_PASSWORD
|
||||||
*/
|
*/
|
||||||
return [
|
return [
|
||||||
'debug' => [
|
'debug' => [ 'auth' => true ],
|
||||||
'tokens' => true,
|
|
||||||
],
|
|
||||||
'organisation' => [
|
'organisation' => [
|
||||||
'registration' => [
|
'registration' => [
|
||||||
'require_approval' => true,
|
'require_approval' => true,
|
||||||
@@ -28,5 +26,6 @@ return [
|
|||||||
'single_membership' => false,
|
'single_membership' => false,
|
||||||
'timeout' => -1,
|
'timeout' => -1,
|
||||||
],
|
],
|
||||||
|
'combine_action_buttons' => false,
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ return [
|
|||||||
'CREATE' => 'Create organisation',
|
'CREATE' => 'Create organisation',
|
||||||
'CREATION_SUCCESSFUL' => 'Successfully created organisation <strong>{{name}}</strong>',
|
'CREATION_SUCCESSFUL' => 'Successfully created organisation <strong>{{name}}</strong>',
|
||||||
|
|
||||||
'EDIT' => 'Edit organistion',
|
'EDIT' => 'Edit organisation',
|
||||||
'UPDATE' => 'Details updated for organistion <strong>{{name}}</strong>',
|
'UPDATE' => 'Details updated for organistion <strong>{{name}}</strong>',
|
||||||
|
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@ return [
|
|||||||
'DELETE_YES' => 'Yes, delete organisation',
|
'DELETE_YES' => 'Yes, delete organisation',
|
||||||
'DELETION_SUCCESSFUL' => 'Successfully deleted organisation <strong>{{name}}</strong>',
|
'DELETION_SUCCESSFUL' => 'Successfully deleted organisation <strong>{{name}}</strong>',
|
||||||
|
|
||||||
'MEMBER_COUNT' => '# Members <sub>(excl admins)</sub>',
|
'MEMBER_COUNT' => '# Members',
|
||||||
'ADMIN_COUNT' => '# Admins',
|
'ADMIN_COUNT' => '# Admins',
|
||||||
|
|
||||||
'SELF' => [
|
'SELF' => [
|
||||||
@@ -155,6 +155,10 @@ return [
|
|||||||
'DEMOTE_CONFIRM_EXTRA' => 'Once demoted they will no longer be able to manage members and agents on the organisation\'s behalf.',
|
'DEMOTE_CONFIRM_EXTRA' => 'Once demoted they will no longer be able to manage members and agents on the organisation\'s behalf.',
|
||||||
'DEMOTE_YES' => 'Yes, demote administrator',
|
'DEMOTE_YES' => 'Yes, demote administrator',
|
||||||
'DEMOTE_SUCCESSFUL' => 'Successfully demoted administrator <strong>{{user_name}}</strong> from being an administrator of organisation <strong>{{name}}</strong>',
|
'DEMOTE_SUCCESSFUL' => 'Successfully demoted administrator <strong>{{user_name}}</strong> from being an administrator of organisation <strong>{{name}}</strong>',
|
||||||
|
|
||||||
|
'RESET_PASSWORD' => 'Send password reset link',
|
||||||
|
'SEND_PASSWORD_LINK_CONFIRM' => 'Please confirm that you wish to send a password reset link to:<br><br> <strong>{{user_name}}</strong> ({{email}}).',
|
||||||
|
'PASSWORD_LINK_SENT' => 'A password reset link has successfully been sent to <strong>{{email}}</strong>.'
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
|
||||||
@@ -168,7 +172,7 @@ return [
|
|||||||
'DEMOTE' => 'Demote to member',
|
'DEMOTE' => 'Demote to member',
|
||||||
|
|
||||||
'EDIT' => 'Edit member',
|
'EDIT' => 'Edit member',
|
||||||
'CHANGE_PASSWORD' => 'Change member password',
|
'RESET_PASSWORD' => 'Send password reset link',
|
||||||
],
|
],
|
||||||
|
|
||||||
'ADMIN' => [
|
'ADMIN' => [
|
||||||
@@ -202,7 +206,12 @@ return [
|
|||||||
'DELETED' => 'Deleted',
|
'DELETED' => 'Deleted',
|
||||||
'RETURN' => 'Return',
|
'RETURN' => 'Return',
|
||||||
|
|
||||||
'JOIN' => 'Join',
|
'ACTIONS_FOR' => 'Actions for',
|
||||||
|
|
||||||
|
'JOIN' => [
|
||||||
|
1 => 'Join',
|
||||||
|
'CANCEL' => 'Cancel join request',
|
||||||
|
],
|
||||||
'LEAVE' => 'Leave',
|
'LEAVE' => 'Leave',
|
||||||
|
|
||||||
'ACTION_CANNOT_UNDONE' => 'This action cannot be undone!',
|
'ACTION_CANNOT_UNDONE' => 'This action cannot be undone!',
|
||||||
|
|||||||
@@ -33,6 +33,8 @@ $app->group('/api/organisations/o/{slug}/members', function () {
|
|||||||
|
|
||||||
$this->put('/m/{user_name}/promote', 'UserFrosting\Sprinkle\Organisations\Controller\OrganisationMembersController:promote');
|
$this->put('/m/{user_name}/promote', 'UserFrosting\Sprinkle\Organisations\Controller\OrganisationMembersController:promote');
|
||||||
$this->put('/m/{user_name}/demote', 'UserFrosting\Sprinkle\Organisations\Controller\OrganisationMembersController:demote');
|
$this->put('/m/{user_name}/demote', 'UserFrosting\Sprinkle\Organisations\Controller\OrganisationMembersController:demote');
|
||||||
|
|
||||||
|
$this->post('/m/{user_name}/password-reset', 'UserFrosting\Sprinkle\Organisations\Controller\OrganisationMembersController:createPasswordReset');
|
||||||
})->add('authGuard')->add(new NoCache());
|
})->add('authGuard')->add(new NoCache());
|
||||||
|
|
||||||
|
|
||||||
@@ -45,4 +47,5 @@ $app->group('/modals/organisations/o/{slug}/members', function () {
|
|||||||
$this->get('/confirm-reject', 'UserFrosting\Sprinkle\Organisations\Controller\OrganisationMembersController:getModalConfirmReject');
|
$this->get('/confirm-reject', 'UserFrosting\Sprinkle\Organisations\Controller\OrganisationMembersController:getModalConfirmReject');
|
||||||
$this->get('/confirm-promote', 'UserFrosting\Sprinkle\Organisations\Controller\OrganisationMembersController:getModalConfirmPromote');
|
$this->get('/confirm-promote', 'UserFrosting\Sprinkle\Organisations\Controller\OrganisationMembersController:getModalConfirmPromote');
|
||||||
$this->get('/confirm-demote', 'UserFrosting\Sprinkle\Organisations\Controller\OrganisationMembersController:getModalConfirmDemote');
|
$this->get('/confirm-demote', 'UserFrosting\Sprinkle\Organisations\Controller\OrganisationMembersController:getModalConfirmDemote');
|
||||||
|
$this->get('/reset-password', 'UserFrosting\Sprinkle\Organisations\Controller\OrganisationMembersController:getModalResetPassword');
|
||||||
})->add('authGuard')->add(new NoCache());
|
})->add('authGuard')->add(new NoCache());
|
||||||
@@ -1,94 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/*
|
|
||||||
* AVSDev UF Organisations (https://avsdev.uk)
|
|
||||||
*
|
|
||||||
* @link https://git.avsdev.uk/avsdev/sprinkle-organisations
|
|
||||||
* @license https://git.avsdev.uk/avsdev/sprinkle-organisations/blob/master/LICENSE.md (LGPL-3.0 License)
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace UserFrosting\Sprinkle\Organisations\Authorize;
|
|
||||||
|
|
||||||
use Illuminate\Support\Arr;
|
|
||||||
use Psr\Container\ContainerInterface;
|
|
||||||
use UserFrosting\Sprinkle\Account\Database\Models\Interfaces\UserInterface;
|
|
||||||
use UserFrosting\Sprinkle\Account\Authorize\AuthorizationManager as UFAuthorizationManager;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* AuthorizationManager class.
|
|
||||||
*
|
|
||||||
* Extends the authorization manager and allows for running an authorization callback without fetching it from the internal list.
|
|
||||||
*
|
|
||||||
* @author Craig Williams (https://avsdev.uk)
|
|
||||||
*/
|
|
||||||
class AuthorizationManager extends UFAuthorizationManager
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Run a registered callback directly.
|
|
||||||
*
|
|
||||||
* @param string $name
|
|
||||||
* @param object $user
|
|
||||||
* @param ... $args
|
|
||||||
*/
|
|
||||||
public function runCallback($user, $name, ...$args)
|
|
||||||
{
|
|
||||||
$debug = $this->ci->config['debug.auth'];
|
|
||||||
$logger = $this->ci->authLogger;
|
|
||||||
|
|
||||||
if (is_null($user) || !($user instanceof UserInterface)) {
|
|
||||||
if ($debug) {
|
|
||||||
$this->ci->authLogger->debug('No user defined. Access denied.');
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The master (root) account has access to everything.
|
|
||||||
// Need to use loose comparison for now, because some DBs return `id` as a string.
|
|
||||||
if ($user->id == $this->ci->config['reserved_user_ids.master']) {
|
|
||||||
if ($debug) {
|
|
||||||
$this->ci->authLogger->debug('User is the master (root) user. Access granted.');
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($debug) {
|
|
||||||
$trace = array_slice(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 3), 1);
|
|
||||||
$this->ci->authLogger->debug('Authorization check requested at: ', $trace);
|
|
||||||
$this->ci->authLogger->debug("Checking authorization for user {$user->id} ('{$user->user_name}') against check '$name'...");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!array_key_exists($name, $this->callbacks) || !isset($this->callbacks[$name])) {
|
|
||||||
if ($debug) {
|
|
||||||
$this->ci->authLogger->debug('No matching callback found. Access denied.');
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
if ($debug) {
|
|
||||||
$this->ci->authLogger->debug("Calling check '{$name}' with arguments:", $args);
|
|
||||||
}
|
|
||||||
|
|
||||||
$result = call_user_func_array($this->callbacks[$name], $args);
|
|
||||||
|
|
||||||
if ($result === true) {
|
|
||||||
if ($debug) {
|
|
||||||
$this->ci->authLogger->debug("User passed check '{$name}'. Access granted.");
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
} catch (Exception $e) {
|
|
||||||
if ($this->debug) {
|
|
||||||
$this->logger->debug("Error running check '$name':" . $e->getMessage() . ". Access denied.");
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -255,7 +255,7 @@ class OrganisationController extends SimpleController
|
|||||||
// Check if name or slug already exists
|
// Check if name or slug already exists
|
||||||
if (
|
if (
|
||||||
isset($data['name']) &&
|
isset($data['name']) &&
|
||||||
$data['name'] != $organisation->name &&
|
strtolower($data['name']) != strtolower($organisation->name) &&
|
||||||
$classMapper->getClassMapping('organisation')::findUnique($data['name'], 'name')
|
$classMapper->getClassMapping('organisation')::findUnique($data['name'], 'name')
|
||||||
) {
|
) {
|
||||||
$ms->addMessageTranslated('danger', 'ORGANISATION.NAME.IN_USE', $data);
|
$ms->addMessageTranslated('danger', 'ORGANISATION.NAME.IN_USE', $data);
|
||||||
@@ -1103,6 +1103,9 @@ class OrganisationController extends SimpleController
|
|||||||
/** @var \UserFrosting\Sprinkle\Account\Authorize\AuthorizationManager $authorizer */
|
/** @var \UserFrosting\Sprinkle\Account\Authorize\AuthorizationManager $authorizer */
|
||||||
$authorizer = $this->ci->authorizer;
|
$authorizer = $this->ci->authorizer;
|
||||||
|
|
||||||
|
/** @var \UserFrosting\Support\Repository\Repository $config */
|
||||||
|
$config = $this->ci->config;
|
||||||
|
|
||||||
/** @var \UserFrosting\Sprinkle\Account\Database\Models\Interfaces\UserInterface $currentUser */
|
/** @var \UserFrosting\Sprinkle\Account\Database\Models\Interfaces\UserInterface $currentUser */
|
||||||
$currentUser = $this->ci->currentUser;
|
$currentUser = $this->ci->currentUser;
|
||||||
|
|
||||||
@@ -1111,7 +1114,33 @@ class OrganisationController extends SimpleController
|
|||||||
throw new ForbiddenException();
|
throw new ForbiddenException();
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->ci->view->render($response, 'pages/organisations.html.twig');
|
$tableColumns = [ 'description', 'join' ];
|
||||||
|
|
||||||
|
|
||||||
|
if ($currentUser->organisations(true)->wherePivot('flag_admin', true)
|
||||||
|
|| $authorizer->checkAccess($currentUser, 'delete_organisation')
|
||||||
|
|| $authorizer->checkAccess($currentUser, 'update_organisation_field')
|
||||||
|
|| $authorizer->checkAccess($currentUser, 'approve_organisation')
|
||||||
|
|| $authorizer->checkAccess($currentUser, 'merge_organisations')
|
||||||
|
|| $config['organisation']['combine_action_buttons']) {
|
||||||
|
$tableColumns[] = 'status';
|
||||||
|
$tableColumns[] = 'actions';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($currentUser->organisations(true)->wherePivot('flag_admin', true)) {
|
||||||
|
$tableColumns[] = 'status';
|
||||||
|
$tableColumns[] = 'actions';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->ci->view->render(
|
||||||
|
$response,
|
||||||
|
'pages/organisations.html.twig',
|
||||||
|
[
|
||||||
|
'table' => [
|
||||||
|
'columns' => $tableColumns
|
||||||
|
]
|
||||||
|
]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1142,7 +1171,23 @@ class OrganisationController extends SimpleController
|
|||||||
throw new ForbiddenException();
|
throw new ForbiddenException();
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->ci->view->render($response, 'pages/deleted-organisations.html.twig');
|
$tableColumns = [ 'description' ];
|
||||||
|
|
||||||
|
if ($authorizer->checkAccess($currentUser, 'restore_organisation') |
|
||||||
|
$authorizer->checkAccess($currentUser, 'permanently_delete_organisation')) {
|
||||||
|
$tableColumns[] = 'status';
|
||||||
|
$tableColumns[] = 'actions';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->ci->view->render(
|
||||||
|
$response,
|
||||||
|
'pages/deleted-organisations.html.twig',
|
||||||
|
[
|
||||||
|
'table' => [
|
||||||
|
'columns' => $tableColumns
|
||||||
|
]
|
||||||
|
]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
namespace UserFrosting\Sprinkle\Organisations\Controller;
|
namespace UserFrosting\Sprinkle\Organisations\Controller;
|
||||||
|
|
||||||
|
use Carbon\Carbon;
|
||||||
use Illuminate\Database\Capsule\Manager as Capsule;
|
use Illuminate\Database\Capsule\Manager as Capsule;
|
||||||
use Psr\Http\Message\ResponseInterface as Response;
|
use Psr\Http\Message\ResponseInterface as Response;
|
||||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||||
@@ -918,6 +919,81 @@ class OrganisationMembersController extends SimpleController
|
|||||||
return $response->withRedirect($this->ci->router->pathFor('uri_organisation', ['slug' => $organisation->slug]));
|
return $response->withRedirect($this->ci->router->pathFor('uri_organisation', ['slug' => $organisation->slug]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Processes the request to send a user a password reset email.
|
||||||
|
*
|
||||||
|
* Processes the request from the user update form, checking that:
|
||||||
|
* 1. The target user's new email address, if specified, is not already in use;
|
||||||
|
* 2. The logged-in user has the necessary permissions to update the posted field(s);
|
||||||
|
* 3. We're not trying to disable the master account;
|
||||||
|
* 4. The submitted data is valid.
|
||||||
|
* This route requires authentication.
|
||||||
|
*
|
||||||
|
* Request type: POST
|
||||||
|
*
|
||||||
|
* @param Request $request
|
||||||
|
* @param Response $response
|
||||||
|
* @param string[] $args
|
||||||
|
*
|
||||||
|
* @throws NotFoundException If user is not found
|
||||||
|
* @throws ForbiddenException If user is not authorized to access page
|
||||||
|
*/
|
||||||
|
public function createPasswordReset(Request $request, Response $response, array $args)
|
||||||
|
{
|
||||||
|
/** @var \UserFrosting\Sprinkle\Account\Authorize\AuthorizationManager $authorizer */
|
||||||
|
$authorizer = $this->ci->authorizer;
|
||||||
|
|
||||||
|
/** @var \UserFrosting\Support\Repository\Repository $config */
|
||||||
|
$config = $this->ci->config;
|
||||||
|
|
||||||
|
/** @var \UserFrosting\Sprinkle\Account\Database\Models\Interfaces\UserInterface $currentUser */
|
||||||
|
$currentUser = $this->ci->currentUser;
|
||||||
|
|
||||||
|
/** @var \UserFrosting\Sprinkle\Core\Alert\AlertStream $ms */
|
||||||
|
$ms = $this->ci->alerts;
|
||||||
|
|
||||||
|
|
||||||
|
// Get the username from the URL
|
||||||
|
$user = $this->getUserFromParams($args);
|
||||||
|
|
||||||
|
if (!$user) {
|
||||||
|
throw new NotFoundException();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Access-controlled resource - check that currentUser has permission to edit "password" for this user
|
||||||
|
if (!$authorizer->checkAccess($currentUser, 'update_user_field', [
|
||||||
|
'user' => $user,
|
||||||
|
'fields' => ['password'],
|
||||||
|
])) {
|
||||||
|
throw new ForbiddenException();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Begin transaction - DB will be rolled back if an exception occurs
|
||||||
|
Capsule::transaction(function () use ($user, $config) {
|
||||||
|
// Create a password reset and shoot off an email
|
||||||
|
$passwordReset = $this->ci->repoPasswordReset->create($user, $config['password_reset.timeouts.reset']);
|
||||||
|
|
||||||
|
// Create and send welcome email with password set link
|
||||||
|
$message = new TwigMailMessage($this->ci->view, 'mail/password-reset.html.twig');
|
||||||
|
|
||||||
|
$message->from($config['address_book.admin'])
|
||||||
|
->addEmailRecipient(new EmailRecipient($user->email, $user->full_name))
|
||||||
|
->addParams([
|
||||||
|
'user' => $user,
|
||||||
|
'token' => $passwordReset->getToken(),
|
||||||
|
'request_date' => Carbon::now()->format('Y-m-d H:i:s'),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->ci->mailer->send($message);
|
||||||
|
});
|
||||||
|
|
||||||
|
$ms->addMessageTranslated('success', 'ORGANISATION.MEMBER.PASSWORD_LINK_SENT', [
|
||||||
|
'email' => $user->email,
|
||||||
|
]);
|
||||||
|
|
||||||
|
return $response->withJson([], 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list of organisation members.
|
* Returns a list of organisation members.
|
||||||
@@ -1359,6 +1435,60 @@ class OrganisationMembersController extends SimpleController
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders the modal form for sending a password reset to a member.
|
||||||
|
*
|
||||||
|
* This does NOT render a complete page. Instead, it renders the HTML for the form, which can be embedded in other pages.
|
||||||
|
* This page requires authentication.
|
||||||
|
*
|
||||||
|
* Request type: GET
|
||||||
|
*
|
||||||
|
* @param Request $request
|
||||||
|
* @param Response $response
|
||||||
|
* @param string[] $args
|
||||||
|
*
|
||||||
|
* @throws NotFoundException If user is not found
|
||||||
|
* @throws ForbiddenException If user is not authorized to access page
|
||||||
|
*/
|
||||||
|
public function getModalResetPassword(Request $request, Response $response, array $args)
|
||||||
|
{
|
||||||
|
/** @var \UserFrosting\Sprinkle\Account\Authorize\AuthorizationManager $authorizer */
|
||||||
|
$authorizer = $this->ci->authorizer;
|
||||||
|
|
||||||
|
/** @var \UserFrosting\Sprinkle\Account\Database\Models\Interfaces\UserInterface $currentUser */
|
||||||
|
$currentUser = $this->ci->currentUser;
|
||||||
|
|
||||||
|
/** @var \UserFrosting\Support\Repository\Repository $config */
|
||||||
|
$config = $this->ci->config;
|
||||||
|
|
||||||
|
// GET parameters
|
||||||
|
$params = $request->getQueryParams();
|
||||||
|
|
||||||
|
$user = $this->getUserFromParams($params);
|
||||||
|
|
||||||
|
$organisation = $this->getOrganisationFromParams($params);
|
||||||
|
|
||||||
|
// Check organisation & user exists
|
||||||
|
if (!$organisation || !$user) {
|
||||||
|
throw new NotFoundException();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Access-controlled resource - check that currentUser has permission to edit "password" field for this user
|
||||||
|
if (!$authorizer->checkAccess($currentUser, 'update_user_field', [
|
||||||
|
'organisation' => $organisation,
|
||||||
|
'user' => $user,
|
||||||
|
'fields' => ['password'],
|
||||||
|
])) {
|
||||||
|
throw new ForbiddenException();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->ci->view->render($response, 'modals/member-reset-password.html.twig', [
|
||||||
|
'user' => $user,
|
||||||
|
'organisation' => $organisation,
|
||||||
|
'page' => [],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send approval email for specified organisation and confirmation to user.
|
* Send approval email for specified organisation and confirmation to user.
|
||||||
@@ -1370,6 +1500,20 @@ class OrganisationMembersController extends SimpleController
|
|||||||
{
|
{
|
||||||
$timeout = $this->ci->config['organisation.membership.timeout'];
|
$timeout = $this->ci->config['organisation.membership.timeout'];
|
||||||
|
|
||||||
|
$admin_fallback = false;
|
||||||
|
$recipientsQuery = $organisation->administrators();
|
||||||
|
|
||||||
|
if ($recipientsQuery->count() == 0) {
|
||||||
|
$admin_fallback = true;
|
||||||
|
$role = $this->ci->classMapper->getClassMapping('role')::where('slug', 'organisations-admin')->with('users')->first();
|
||||||
|
if ($role->users()->count() == 0) {
|
||||||
|
$role = $this->ci->classMapper->getClassMapping('role')::where('slug', 'site-admin')->with('users')->first();
|
||||||
|
}
|
||||||
|
$recipientsQuery = $role->users();
|
||||||
|
}
|
||||||
|
|
||||||
|
$recipients = $recipientsQuery->get();
|
||||||
|
|
||||||
// Create and send approval email
|
// Create and send approval email
|
||||||
$message = new TwigMailMessage($this->ci->view, 'mail/organisation-membership-request.html.twig');
|
$message = new TwigMailMessage($this->ci->view, 'mail/organisation-membership-request.html.twig');
|
||||||
|
|
||||||
@@ -1379,20 +1523,9 @@ class OrganisationMembersController extends SimpleController
|
|||||||
'organisation' => $organisation,
|
'organisation' => $organisation,
|
||||||
'token' => $token,
|
'token' => $token,
|
||||||
'approval_expiration' => ($timeout > 0 ? floor($timeout / 86400) . ' days' : false),
|
'approval_expiration' => ($timeout > 0 ? floor($timeout / 86400) . ' days' : false),
|
||||||
|
'admin_fallback' => $admin_fallback,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$recipientsQuery = $organisation->administrators();
|
|
||||||
|
|
||||||
if ($recipientsQuery->count() == 0) {
|
|
||||||
$role = $this->ci->classMapper->getClassMapping('role')::where('slug', 'organisations-admin')->with('users')->first();
|
|
||||||
if ($role->users()->count() == 0) {
|
|
||||||
$role = $this->ci->classMapper->getClassMapping('role')::where('slug', 'site-admin')->with('users')->first();
|
|
||||||
}
|
|
||||||
$recipientsQuery = $role->users();
|
|
||||||
}
|
|
||||||
|
|
||||||
$recipients = $recipientsQuery->get();
|
|
||||||
|
|
||||||
foreach($recipients as $recipient) {
|
foreach($recipients as $recipient) {
|
||||||
$message->addEmailRecipient(new EmailRecipient($recipient->email, $recipient->full_name));
|
$message->addEmailRecipient(new EmailRecipient($recipient->email, $recipient->full_name));
|
||||||
$message->addParams([ 'recipient' => $recipient ]);
|
$message->addParams([ 'recipient' => $recipient ]);
|
||||||
@@ -1513,7 +1646,7 @@ class OrganisationMembersController extends SimpleController
|
|||||||
$this->sendRejectedEmail($requester, $organisation);
|
$this->sendRejectedEmail($requester, $organisation);
|
||||||
|
|
||||||
$this->ci->userActivityLogger->info("User {$currentUser->user_name} rejected the request for user {$requester->user_name} to join organisation {$organisation->name}.", [
|
$this->ci->userActivityLogger->info("User {$currentUser->user_name} rejected the request for user {$requester->user_name} to join organisation {$organisation->name}.", [
|
||||||
'type' => 'organisation_member_approved',
|
'type' => 'organisation_member_rejected',
|
||||||
'user_id' => $currentUser->id,
|
'user_id' => $currentUser->id,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|||||||
@@ -462,7 +462,7 @@ class OrganisationRegistrationController extends SimpleController
|
|||||||
|
|
||||||
// Record the event in the activity log
|
// Record the event in the activity log
|
||||||
$this->ci->userActivityLogger->info("User {$currentUser->user_name} denied the registration request for organisation {$organisation->name}.", [
|
$this->ci->userActivityLogger->info("User {$currentUser->user_name} denied the registration request for organisation {$organisation->name}.", [
|
||||||
'type' => 'organisation_approved',
|
'type' => 'organisation_denied',
|
||||||
'user_id' => $currentUser->id,
|
'user_id' => $currentUser->id,
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
@@ -552,7 +552,7 @@ class OrganisationRegistrationController extends SimpleController
|
|||||||
|
|
||||||
// Record the event in the activity log
|
// Record the event in the activity log
|
||||||
$this->ci->userActivityLogger->info("User {$currentUser->user_name} denied the registration request for organisation {$organisation->name}.", [
|
$this->ci->userActivityLogger->info("User {$currentUser->user_name} denied the registration request for organisation {$organisation->name}.", [
|
||||||
'type' => 'organisation_approved',
|
'type' => 'organisation_denied',
|
||||||
'user_id' => $currentUser->id,
|
'user_id' => $currentUser->id,
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
* @license https://git.avsdev.uk/avsdev/sprinkle-organisations/blob/master/LICENSE.md (LGPL-3.0 License)
|
* @license https://git.avsdev.uk/avsdev/sprinkle-organisations/blob/master/LICENSE.md (LGPL-3.0 License)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace UserFrosting\Sprinkle\Organisations\Database\Migrations\v010;
|
namespace UserFrosting\Sprinkle\Organisations\Database\Migrations\v1_0_0;
|
||||||
|
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
use UserFrosting\Sprinkle\Core\Database\Migration;
|
use UserFrosting\Sprinkle\Core\Database\Migration;
|
||||||
@@ -25,7 +25,7 @@ class OrganisationApprovalsTable extends Migration
|
|||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public static $dependencies = [
|
public static $dependencies = [
|
||||||
'\UserFrosting\Sprinkle\Account\Database\Migrations\v400\UsersTable',
|
'\UserFrosting\Sprinkle\Account\Database\Migrations\v430\UpdateUsersTable',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
* @license https://git.avsdev.uk/avsdev/sprinkle-organisations/blob/master/LICENSE.md (LGPL-3.0 License)
|
* @license https://git.avsdev.uk/avsdev/sprinkle-organisations/blob/master/LICENSE.md (LGPL-3.0 License)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace UserFrosting\Sprinkle\Organisations\Database\Migrations\v010;
|
namespace UserFrosting\Sprinkle\Organisations\Database\Migrations\v1_0_0;
|
||||||
|
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
use UserFrosting\Sprinkle\Organisations\Database\Models\Organisation;
|
use UserFrosting\Sprinkle\Organisations\Database\Models\Organisation;
|
||||||
@@ -29,8 +29,8 @@ class OrganisationMembersTable extends Migration
|
|||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public static $dependencies = [
|
public static $dependencies = [
|
||||||
'\UserFrosting\Sprinkle\Account\Database\Migrations\v400\UsersTable',
|
'\UserFrosting\Sprinkle\Account\Database\Migrations\v430\UpdateUsersTable',
|
||||||
'\UserFrosting\Sprinkle\Organisations\Database\Migrations\v010\OrganisationsTable',
|
'\UserFrosting\Sprinkle\Organisations\Database\Migrations\v1_0_0\OrganisationsTable',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
* @license https://git.avsdev.uk/avsdev/sprinkle-organisations/blob/master/LICENSE.md (LGPL-3.0 License)
|
* @license https://git.avsdev.uk/avsdev/sprinkle-organisations/blob/master/LICENSE.md (LGPL-3.0 License)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace UserFrosting\Sprinkle\Organisations\Database\Migrations\v010;
|
namespace UserFrosting\Sprinkle\Organisations\Database\Migrations\v1_0_0;
|
||||||
|
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
use UserFrosting\Sprinkle\Core\Database\Migration;
|
use UserFrosting\Sprinkle\Core\Database\Migration;
|
||||||
@@ -25,7 +25,7 @@ class OrganisationMembershipApprovalsTable extends Migration
|
|||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public static $dependencies = [
|
public static $dependencies = [
|
||||||
'\UserFrosting\Sprinkle\Account\Database\Migrations\v400\UsersTable',
|
'\UserFrosting\Sprinkle\Account\Database\Migrations\v430\UpdateUsersTable',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
* @license https://git.avsdev.uk/avsdev/sprinkle-organisations/blob/master/LICENSE.md (LGPL-3.0 License)
|
* @license https://git.avsdev.uk/avsdev/sprinkle-organisations/blob/master/LICENSE.md (LGPL-3.0 License)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace UserFrosting\Sprinkle\Organisations\Database\Migrations\v010;
|
namespace UserFrosting\Sprinkle\Organisations\Database\Migrations\v1_0_0;
|
||||||
|
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
use UserFrosting\Sprinkle\Organisations\Database\Models\Organisation;
|
use UserFrosting\Sprinkle\Organisations\Database\Models\Organisation;
|
||||||
@@ -27,7 +27,7 @@ class OrganisationsTable extends Migration
|
|||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public static $dependencies = [
|
public static $dependencies = [
|
||||||
'\UserFrosting\Sprinkle\Account\Database\Migrations\v400\UsersTable',
|
'\UserFrosting\Sprinkle\Account\Database\Migrations\v430\UpdateUsersTable',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -124,7 +124,7 @@ trait UserOrganisations {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function bootUserOrganisations()
|
static public function bootUserOrganisations()
|
||||||
{
|
{
|
||||||
static::deleting(function ($user) {
|
static::deleting(function ($user) {
|
||||||
if (!$user->deleteUserOrganisations($user->isForceDeleting())) {
|
if (!$user->deleteUserOrganisations($user->isForceDeleting())) {
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ use Illuminate\Database\Eloquent\SoftDeletes;
|
|||||||
use Illuminate\Database\Capsule\Manager as DB;
|
use Illuminate\Database\Capsule\Manager as DB;
|
||||||
use UserFrosting\Sprinkle\Core\Database\Models\Model;
|
use UserFrosting\Sprinkle\Core\Database\Models\Model;
|
||||||
use UserFrosting\Sprinkle\Organisations\Database\Models\Interfaces\OrganisationInterface;
|
use UserFrosting\Sprinkle\Organisations\Database\Models\Interfaces\OrganisationInterface;
|
||||||
use UserFrosting\Sprinkle\Organisations\Repository\Interfaces\TokenOwnerInterface;
|
use UserFrosting\Sprinkle\UFTweaks\Repository\Interfaces\TokenOwnerInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Organisation Class.
|
* Organisation Class.
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ namespace UserFrosting\Sprinkle\Organisations\Database\Models;
|
|||||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
use Illuminate\Database\Capsule\Manager as DB;
|
use Illuminate\Database\Capsule\Manager as DB;
|
||||||
use UserFrosting\Sprinkle\Core\Database\Models\Model;
|
use UserFrosting\Sprinkle\Core\Database\Models\Model;
|
||||||
use UserFrosting\Sprinkle\Organisations\Repository\Interfaces\TokenOwnerInterface;
|
use UserFrosting\Sprinkle\UFTweaks\Repository\Interfaces\TokenOwnerInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* OrganisationMember mapping Class.
|
* OrganisationMember mapping Class.
|
||||||
|
|||||||
@@ -43,6 +43,18 @@ class OrganisationPermissions extends BaseSeed
|
|||||||
*/
|
*/
|
||||||
protected function getPermissions()
|
protected function getPermissions()
|
||||||
{
|
{
|
||||||
|
$roleIds = [
|
||||||
|
'user' => Role::where('slug', 'user')->first()->id,
|
||||||
|
'group-admin' => Role::where('slug', 'group-admin')->first()->id,
|
||||||
|
'site-admin' => Role::where('slug', 'site-admin')->first()->id,
|
||||||
|
'organisations-admin' => Role::where('slug', 'organisations-admin')->first()->id,
|
||||||
|
];
|
||||||
|
|
||||||
|
$canAdminOrgUsers = "(has_role(self.id,{$roleIds['organisations-admin']}) || (has_matching_organisation(self.id,user.id,1) && !has_role(user.id,{$roleIds['organisations-admin']})))";
|
||||||
|
$canAdminOrgAdmins = "(has_role(self.id,{$roleIds['organisations-admin']}) || has_matching_organisation(self.id,user.id,1))";
|
||||||
|
$excludeMasters = "(!is_master(user.id) && !has_role(user.id,{$roleIds['site-admin']}))";
|
||||||
|
$isSelf = "equals_num(self.id,user.id)";
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'create_organisation' => new Permission([
|
'create_organisation' => new Permission([
|
||||||
'slug' => 'create_organisation',
|
'slug' => 'create_organisation',
|
||||||
@@ -56,24 +68,19 @@ class OrganisationPermissions extends BaseSeed
|
|||||||
'conditions' => "in(property,['name','slug','description'])",
|
'conditions' => "in(property,['name','slug','description'])",
|
||||||
'description' => 'View certain properties of any organisation.',
|
'description' => 'View certain properties of any organisation.',
|
||||||
]),
|
]),
|
||||||
'view_organisation_members_field' => new Permission([
|
|
||||||
'slug' => 'view_organisation_field',
|
|
||||||
'name' => 'View organisation members field',
|
|
||||||
'conditions' => "in(property,['members'])",
|
|
||||||
'description' => 'View members field of any organisation.',
|
|
||||||
]),
|
|
||||||
'view_organisation_members' => new Permission([
|
|
||||||
'slug' => 'view_organisation_members',
|
|
||||||
'name' => 'View organisation members',
|
|
||||||
'conditions' => "always()",
|
|
||||||
'description' => 'View members of any organisation.',
|
|
||||||
]),
|
|
||||||
'update_organisation_field' => new Permission([
|
'update_organisation_field' => new Permission([
|
||||||
'slug' => 'update_organisation_field',
|
'slug' => 'update_organisation_field',
|
||||||
'name' => 'Edit organisation',
|
'name' => 'Edit organisation',
|
||||||
'conditions' => 'always()',
|
'conditions' => 'always()',
|
||||||
'description' => 'Edit basic properties of any organisation.',
|
'description' => 'Edit basic properties of any organisation.',
|
||||||
]),
|
]),
|
||||||
|
'delete_organisation' => new Permission([
|
||||||
|
'slug' => 'delete_organisation',
|
||||||
|
'name' => 'Delete organisation',
|
||||||
|
'conditions' => 'always()',
|
||||||
|
'description' => 'Delete an organisation.',
|
||||||
|
]),
|
||||||
|
|
||||||
'approve_organisation' => new Permission([
|
'approve_organisation' => new Permission([
|
||||||
'slug' => 'approve_organisation',
|
'slug' => 'approve_organisation',
|
||||||
'name' => 'Approve/Deny organisation registration',
|
'name' => 'Approve/Deny organisation registration',
|
||||||
@@ -86,12 +93,6 @@ class OrganisationPermissions extends BaseSeed
|
|||||||
'conditions' => 'always()',
|
'conditions' => 'always()',
|
||||||
'description' => 'Merge two organisations together, including all the members.',
|
'description' => 'Merge two organisations together, including all the members.',
|
||||||
]),
|
]),
|
||||||
'delete_organisation' => new Permission([
|
|
||||||
'slug' => 'delete_organisation',
|
|
||||||
'name' => 'Delete organisation',
|
|
||||||
'conditions' => 'always()',
|
|
||||||
'description' => 'Delete an organisation.',
|
|
||||||
]),
|
|
||||||
'restore_organisation' => new Permission([
|
'restore_organisation' => new Permission([
|
||||||
'slug' => 'restore_organisation',
|
'slug' => 'restore_organisation',
|
||||||
'name' => 'Restore organisation',
|
'name' => 'Restore organisation',
|
||||||
@@ -111,6 +112,40 @@ class OrganisationPermissions extends BaseSeed
|
|||||||
'description' => 'Accept/Reject organisation join requests.',
|
'description' => 'Accept/Reject organisation join requests.',
|
||||||
]),
|
]),
|
||||||
|
|
||||||
|
'uri_organisation' => new Permission([
|
||||||
|
'slug' => 'uri_organisation',
|
||||||
|
'name' => 'View organisation',
|
||||||
|
'conditions' => 'always()',
|
||||||
|
'description' => 'View the organisation page of any organisation.',
|
||||||
|
]),
|
||||||
|
'uri_organisations' => new Permission([
|
||||||
|
'slug' => 'uri_organisations',
|
||||||
|
'name' => 'Organisation management page',
|
||||||
|
'conditions' => 'always()',
|
||||||
|
'description' => 'View a page containing a list of organisations.',
|
||||||
|
]),
|
||||||
|
'uri_deleted_organisations' => new Permission([
|
||||||
|
'slug' => 'uri_deleted_organisations',
|
||||||
|
'name' => 'Deleted organisation management page',
|
||||||
|
'conditions' => 'always()',
|
||||||
|
'description' => 'View a page containing a list of deleted organisations.',
|
||||||
|
]),
|
||||||
|
|
||||||
|
|
||||||
|
'view_organisation_members' => new Permission([
|
||||||
|
'slug' => 'view_organisation_field',
|
||||||
|
'name' => 'View organisation members',
|
||||||
|
'conditions' => "in(property,['members'])",
|
||||||
|
'description' => 'View members of any organisation.',
|
||||||
|
]),
|
||||||
|
'promote_organisation_member' => new Permission([
|
||||||
|
'slug' => 'promote_organisation_member',
|
||||||
|
'name' => 'Promote organisation member/Demote organisation administrator',
|
||||||
|
'conditions' => "is_organisation_member(user.id,organisation.id)",
|
||||||
|
'description' => 'Promote an organisation member to administrator status or demote an administrator to member status.',
|
||||||
|
]),
|
||||||
|
|
||||||
|
|
||||||
'register_organisation' => new Permission([
|
'register_organisation' => new Permission([
|
||||||
'slug' => 'register_organisation',
|
'slug' => 'register_organisation',
|
||||||
'name' => 'Register organisation',
|
'name' => 'Register organisation',
|
||||||
@@ -129,6 +164,15 @@ class OrganisationPermissions extends BaseSeed
|
|||||||
'conditions' => 'always()',
|
'conditions' => 'always()',
|
||||||
'description' => 'Allows members to leave organisations.',
|
'description' => 'Allows members to leave organisations.',
|
||||||
]),
|
]),
|
||||||
|
|
||||||
|
|
||||||
|
'uri_organisation_own' => new Permission([
|
||||||
|
'slug' => 'uri_organisation',
|
||||||
|
'name' => 'View own organisation',
|
||||||
|
'conditions' => 'is_organisation_member(self.id,organisation.id)',
|
||||||
|
'description' => 'View the organisation page of an organisation you are a member of.',
|
||||||
|
]),
|
||||||
|
|
||||||
'view_organisation_field_own' => new Permission([
|
'view_organisation_field_own' => new Permission([
|
||||||
'slug' => 'view_organisation_field',
|
'slug' => 'view_organisation_field',
|
||||||
'name' => 'View own organisation',
|
'name' => 'View own organisation',
|
||||||
@@ -147,76 +191,66 @@ class OrganisationPermissions extends BaseSeed
|
|||||||
'conditions' => "is_organisation_admin(self.id,organisation.id)",
|
'conditions' => "is_organisation_admin(self.id,organisation.id)",
|
||||||
'description' => 'Accept/Reject organisation join requests.',
|
'description' => 'Accept/Reject organisation join requests.',
|
||||||
]),
|
]),
|
||||||
|
|
||||||
'uri_organisation' => new Permission([
|
|
||||||
'slug' => 'uri_organisation',
|
|
||||||
'name' => 'View organisation',
|
|
||||||
'conditions' => 'always()',
|
|
||||||
'description' => 'View the organisation page of any organisation.',
|
|
||||||
]),
|
|
||||||
'uri_user' => new Permission([
|
|
||||||
'slug' => 'uri_user',
|
|
||||||
'name' => 'View organisation member',
|
|
||||||
'conditions' => 'can_admin_via_orgs(self.id, user.id)',
|
|
||||||
'description' => 'View the user page of any member of your organisation.',
|
|
||||||
]),
|
|
||||||
'uri_organisation_own' => new Permission([
|
|
||||||
'slug' => 'uri_organisation',
|
|
||||||
'name' => 'View own organisation',
|
|
||||||
'conditions' => 'is_organisation_member(self.id,organisation.id)',
|
|
||||||
'description' => 'View the organisation page of an organisation you are a member of.',
|
|
||||||
]),
|
|
||||||
'uri_organisations' => new Permission([
|
|
||||||
'slug' => 'uri_organisations',
|
|
||||||
'name' => 'Organisation management page',
|
|
||||||
'conditions' => 'always()',
|
|
||||||
'description' => 'View a page containing a list of organisations.',
|
|
||||||
]),
|
|
||||||
'uri_deleted_organisations' => new Permission([
|
|
||||||
'slug' => 'uri_deleted_organisations',
|
|
||||||
'name' => 'Deleted organisation management page',
|
|
||||||
'conditions' => 'always()',
|
|
||||||
'description' => 'View a page containing a list of deleted organisations.',
|
|
||||||
]),
|
|
||||||
|
|
||||||
'update_org_user_field' => new Permission([
|
|
||||||
'slug' => 'update_user_field',
|
|
||||||
'name' => 'Edit organisation member',
|
|
||||||
'conditions' => "subset(fields,['organisations'])",
|
|
||||||
'description' => 'Edit users who are in any organisation.',
|
|
||||||
]),
|
|
||||||
'view_org_user_field' => new Permission([
|
|
||||||
'slug' => 'view_user_field',
|
|
||||||
'name' => 'View organisation member',
|
|
||||||
'conditions' => "in(property,['organisations'])",
|
|
||||||
'description' => 'View certain properties of any user in any organisation.',
|
|
||||||
]),
|
|
||||||
|
|
||||||
'update_org_user_field_own' => new Permission([
|
|
||||||
'slug' => 'update_user_field',
|
|
||||||
'name' => 'Edit organisation member',
|
|
||||||
'conditions' => "can_admin_via_orgs(self.id, user.id) && subset(fields,['organisations'])",
|
|
||||||
'description' => 'Edit users who are in an organisation they are a member of.',
|
|
||||||
]),
|
|
||||||
'view_org_user_field_own' => new Permission([
|
|
||||||
'slug' => 'view_user_field',
|
|
||||||
'name' => 'View organisation member',
|
|
||||||
'conditions' => "similar_orgs(self.id, user.id) && in(property,['organisations'])",
|
|
||||||
'description' => 'View certain properties of any user in their organisation.',
|
|
||||||
]),
|
|
||||||
|
|
||||||
'promote_organisation_member' => new Permission([
|
|
||||||
'slug' => 'promote_organisation_member',
|
|
||||||
'name' => 'Promote organisation member/Demote organisation administrator',
|
|
||||||
'conditions' => "is_organisation_member(user.id,organisation.id) || is_organisation_admin(user.id,organisation.id)",
|
|
||||||
'description' => 'Promote an organisation member to administrator status or demote and administrator to member status.',
|
|
||||||
]),
|
|
||||||
'promote_organisation_member_own' => new Permission([
|
'promote_organisation_member_own' => new Permission([
|
||||||
'slug' => 'promote_organisation_member',
|
'slug' => 'promote_organisation_member',
|
||||||
'name' => 'Promote organisation member/Demote organisation administrator',
|
'name' => 'Promote organisation member/Demote organisation administrator',
|
||||||
'conditions' => "is_organisation_admin(self.id,organisation.id) && (is_organisation_member(user.id,organisation.id) || is_organisation_admin(user.id,organisation.id))",
|
'conditions' => "is_organisation_admin(self.id,organisation.id) && is_organisation_member(user.id,organisation.id)",
|
||||||
'description' => 'Promote an organisation member from your own organisation to administrator status or demote and administrator to member status.',
|
'description' => 'Promote an organisation member from your own organisation to administrator status or demote and administrator to member status.',
|
||||||
]),
|
]),
|
||||||
|
|
||||||
|
|
||||||
|
'uri_user_in_organisation' => new Permission([
|
||||||
|
'slug' => 'uri_user',
|
||||||
|
'name' => 'View user',
|
||||||
|
'conditions' => "(($canAdminOrgAdmins && $excludeMasters) || $isSelf)",
|
||||||
|
'description' => 'View the user page of any user in your orgnisation, except the master user and Site and (global) Organisation Administrators (except yourself).',
|
||||||
|
]),
|
||||||
|
'view_user_field' => new Permission([
|
||||||
|
'slug' => 'view_user_field',
|
||||||
|
'name' => 'View user',
|
||||||
|
'conditions' => "in(property,['organisations'])",
|
||||||
|
'description' => 'View the organisations property of any user.',
|
||||||
|
]),
|
||||||
|
'update_user_field' => new Permission([
|
||||||
|
'slug' => 'update_user_field',
|
||||||
|
'name' => 'Edit user',
|
||||||
|
'conditions' => "$excludeMasters && subset(fields,['organisations'])",
|
||||||
|
'description' => 'Edit organisations for users who are not Site Administrators.',
|
||||||
|
]),
|
||||||
|
|
||||||
|
'view_user_field_group' => new Permission([
|
||||||
|
'slug' => 'view_user_field',
|
||||||
|
'name' => 'View user',
|
||||||
|
'conditions' => "equals_num(self.group_id,user.group_id) && $excludeMasters && (!has_role(user.id,{$roleIds['group-admin']}) || equals_num(self.id,user.id)) && in(property,['organisations'])",
|
||||||
|
'description' => 'View organisations of any user in your own group, except the master user and Site and Group Administrators (except yourself).',
|
||||||
|
]),
|
||||||
|
'update_user_field_group' => new Permission([
|
||||||
|
'slug' => 'update_user_field',
|
||||||
|
'name' => 'Edit group user',
|
||||||
|
'conditions' => "equals_num(self.group_id,user.group_id) && $excludeMasters && (!has_role(user.id,{$roleIds['group-admin']}) || equals_num(self.id,user.id)) && subset(fields,['organisations'])",
|
||||||
|
'description' => 'Edit organisations for users in your own group who are not Site or Group Administrators, except yourself.',
|
||||||
|
]),
|
||||||
|
|
||||||
|
'view_user_field_organisation_audit' => new Permission([
|
||||||
|
'slug' => 'view_user_field',
|
||||||
|
'name' => 'View user',
|
||||||
|
'conditions' => "(($canAdminOrgUsers && $excludeMasters) || $isSelf) && in(property,['activities'])",
|
||||||
|
'description' => 'View certain properties of any user in your own organisation, except the master user and Site and (global) Organisation Administrators (except yourself).',
|
||||||
|
]),
|
||||||
|
'update_user_field_organisation' => new Permission([
|
||||||
|
'slug' => 'update_user_field',
|
||||||
|
'name' => 'Edit organisation user',
|
||||||
|
|
||||||
|
'conditions' => "(($canAdminOrgUsers && $excludeMasters) || $isSelf) && subset(fields,['name','email','locale','flag_enabled','flag_verified','password'])",
|
||||||
|
'description' => 'Edit users in your own organisation who are not Site or (global) Organisation Administrators, except yourself.',
|
||||||
|
]),
|
||||||
|
|
||||||
|
'view_user_field_organisation' => new Permission([
|
||||||
|
'slug' => 'view_user_field',
|
||||||
|
'name' => 'View user',
|
||||||
|
'conditions' => "(($canAdminOrgUsers && $excludeMasters) || $isSelf) && in(property,['user_name','name','email','locale','roles','group','organisations'])",
|
||||||
|
'description' => 'View certain properties of any user in your own organisation, except the master user and Site and (global) Organisation Administrators (except yourself).',
|
||||||
|
]),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -253,45 +287,43 @@ class OrganisationPermissions extends BaseSeed
|
|||||||
$roleSiteAdmin = Role::where('slug', 'site-admin')->first();
|
$roleSiteAdmin = Role::where('slug', 'site-admin')->first();
|
||||||
if ($roleSiteAdmin) {
|
if ($roleSiteAdmin) {
|
||||||
$roleSiteAdmin->permissions()->syncWithoutDetaching([
|
$roleSiteAdmin->permissions()->syncWithoutDetaching([
|
||||||
|
$permissions['view_user_field']->id,
|
||||||
|
$permissions['update_user_field']->id,
|
||||||
|
|
||||||
|
|
||||||
$permissions['create_organisation']->id,
|
$permissions['create_organisation']->id,
|
||||||
$permissions['approve_organisation']->id,
|
|
||||||
|
|
||||||
$permissions['view_organisation_field']->id,
|
$permissions['view_organisation_field']->id,
|
||||||
$permissions['view_organisation_members_field']->id,
|
|
||||||
$permissions['view_organisation_members']->id,
|
|
||||||
|
|
||||||
$permissions['update_organisation_field']->id,
|
$permissions['update_organisation_field']->id,
|
||||||
|
|
||||||
$permissions['merge_organisations']->id,
|
|
||||||
|
|
||||||
$permissions['delete_organisation']->id,
|
$permissions['delete_organisation']->id,
|
||||||
|
|
||||||
|
$permissions['approve_organisation']->id,
|
||||||
|
$permissions['merge_organisations']->id,
|
||||||
$permissions['restore_organisation']->id,
|
$permissions['restore_organisation']->id,
|
||||||
$permissions['permenent_delete_organisation']->id,
|
$permissions['permenent_delete_organisation']->id,
|
||||||
|
$permissions['accept_organisation_join_request']->id,
|
||||||
|
|
||||||
$permissions['uri_user']->id,
|
|
||||||
$permissions['uri_organisation']->id,
|
$permissions['uri_organisation']->id,
|
||||||
|
$permissions['uri_organisations']->id,
|
||||||
$permissions['uri_deleted_organisations']->id,
|
$permissions['uri_deleted_organisations']->id,
|
||||||
|
|
||||||
|
$permissions['view_organisation_members']->id,
|
||||||
$permissions['register_organisation']->id,
|
|
||||||
$permissions['join_organisation']->id,
|
|
||||||
$permissions['leave_organisation']->id,
|
|
||||||
|
|
||||||
$permissions['view_org_user_field_own']->id,
|
|
||||||
$permissions['update_org_user_field_own']->id,
|
|
||||||
$permissions['accept_organisation_join_request_own']->id,
|
|
||||||
$permissions['promote_organisation_member_own']->id,
|
|
||||||
|
|
||||||
$permissions['view_organisation_field_own']->id,
|
|
||||||
$permissions['update_organisation_field_own']->id,
|
|
||||||
|
|
||||||
$permissions['accept_organisation_join_request']->id,
|
|
||||||
$permissions['update_org_user_field']->id,
|
|
||||||
$permissions['view_org_user_field']->id,
|
|
||||||
$permissions['promote_organisation_member']->id,
|
$permissions['promote_organisation_member']->id,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
$permissions['uri_organisation_own']->id,
|
$roleUserAdmin = Role::where('slug', 'user-admin')->first();
|
||||||
$permissions['uri_organisations']->id,
|
if ($roleSiteAdmin) {
|
||||||
|
$roleSiteAdmin->permissions()->syncWithoutDetaching([
|
||||||
|
$permissions['view_user_field']->id,
|
||||||
|
$permissions['update_user_field']->id,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$roleGroupAdmin = Role::where('slug', 'group-admin')->first();
|
||||||
|
if ($roleGroupAdmin) {
|
||||||
|
$roleGroupAdmin->permissions()->sync([
|
||||||
|
$permissions['view_user_field_group']->id,
|
||||||
|
$permissions['update_user_field_group']->id,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -299,52 +331,27 @@ class OrganisationPermissions extends BaseSeed
|
|||||||
if ($roleOrgAdmin) {
|
if ($roleOrgAdmin) {
|
||||||
$roleOrgAdmin->permissions()->syncWithoutDetaching([
|
$roleOrgAdmin->permissions()->syncWithoutDetaching([
|
||||||
$permissions['create_organisation']->id,
|
$permissions['create_organisation']->id,
|
||||||
$permissions['approve_organisation']->id,
|
|
||||||
|
|
||||||
$permissions['view_organisation_field']->id,
|
$permissions['view_organisation_field']->id,
|
||||||
$permissions['view_organisation_members_field']->id,
|
|
||||||
$permissions['view_organisation_members']->id,
|
|
||||||
|
|
||||||
$permissions['update_organisation_field']->id,
|
$permissions['update_organisation_field']->id,
|
||||||
|
|
||||||
$permissions['merge_organisations']->id,
|
|
||||||
|
|
||||||
$permissions['delete_organisation']->id,
|
$permissions['delete_organisation']->id,
|
||||||
|
|
||||||
|
$permissions['approve_organisation']->id,
|
||||||
|
$permissions['merge_organisations']->id,
|
||||||
$permissions['restore_organisation']->id,
|
$permissions['restore_organisation']->id,
|
||||||
$permissions['permenent_delete_organisation']->id,
|
$permissions['permenent_delete_organisation']->id,
|
||||||
|
$permissions['accept_organisation_join_request']->id,
|
||||||
|
|
||||||
$permissions['uri_user']->id,
|
|
||||||
$permissions['uri_organisation']->id,
|
$permissions['uri_organisation']->id,
|
||||||
|
$permissions['uri_organisations']->id,
|
||||||
|
$permissions['uri_user_in_organisation']->id,
|
||||||
$permissions['uri_deleted_organisations']->id,
|
$permissions['uri_deleted_organisations']->id,
|
||||||
|
|
||||||
|
$permissions['view_organisation_members']->id,
|
||||||
$permissions['register_organisation']->id,
|
|
||||||
$permissions['join_organisation']->id,
|
|
||||||
$permissions['leave_organisation']->id,
|
|
||||||
|
|
||||||
$permissions['view_org_user_field_own']->id,
|
|
||||||
$permissions['update_org_user_field_own']->id,
|
|
||||||
$permissions['accept_organisation_join_request_own']->id,
|
|
||||||
$permissions['promote_organisation_member_own']->id,
|
|
||||||
|
|
||||||
$permissions['view_organisation_field_own']->id,
|
|
||||||
$permissions['update_organisation_field_own']->id,
|
|
||||||
|
|
||||||
$permissions['accept_organisation_join_request']->id,
|
|
||||||
$permissions['update_org_user_field']->id,
|
|
||||||
$permissions['view_org_user_field']->id,
|
|
||||||
$permissions['promote_organisation_member']->id,
|
$permissions['promote_organisation_member']->id,
|
||||||
|
|
||||||
$permissions['uri_organisation_own']->id,
|
$permissions['view_user_field_organisation_audit']->id,
|
||||||
$permissions['uri_organisations']->id,
|
$permissions['view_user_field_organisation']->id,
|
||||||
|
$permissions['update_user_field_organisation']->id,
|
||||||
|
|
||||||
Permission::where('slug', 'create_user')->first()->id,
|
|
||||||
Permission::where('slug', 'delete_user')->first()->id,
|
|
||||||
Permission::where('slug', 'update_user_field')->where('conditions', "!has_role(user.id,{$roleSiteAdmin->id}) && subset(fields,['name','email','locale','group','flag_enabled','flag_verified','password'])")->first()->id,
|
|
||||||
|
|
||||||
Permission::where('slug', 'uri_users')->first()->id,
|
|
||||||
Permission::where('slug', 'uri_user')->where('conditions', 'always()')->first()->id,
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -355,18 +362,17 @@ class OrganisationPermissions extends BaseSeed
|
|||||||
$permissions['join_organisation']->id,
|
$permissions['join_organisation']->id,
|
||||||
$permissions['leave_organisation']->id,
|
$permissions['leave_organisation']->id,
|
||||||
|
|
||||||
$permissions['view_org_user_field_own']->id,
|
$permissions['view_organisation_field_own']->id,
|
||||||
$permissions['update_org_user_field_own']->id,
|
$permissions['update_organisation_field_own']->id,
|
||||||
$permissions['accept_organisation_join_request_own']->id,
|
$permissions['accept_organisation_join_request_own']->id,
|
||||||
$permissions['promote_organisation_member_own']->id,
|
$permissions['promote_organisation_member_own']->id,
|
||||||
|
|
||||||
$permissions['view_organisation_field_own']->id,
|
|
||||||
$permissions['update_organisation_field_own']->id,
|
|
||||||
|
|
||||||
$permissions['uri_organisation_own']->id,
|
$permissions['uri_organisation_own']->id,
|
||||||
$permissions['uri_organisations']->id,
|
$permissions['uri_organisations']->id,
|
||||||
|
$permissions['uri_user_in_organisation']->id,
|
||||||
|
|
||||||
$permissions['uri_user']->id,
|
$permissions['view_user_field_organisation']->id,
|
||||||
|
$permissions['update_user_field_organisation']->id,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ class OrganisationRoles extends BaseSeed
|
|||||||
new Role([
|
new Role([
|
||||||
'slug' => 'organisations-admin',
|
'slug' => 'organisations-admin',
|
||||||
'name' => 'Organisations Administrator',
|
'name' => 'Organisations Administrator',
|
||||||
'description' => 'This role is meant for "organisation administrators", who can basically do anything related to organisations and their members.',
|
'description' => 'This role is meant for administrators who can basically do anything related to any organisations.',
|
||||||
]),
|
]),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,492 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/*
|
|
||||||
* AVSDev UF Organisations (https://avsdev.uk)
|
|
||||||
*
|
|
||||||
* @link https://git.avsdev.uk/avsdev/sprinkle-organisations
|
|
||||||
* @license https://git.avsdev.uk/avsdev/sprinkle-organisations/blob/master/LICENSE.md (LGPL-3.0 License)
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace UserFrosting\Sprinkle\Organisations\Repository;
|
|
||||||
|
|
||||||
use Carbon\Carbon;
|
|
||||||
use UserFrosting\Sprinkle\Organisations\Repository\Interfaces\TokenOwnerInterface;
|
|
||||||
use UserFrosting\Sprinkle\Core\Database\Models\Model;
|
|
||||||
use UserFrosting\Sprinkle\Core\Util\ClassMapper;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An abstract class for interacting with a repository of time-sensitive tokens which can be owned by any object.
|
|
||||||
*
|
|
||||||
* Tokens are used, for example, to perform password resets and new account email verifications.
|
|
||||||
*
|
|
||||||
* @author Craig Williams (https://avsdev.uk)
|
|
||||||
*/
|
|
||||||
abstract class BasicTokenRepository
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @var ClassMapper
|
|
||||||
*/
|
|
||||||
protected $classMapper;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $algorithm;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $modelIdentifier;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var TokenLogger
|
|
||||||
*/
|
|
||||||
protected $tokenLogger;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new TokenRepository object.
|
|
||||||
*
|
|
||||||
* @param ClassMapper $classMapper Maps generic class identifiers to specific class names.
|
|
||||||
* @param string $algorithm The hashing algorithm to use when storing generated tokens.
|
|
||||||
*/
|
|
||||||
public function __construct(ClassMapper $classMapper, $algorithm = 'sha512', $tokenLogger = null, $debug = false)
|
|
||||||
{
|
|
||||||
$this->classMapper = $classMapper;
|
|
||||||
$this->algorithm = $algorithm;
|
|
||||||
$this->tokenLogger = ($debug ? $tokenLogger : null);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new token.
|
|
||||||
*
|
|
||||||
* @param TokenOwnerInterface $tokenOwner The object to associate with this token, be it an organisation, user, group etc.
|
|
||||||
* @param int $timeout The time, in seconds, after which this token should expire.
|
|
||||||
*
|
|
||||||
* @return Model The model (PasswordReset, Verification, etc) object that stores the token.
|
|
||||||
*/
|
|
||||||
public function create(TokenOwnerInterface $tokenOwner, $timeout)
|
|
||||||
{
|
|
||||||
// Remove any previous tokens for this tokenOwner
|
|
||||||
$this->removeExisting($tokenOwner);
|
|
||||||
|
|
||||||
if ($this->tokenLogger) {
|
|
||||||
$this->tokenLogger->debug('Creating new token for {{owner}} which expires in {{timeout}} seconds', [
|
|
||||||
'tokenOwner' => $tokenOwner,
|
|
||||||
'timeout' => $timeout
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compute expiration time
|
|
||||||
$expiresAt = Carbon::now()->addSeconds($timeout);
|
|
||||||
|
|
||||||
$model = $this->classMapper->createInstance($this->modelIdentifier);
|
|
||||||
|
|
||||||
// Generate a random token
|
|
||||||
$model->setToken($this->generateRandomToken());
|
|
||||||
|
|
||||||
// Hash the password reset token for the stored version
|
|
||||||
$hash = hash($this->algorithm, $model->getToken());
|
|
||||||
|
|
||||||
$model->fill([
|
|
||||||
'owner_id' => $tokenOwner->getId(),
|
|
||||||
'hash' => $hash,
|
|
||||||
'completed' => false,
|
|
||||||
'expires_at' => ($timeout >= 0 ? $expiresAt : null),
|
|
||||||
]);
|
|
||||||
|
|
||||||
$model->save();
|
|
||||||
|
|
||||||
if ($this->tokenLogger) {
|
|
||||||
$this->tokenLogger->debug('Completed new token', ['model' => $model]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $model;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Cancels a specified token by removing it from the database.
|
|
||||||
*
|
|
||||||
* @param int $token The token to remove.
|
|
||||||
*
|
|
||||||
* @return Model|false
|
|
||||||
*/
|
|
||||||
public function cancel($token)
|
|
||||||
{
|
|
||||||
if ($this->tokenLogger) {
|
|
||||||
$this->tokenLogger->debug('Cancelling token {{token}}', [
|
|
||||||
'token' => $token
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hash the password reset token for the stored version
|
|
||||||
$hash = hash($this->algorithm, $token);
|
|
||||||
|
|
||||||
// Find an incomplete reset request for the specified hash
|
|
||||||
$model = $this->classMapper->getClassMapping($this->modelIdentifier)::query()
|
|
||||||
->where('hash', $hash)
|
|
||||||
->where('completed', false)
|
|
||||||
->first();
|
|
||||||
|
|
||||||
if ($model === null) {
|
|
||||||
if ($this->tokenLogger) {
|
|
||||||
$this->tokenLogger->warn('Token not found!');
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->tokenLogger) {
|
|
||||||
$this->tokenLogger->debug('Deleting matched model', [
|
|
||||||
'model' => $model
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
$model->delete();
|
|
||||||
|
|
||||||
return $model;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Completes a token-based process, invoking updateTokenOwner() in the child object to do the actual action.
|
|
||||||
*
|
|
||||||
* @param int $token The token to complete.
|
|
||||||
* @param mixed[] $params An optional list of parameters to pass to updateUser().
|
|
||||||
*
|
|
||||||
* @return Model|false
|
|
||||||
*/
|
|
||||||
public function complete($token, $params = [])
|
|
||||||
{
|
|
||||||
if ($this->tokenLogger) {
|
|
||||||
$this->tokenLogger->debug('Completing token for {{token}}', [
|
|
||||||
'token' => $token
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hash the token for the stored version
|
|
||||||
$hash = hash($this->algorithm, $token);
|
|
||||||
|
|
||||||
// Find an unexpired, incomplete token for the specified hash
|
|
||||||
$model = $this->classMapper->getClassMapping($this->modelIdentifier)::query()
|
|
||||||
->where('hash', $hash)
|
|
||||||
->where('completed', false)
|
|
||||||
->where(function($query) {
|
|
||||||
return $query->where('expires_at', '>', Carbon::now())->orWhereNull('expires_at');
|
|
||||||
})
|
|
||||||
->first();
|
|
||||||
|
|
||||||
if ($model === null) {
|
|
||||||
if ($this->tokenLogger) {
|
|
||||||
$this->tokenLogger->warn('Token not found!');
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->tokenLogger) {
|
|
||||||
$this->tokenLogger->debug('Found:', [
|
|
||||||
'model' => $model
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
$ret = $this->updateTokenOwner($model->owner_id, $model, $params);
|
|
||||||
|
|
||||||
if ($this->tokenLogger) {
|
|
||||||
$this->tokenLogger->debug('Return of updateTokenOwner: {{ret}}', [
|
|
||||||
'ret' => $ret
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
$model->fill([
|
|
||||||
'completed' => true,
|
|
||||||
'completed_at' => Carbon::now(),
|
|
||||||
]);
|
|
||||||
|
|
||||||
$model->save();
|
|
||||||
|
|
||||||
return $model;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Completes a token-based process using the owner instead of the token,
|
|
||||||
* invoking updateTokenOwner() in the child object to do the actual action.
|
|
||||||
*
|
|
||||||
* @param int $token The token to complete.
|
|
||||||
* @param mixed[] $params An optional list of parameters to pass to updateUser().
|
|
||||||
*
|
|
||||||
* @return Model|false
|
|
||||||
*/
|
|
||||||
public function completeForOwner(TokenOwnerInterface $tokenOwner, $params = [])
|
|
||||||
{
|
|
||||||
if ($this->tokenLogger) {
|
|
||||||
$this->tokenLogger->debug('Completing token for {{owner}}', [
|
|
||||||
'owner' => $tokenOwner
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find an unexpired, incomplete tokens for the specified owner.
|
|
||||||
// Using first() works because owners can only have at most 1 active token
|
|
||||||
$model = $this->classMapper->getClassMapping($this->modelIdentifier)::query()
|
|
||||||
->where('owner_id', $tokenOwner->getId())
|
|
||||||
->where('completed', false)
|
|
||||||
->where(function($query) {
|
|
||||||
return $query->where('expires_at', '>', Carbon::now())->orWhereNull('expires_at');
|
|
||||||
})
|
|
||||||
->first();
|
|
||||||
|
|
||||||
if ($model === null) {
|
|
||||||
if ($this->tokenLogger) {
|
|
||||||
$this->tokenLogger->warn('Token not found!');
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->tokenLogger) {
|
|
||||||
$this->tokenLogger->debug('Found:', [
|
|
||||||
'model' => $model
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
$ret = $this->updateTokenOwner($model->owner_id, $model, $params);
|
|
||||||
|
|
||||||
if ($this->tokenLogger) {
|
|
||||||
$this->tokenLogger->debug('Return of updateTokenOwner: {{ret}}', [
|
|
||||||
'ret' => $ret
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
$model->fill([
|
|
||||||
'completed' => true,
|
|
||||||
'completed_at' => Carbon::now(),
|
|
||||||
]);
|
|
||||||
|
|
||||||
$model->save();
|
|
||||||
|
|
||||||
return $model;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reverts a completed token request to its previously incomplete state.
|
|
||||||
*
|
|
||||||
* @param TokenOwnerInterface $tokenOwner The owner of the token to revert.
|
|
||||||
*
|
|
||||||
* @return Model|false
|
|
||||||
*/
|
|
||||||
public function revert(TokenOwnerInterface $tokenOwner)
|
|
||||||
{
|
|
||||||
if ($this->tokenLogger) {
|
|
||||||
$this->tokenLogger->debug('Reverting token for {{owner}}', [
|
|
||||||
'owner' => $tokenOwner
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find an unexpired, incomplete tokens for the specified owner.
|
|
||||||
// Using first() works because owners can only have at most 1 active token
|
|
||||||
$model = $this->classMapper->getClassMapping($this->modelIdentifier)::query()
|
|
||||||
->where('owner_id', $tokenOwner->getId())
|
|
||||||
->where('completed', true)
|
|
||||||
->where(function($query) {
|
|
||||||
return $query->where('expires_at', '>', Carbon::now())->orWhereNull('expires_at');
|
|
||||||
})
|
|
||||||
->first();
|
|
||||||
|
|
||||||
if ($model === null) {
|
|
||||||
if ($this->tokenLogger) {
|
|
||||||
$this->tokenLogger->warn('Token not found!');
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->tokenLogger) {
|
|
||||||
$this->tokenLogger->debug('Found:', [
|
|
||||||
'model' => $model
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
$model->fill([
|
|
||||||
'completed' => false,
|
|
||||||
'completed_at' => null,
|
|
||||||
]);
|
|
||||||
|
|
||||||
$model->save();
|
|
||||||
|
|
||||||
return $model;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine if a specified token owner has an incomplete and unexpired token.
|
|
||||||
*
|
|
||||||
* @param TokenOwnerInterface $tokenOwner The token owner object to look up.
|
|
||||||
* @param int $token Optionally, try to match a specific token.
|
|
||||||
*
|
|
||||||
* @return Model|false
|
|
||||||
*/
|
|
||||||
public function exists(TokenOwnerInterface $tokenOwner, $token = null)
|
|
||||||
{
|
|
||||||
if ($this->tokenLogger) {
|
|
||||||
$this->tokenLogger->debug('Searching for token for {{owner}} (with optional {{token}})', [
|
|
||||||
'owner' => $tokenOwner,
|
|
||||||
'token' => $token
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
$model = $this->classMapper->getClassMapping($this->modelIdentifier)::query()
|
|
||||||
->where('owner_id', $tokenOwner->id)
|
|
||||||
->where('completed', false)
|
|
||||||
->where(function($query) {
|
|
||||||
return $query->where('expires_at', '>', Carbon::now())->orWhereNull('expires_at');
|
|
||||||
});
|
|
||||||
|
|
||||||
if ($token) {
|
|
||||||
// get token hash
|
|
||||||
$hash = hash($this->algorithm, $token);
|
|
||||||
if ($this->tokenLogger) {
|
|
||||||
$this->tokenLogger->debug('Token hash: {{hash}}', [
|
|
||||||
'hash' => $hash
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
$model->where('hash', $hash);
|
|
||||||
}
|
|
||||||
|
|
||||||
$result = $model->first() ?: false;
|
|
||||||
|
|
||||||
if ($this->tokenLogger) {
|
|
||||||
$this->tokenLogger->debug('Found:', [
|
|
||||||
'result' => $result
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Find an unexpired and un-completed token for the specified owner.
|
|
||||||
*
|
|
||||||
* @param TokenOwnerInterface $tokenOwner The token owner object to look up.
|
|
||||||
* @param int $token Optionally, try to match a specific token.
|
|
||||||
*
|
|
||||||
* @return owner_id|null
|
|
||||||
*/
|
|
||||||
public function findOwner($token)
|
|
||||||
{
|
|
||||||
if ($this->tokenLogger) {
|
|
||||||
$this->tokenLogger->debug('Searching token for owner of {{token}}', [
|
|
||||||
'token' => $token
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// get token hash
|
|
||||||
$hash = hash($this->algorithm, $token);
|
|
||||||
|
|
||||||
if ($this->tokenLogger) {
|
|
||||||
$this->tokenLogger->debug('Token hash: {{hash}}', [
|
|
||||||
'hash' => $hash
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
$model = $this->classMapper->getClassMapping($this->modelIdentifier)::query()
|
|
||||||
->where('hash', $hash)
|
|
||||||
->where('completed', false)
|
|
||||||
->where(function($query) {
|
|
||||||
return $query->where('expires_at', '>', Carbon::now())->orWhereNull('expires_at');
|
|
||||||
})
|
|
||||||
->first();
|
|
||||||
|
|
||||||
if ($this->tokenLogger) {
|
|
||||||
$this->tokenLogger->debug('Found:', [
|
|
||||||
'model' => $model
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $model ? $model->owner_id : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete all existing tokens from the database for a particular owner.
|
|
||||||
*
|
|
||||||
* @param TokenOwnerInterface $tokenOwner
|
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function removeExisting(TokenOwnerInterface $tokenOwner)
|
|
||||||
{
|
|
||||||
if ($this->tokenLogger) {
|
|
||||||
$this->tokenLogger->debug('Removing all tokens for {{owner}}', [
|
|
||||||
'owner' => $tokenOwner
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
$result = $this->classMapper->getClassMapping($this->modelIdentifier)::query()
|
|
||||||
->where('owner_id', $tokenOwner->getId())
|
|
||||||
->delete();
|
|
||||||
|
|
||||||
if ($this->tokenLogger) {
|
|
||||||
$this->tokenLogger->debug('Deletion result: {{result}}', [
|
|
||||||
'result' => $result
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove all expired tokens from the database.
|
|
||||||
*
|
|
||||||
* @return bool|null
|
|
||||||
*/
|
|
||||||
public function removeExpired()
|
|
||||||
{
|
|
||||||
if ($this->tokenLogger) {
|
|
||||||
$this->tokenLogger->debug('Removing expired tokens...');
|
|
||||||
}
|
|
||||||
|
|
||||||
$result = $this->classMapper->getClassMapping($this->modelIdentifier)::query()
|
|
||||||
->where('completed', false)
|
|
||||||
->whereNotNull('expires_at')
|
|
||||||
->where('expires_at', '<', Carbon::now())
|
|
||||||
->delete();
|
|
||||||
|
|
||||||
if ($this->tokenLogger) {
|
|
||||||
$this->tokenLogger->debug('Deletion result: {{result}}', [
|
|
||||||
'result' => $result
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generate a new random token.
|
|
||||||
*
|
|
||||||
* This generates a token to use for verifying anything you like, with a unique reference.
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
protected function generateRandomToken()
|
|
||||||
{
|
|
||||||
do {
|
|
||||||
$gen = md5(uniqid(mt_rand(), false));
|
|
||||||
} while ($this->classMapper->getClassMapping($this->modelIdentifier)::query()
|
|
||||||
->where('hash', hash($this->algorithm, $gen))
|
|
||||||
->first());
|
|
||||||
|
|
||||||
if ($this->tokenLogger) {
|
|
||||||
$this->tokenLogger->debug('Generated token {{token}}', [
|
|
||||||
'token' => $gen
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $gen;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Modify the owner of the token during the token completion process.
|
|
||||||
*
|
|
||||||
* This method is called during complete(), and is a way for concrete implementations to modify the owner.
|
|
||||||
*
|
|
||||||
* @param integer $owner_id The id of the token owner
|
|
||||||
* @param mixed[] $args
|
|
||||||
*
|
|
||||||
* @return mixed[] $args the list of parameters that were supplied to the call to `complete()`
|
|
||||||
*/
|
|
||||||
abstract protected function updateTokenOwner($owner_id, $model, $args);
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/*
|
|
||||||
* AVSDev UF Organisations (https://avsdev.uk)
|
|
||||||
*
|
|
||||||
* @link https://git.avsdev.uk/avsdev/sprinkle-organisations
|
|
||||||
* @license https://git.avsdev.uk/avsdev/sprinkle-organisations/blob/master/LICENSE.md (LGPL-3.0 License)
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace UserFrosting\Sprinkle\Organisations\Repository\Interfaces;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Token Owner Interface.
|
|
||||||
*
|
|
||||||
* Represents a Token Owner object. The only requirement is that it must provide a unique id per object.
|
|
||||||
*/
|
|
||||||
interface TokenOwnerInterface
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Returns a unique ID for this Token Owner
|
|
||||||
*
|
|
||||||
* @return integer|string
|
|
||||||
*/
|
|
||||||
public function getId();
|
|
||||||
}
|
|
||||||
@@ -10,6 +10,7 @@
|
|||||||
namespace UserFrosting\Sprinkle\Organisations\Repository;
|
namespace UserFrosting\Sprinkle\Organisations\Repository;
|
||||||
|
|
||||||
use UserFrosting\Sprinkle\Core\Util\ClassMapper;
|
use UserFrosting\Sprinkle\Core\Util\ClassMapper;
|
||||||
|
use UserFrosting\Sprinkle\UFTweaks\Repository\BasicTokenRepository;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Token repository class for new organisation approval.
|
* Token repository class for new organisation approval.
|
||||||
@@ -28,7 +29,7 @@ class OrganisationApprovalRepository extends BasicTokenRepository
|
|||||||
*/
|
*/
|
||||||
protected function updateTokenOwner($owner_id, $model, $args)
|
protected function updateTokenOwner($owner_id, $model, $args)
|
||||||
{
|
{
|
||||||
$organisation = $this->classMapper->getClassMapping('organisation')::findUnique($owner_id, 'id', false);
|
$organisation = $this->classMapper->getClassMapping('organisation')::where('id', $owner_id)->first();
|
||||||
|
|
||||||
if (!$organisation) {
|
if (!$organisation) {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
namespace UserFrosting\Sprinkle\Organisations\Repository;
|
namespace UserFrosting\Sprinkle\Organisations\Repository;
|
||||||
|
|
||||||
use UserFrosting\Sprinkle\Core\Util\ClassMapper;
|
use UserFrosting\Sprinkle\Core\Util\ClassMapper;
|
||||||
|
use UserFrosting\Sprinkle\UFTweaks\Repository\BasicTokenRepository;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Token repository organisation membership join requests.
|
* Token repository organisation membership join requests.
|
||||||
@@ -28,7 +29,7 @@ class OrganisationMembershipApprovalRepository extends BasicTokenRepository
|
|||||||
*/
|
*/
|
||||||
protected function updateTokenOwner($owner_id, $model, $args)
|
protected function updateTokenOwner($owner_id, $model, $args)
|
||||||
{
|
{
|
||||||
$memberMap = $this->classMapper->getClassMapping('organisation_member')::findUnique($owner_id, 'map_id', false);
|
$memberMap = $this->classMapper->getClassMapping('organisation_member')::where('map_id', $owner_id)->first();
|
||||||
|
|
||||||
if (!$memberMap) {
|
if (!$memberMap) {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -10,19 +10,14 @@
|
|||||||
namespace UserFrosting\Sprinkle\Organisations\ServicesProvider;
|
namespace UserFrosting\Sprinkle\Organisations\ServicesProvider;
|
||||||
|
|
||||||
use Illuminate\Database\Capsule\Manager as Capsule;
|
use Illuminate\Database\Capsule\Manager as Capsule;
|
||||||
use Monolog\Formatter\LineFormatter;
|
|
||||||
use Monolog\Handler\StreamHandler;
|
|
||||||
use Monolog\Logger;
|
|
||||||
use Psr\Container\ContainerInterface;
|
use Psr\Container\ContainerInterface;
|
||||||
use Psr\Http\Message\ResponseInterface as Response;
|
use Psr\Http\Message\ResponseInterface as Response;
|
||||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||||
use UserFrosting\Sprinkle\Core\Log\MixedFormatter;
|
|
||||||
use UserFrosting\Sprinkle\Organisations\Database\Models\Interfaces\OrganisationInterface;
|
use UserFrosting\Sprinkle\Organisations\Database\Models\Interfaces\OrganisationInterface;
|
||||||
use UserFrosting\Sprinkle\Organisations\Database\Models\User;
|
use UserFrosting\Sprinkle\Organisations\Database\Models\User;
|
||||||
use UserFrosting\Sprinkle\Organisations\Twig\OrganisationsExtension;
|
use UserFrosting\Sprinkle\Organisations\Twig\OrganisationsExtension;
|
||||||
use UserFrosting\Sprinkle\Organisations\Repository\OrganisationApprovalRepository;
|
use UserFrosting\Sprinkle\Organisations\Repository\OrganisationApprovalRepository;
|
||||||
use UserFrosting\Sprinkle\Organisations\Repository\OrganisationMembershipApprovalRepository;
|
use UserFrosting\Sprinkle\Organisations\Repository\OrganisationMembershipApprovalRepository;
|
||||||
use UserFrosting\Sprinkle\Organisations\Authorize\AuthorizationManager;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -64,8 +59,21 @@ class ServicesProvider
|
|||||||
* @return \UserFrosting\Sprinkle\Core\Util\ClassMapper
|
* @return \UserFrosting\Sprinkle\Core\Util\ClassMapper
|
||||||
*/
|
*/
|
||||||
$container->extend('authorizer', function ($authorizer, $c) {
|
$container->extend('authorizer', function ($authorizer, $c) {
|
||||||
|
/*
|
||||||
|
* Check if all $user has an $organisation.
|
||||||
|
*
|
||||||
|
* @param int $user_id the id of the requesting user (normally currentUser->id).
|
||||||
|
* @return bool true if $user is a verified member of any organisation.
|
||||||
|
*/
|
||||||
|
$authorizer->addCallback('has_organisation', function ($user_id) {
|
||||||
|
$query = Capsule::table('organisation_members')
|
||||||
|
->join('organisations', 'organisation_members.organisation_id', 'organisations.id')
|
||||||
|
->where('user_id', $user_id)
|
||||||
|
->where('organisation_members.flag_approved', true)
|
||||||
|
->where('organisations.flag_approved', true);
|
||||||
|
|
||||||
$new_authorizer = new AuthorizationManager($c, $authorizer->getCallbacks());
|
return $query->count() > 0;
|
||||||
|
});
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check if all $user is a member of $organisation.
|
* Check if all $user is a member of $organisation.
|
||||||
@@ -74,12 +82,17 @@ class ServicesProvider
|
|||||||
* @param int $organisation_id the id of the target organisation.
|
* @param int $organisation_id the id of the target organisation.
|
||||||
* @return bool true if $user is a member of $organisation.
|
* @return bool true if $user is a member of $organisation.
|
||||||
*/
|
*/
|
||||||
$new_authorizer->addCallback('is_organisation_member', function ($user_id, $organisation_id) {
|
$authorizer->addCallback('is_organisation_member', function ($user_id, $organisation_id, $explicit = false) {
|
||||||
return Capsule::table('organisation_members')
|
$query = Capsule::table('organisation_members')
|
||||||
->where('user_id', $user_id)
|
->where('user_id', $user_id)
|
||||||
->where('organisation_id', $organisation_id)
|
->where('organisation_id', $organisation_id)
|
||||||
->where('flag_approved', true)
|
->where('flag_approved', true);
|
||||||
->count() > 0;
|
|
||||||
|
if ($explicit) {
|
||||||
|
$query = $query->where('flag_admin', false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $query->count() > 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -89,35 +102,45 @@ class ServicesProvider
|
|||||||
* @param int $organisation_id the id of the target organisation.
|
* @param int $organisation_id the id of the target organisation.
|
||||||
* @return bool true if $user is an administrator of $organisation.
|
* @return bool true if $user is an administrator of $organisation.
|
||||||
*/
|
*/
|
||||||
$new_authorizer->addCallback('is_organisation_admin', function ($user_id, $organisation_id) {
|
$authorizer->addCallback('is_organisation_admin', function ($user_id, $organisation_id) {
|
||||||
return Capsule::table('organisation_members')
|
$query = Capsule::table('organisation_members')
|
||||||
->where('user_id', $user_id)
|
->where('user_id', $user_id)
|
||||||
->where('organisation_id', $organisation_id)
|
->where('organisation_id', $organisation_id)
|
||||||
->where('flag_admin', true)
|
->where('flag_admin', true);
|
||||||
->count() > 0;
|
|
||||||
|
return $query->count() > 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check if $admin_id can modify $user_id via any of their joint organisations
|
* Check if $user_A_id is in an organisation that $user_B_id is also in
|
||||||
*
|
*
|
||||||
* @param int $admin_id the id of the admin user (normally currentUser->id).
|
* @param int $user_A_id the id of the first user (normally currentUser->id).
|
||||||
* @param int $user_id the id of the target user.
|
* @param int $user_B_id the id of the second user.
|
||||||
* @return bool true if $admin_id is an administrator of an organisation with $user_id in.
|
* @param bool $check_is_admin also check if A can administrate B.
|
||||||
|
* @return bool true if $user_A_id in an organisation with $user_B_id in.
|
||||||
*/
|
*/
|
||||||
$new_authorizer->addCallback('can_admin_via_orgs', function ($admin_id, $user_id) {
|
$authorizer->addCallback('has_matching_organisation', function ($user_A_id, $user_B_id, $check_is_admin = false) {
|
||||||
$admin = User::findInt($admin_id);
|
$user_A = User::findInt($user_A_id);
|
||||||
$user = User::findInt($user_id);
|
$user_B = User::findInt($user_B_id);
|
||||||
|
|
||||||
foreach($admin->adminForOrganisations()->get() as $org) {
|
if ($check_is_admin) {
|
||||||
if ($org->members(true)->where('user_id', $user_id)->count() > 0) {
|
foreach($user_A->adminForOrganisations()->get() as $org) {
|
||||||
|
if ($org->members(true)->where('user_id', $user_B_id)->count() > 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
foreach($user_A->organisations()->get() as $org) {
|
||||||
|
if ($org->members(true)->where('user_id', $user_B_id)->count() > 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
return $new_authorizer;
|
return $authorizer;
|
||||||
});
|
});
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -127,34 +150,14 @@ class ServicesProvider
|
|||||||
*/
|
*/
|
||||||
$container->extend('view', function ($view, $c) {
|
$container->extend('view', function ($view, $c) {
|
||||||
$twig = $view->getEnvironment();
|
$twig = $view->getEnvironment();
|
||||||
|
|
||||||
$extension = new OrganisationsExtension($c);
|
$extension = new OrganisationsExtension($c);
|
||||||
|
|
||||||
$twig->addExtension($extension);
|
$twig->addExtension($extension);
|
||||||
|
|
||||||
return $view;
|
return $view;
|
||||||
});
|
});
|
||||||
|
|
||||||
/*
|
|
||||||
* Token logging with Monolog.
|
|
||||||
*
|
|
||||||
* Extend this service to push additional handlers onto the 'tokens' log stack.
|
|
||||||
*
|
|
||||||
* @return \Monolog\Logger
|
|
||||||
*/
|
|
||||||
$container['tokenLogger'] = function ($c) {
|
|
||||||
$logger = new Logger('tokens');
|
|
||||||
|
|
||||||
$logFile = $c->locator->findResource('log://userfrosting.log', true, true);
|
|
||||||
|
|
||||||
$handler = new StreamHandler($logFile);
|
|
||||||
|
|
||||||
$formatter = new MixedFormatter(null, null, true);
|
|
||||||
|
|
||||||
$handler->setFormatter($formatter);
|
|
||||||
$logger->pushHandler($handler);
|
|
||||||
|
|
||||||
return $logger;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns a callback that handles merging any organisation objects.
|
* Returns a callback that handles merging any organisation objects.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -125,6 +125,31 @@ class OrganisationSprunje extends Sprunje
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter by description (case insensitive).
|
||||||
|
*
|
||||||
|
* @param Builder $query
|
||||||
|
* @param mixed $value
|
||||||
|
*
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
protected function filterInfo($query, $value)
|
||||||
|
{
|
||||||
|
// Split value on separator for OR queries
|
||||||
|
$values = explode($this->orSeparator, $value);
|
||||||
|
$query->where(function ($query) use ($values) {
|
||||||
|
foreach ($values as $value) {
|
||||||
|
$query->orWhereRaw(
|
||||||
|
'LOWER(name) LIKE ?', [ '%' . strtolower($value) . '%' ]
|
||||||
|
)->orWhereRaw(
|
||||||
|
'LOWER(description) LIKE ?', [ '%' . strtolower($value) . '%' ]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a list of possible user statuses.
|
* Return a list of possible user statuses.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ namespace UserFrosting\Sprinkle\Organisations\Sprunje;
|
|||||||
use Illuminate\Database\Schema\Builder;
|
use Illuminate\Database\Schema\Builder;
|
||||||
use UserFrosting\Sprinkle\Core\Facades\Translator;
|
use UserFrosting\Sprinkle\Core\Facades\Translator;
|
||||||
use UserFrosting\Sprinkle\Core\Sprunje\Sprunje;
|
use UserFrosting\Sprinkle\Core\Sprunje\Sprunje;
|
||||||
use UserFrosting\Sprinkle\Admin\Sprunje\UserSprunje as UFUserSprunje;
|
use UserFrosting\Sprinkle\UFTweaks\Sprunje\UserSprunje as UFUserSprunje;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* UserSprunje.
|
* UserSprunje.
|
||||||
@@ -29,8 +29,10 @@ class UserSprunje extends UFUserSprunje
|
|||||||
'last_activity',
|
'last_activity',
|
||||||
'status',
|
'status',
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $sortable = [
|
protected $sortable = [
|
||||||
'name',
|
'name',
|
||||||
|
'organisations',
|
||||||
'last_activity',
|
'last_activity',
|
||||||
'status',
|
'status',
|
||||||
];
|
];
|
||||||
@@ -56,6 +58,7 @@ class UserSprunje extends UFUserSprunje
|
|||||||
*/
|
*/
|
||||||
protected function sortOrganisations($query, $direction)
|
protected function sortOrganisations($query, $direction)
|
||||||
{
|
{
|
||||||
|
$query = $query->addSelect('organisations.name');
|
||||||
$query->orderBy('organisations.name', $direction);
|
$query->orderBy('organisations.name', $direction);
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
@@ -75,13 +78,64 @@ class UserSprunje extends UFUserSprunje
|
|||||||
$values = explode($this->orSeparator, $value);
|
$values = explode($this->orSeparator, $value);
|
||||||
$query->where(function ($query) use ($values) {
|
$query->where(function ($query) use ($values) {
|
||||||
foreach ($values as $value) {
|
foreach ($values as $value) {
|
||||||
$query->orLike('organisations.name', $value);
|
$likeValue = '%' . mb_strtolower($value) . '%';
|
||||||
|
$query->orWhereRaw('LOWER(organisations.name) LIKE ?', $likeValue);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sort based on last activity time.
|
||||||
|
*
|
||||||
|
* @param Builder $query
|
||||||
|
* @param string $direction
|
||||||
|
*
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
protected function sortLastActivity($query, $direction)
|
||||||
|
{
|
||||||
|
$query = $query->addSelect('activities.occurred_at');
|
||||||
|
$query->orderBy('activities.occurred_at', $direction);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sort based on last name.
|
||||||
|
*
|
||||||
|
* @param Builder $query
|
||||||
|
* @param string $direction
|
||||||
|
*
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
protected function sortName($query, $direction)
|
||||||
|
{
|
||||||
|
$query = $query->addSelect('last_name');
|
||||||
|
$query = $query->addSelect('first_name');
|
||||||
|
$query->orderBy('last_name', $direction)->orderBy('first_name', $direction);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sort active, unactivated, disabled.
|
||||||
|
*
|
||||||
|
* @param Builder $query
|
||||||
|
* @param string $direction
|
||||||
|
*
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
protected function sortStatus($query, $direction)
|
||||||
|
{
|
||||||
|
$query = $query->addSelect('flag_enabled');
|
||||||
|
$query = $query->addSelect('flag_verified');
|
||||||
|
$query->orderBy('flag_enabled', $direction)->orderBy('flag_verified', $direction);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the unpaginated count of items (before filtering) in this query.
|
* Get the unpaginated count of items (before filtering) in this query.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -66,22 +66,18 @@ class OrganisationsExtension extends AbstractExtension implements GlobalsInterfa
|
|||||||
return Capsule::table('organisation_members')
|
return Capsule::table('organisation_members')
|
||||||
->where('user_id', $currentUser->id)
|
->where('user_id', $currentUser->id)
|
||||||
->where('organisation_id', $organisation->id)
|
->where('organisation_id', $organisation->id)
|
||||||
->where('flag_admin', true)
|
|
||||||
->where('flag_approved', true)
|
->where('flag_approved', true)
|
||||||
|
->where('flag_admin', true)
|
||||||
->count() > 0;
|
->count() > 0;
|
||||||
}),
|
}),
|
||||||
new TwigFunction('isOrganisationRegistrant', function ($organisation) {
|
new TwigFunction('isOrganisationRegistrant', function ($organisation) {
|
||||||
$currentUser = $this->services->currentUser;
|
$currentUser = $this->services->currentUser;
|
||||||
return $organisation->registrant_id == $currentUser->id;
|
return $organisation->registrant_id == $currentUser->id;
|
||||||
}),
|
}),
|
||||||
new TwigFunction('hasRole', function ($roleSlug) {
|
|
||||||
$currentUser = $this->services->currentUser;
|
|
||||||
return $currentUser->roles()->where('slug', $roleSlug)->count() > 0;
|
|
||||||
}),
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getGlobals()
|
public function getGlobals(): array
|
||||||
{
|
{
|
||||||
$config = $this->services->config['organisation'];
|
$config = $this->services->config['organisation'];
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{% include "@uf-tweaks/forms/inputs/abstract/description.html.twig" with
|
||||||
|
{
|
||||||
|
"type" : "organisation",
|
||||||
|
"current_value" : organisation.description,
|
||||||
|
"col_width" : col_width
|
||||||
|
}
|
||||||
|
%}
|
||||||
8
templates/forms/inputs/organisation-name.html.twig
Normal file
8
templates/forms/inputs/organisation-name.html.twig
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{% include "@uf-tweaks/forms/inputs/abstract/name.html.twig" with
|
||||||
|
{
|
||||||
|
"type" : "organisation",
|
||||||
|
"current_value" : organisation.name,
|
||||||
|
"field_name" : translate('ORGANISATION.NAME'),
|
||||||
|
"col_width" : col_width
|
||||||
|
}
|
||||||
|
%}
|
||||||
7
templates/forms/inputs/organisation-slug.html.twig
Normal file
7
templates/forms/inputs/organisation-slug.html.twig
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{% include "@uf-tweaks/forms/inputs/abstract/slug.html.twig" with
|
||||||
|
{
|
||||||
|
"type" : "organisation",
|
||||||
|
"current_value" : organisation.slug,
|
||||||
|
"col_width" : col_width
|
||||||
|
}
|
||||||
|
%}
|
||||||
@@ -4,64 +4,26 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
{% block organisation_form %}
|
{% block organisation_form %}
|
||||||
{% block organisation_field_name %}
|
{% block input_organisation_name %}
|
||||||
{% if 'name' not in form.fields.hidden %}
|
{% include "forms/inputs/organisation-name.html.twig" with { 'col_width': 'col-sm-12' } %}
|
||||||
<div class="col-sm-12">
|
|
||||||
<div class="form-group">
|
|
||||||
<label>{{translate("ORGANISATION.NAME")}}</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<span class="input-group-addon"><i class="fas fa-edit fa-fw"></i></span>
|
|
||||||
<input type="text" class="form-control" name="name" autocomplete="off" value="{{organisation.name}}" placeholder="{{translate("ORGANISATION.NAME.EXPLAIN")}}" {% if 'name' in form.fields.disabled %}disabled{% endif %}>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block organisation_field_slug %}
|
{% block input_organisation_slug %}
|
||||||
{% if 'slug' not in form.fields.hidden %}
|
{% include "forms/inputs/organisation-slug.html.twig" with { 'col_width': 'col-sm-12' } %}
|
||||||
<div class="col-sm-12">
|
|
||||||
<div class="form-group">
|
|
||||||
<label>{{translate("SLUG")}}</label>
|
|
||||||
<div class="input-group">
|
|
||||||
<span class="input-group-addon"><i class="fas fa-tag fa-fw"></i></span>
|
|
||||||
<input type="text" class="form-control" name="slug" autocomplete="off" value="{{organisation.slug}}" placeholder="{{translate("SLUG")}}" {% if 'slug' in form.fields.disabled %}disabled{% endif %} readonly>
|
|
||||||
{% if 'slug' not in form.fields.disabled %}
|
|
||||||
<span class="input-group-btn" data-toggle="buttons">
|
|
||||||
<label class="btn btn-primary">
|
|
||||||
<input type="checkbox" id="form-organisation-slug-override" autocomplete="off"> {{translate("OVERRIDE")}}
|
|
||||||
</label>
|
|
||||||
</span>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% else %}
|
|
||||||
<input type="hidden" name="slug" autocomplete="off" value="{{organisation.slug}}">
|
|
||||||
{% endif %}
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block organisation_field_description %}
|
{% block input_organisation_description %}
|
||||||
{% if 'description' not in form.fields.hidden %}
|
{% include "forms/inputs/organisation-description.html.twig" with { 'col_width': 'col-sm-12' } %}
|
||||||
<div class="col-sm-12">
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="input_description">{{translate("DESCRIPTION")}}</label>
|
|
||||||
<textarea id="input_description" class="form-control" type="text" name="description" {% if 'description' in form.fields.disabled %}disabled{% endif %} rows=6>{{organisation.description}}</textarea>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
</div><br>
|
</div><br>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
{% block organisation_form_buttons %}
|
|
||||||
<div class="col-xs-6 col-sm-4">
|
<div class="col-xs-6 col-sm-4">
|
||||||
<button type="submit" class="btn btn-block btn-lg btn-success">{{form.submit_text}}</button>
|
<button type="submit" class="btn btn-block btn-lg btn-success">{{form.submit_text}}</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-xs-4 col-sm-3 pull-right">
|
<div class="col-xs-4 col-sm-3 pull-right">
|
||||||
<button type="button" class="btn btn-block btn-lg btn-link" data-dismiss="modal">{{translate("CANCEL")}}</button>
|
<button type="button" class="btn btn-block btn-lg btn-link" data-dismiss="modal">{{translate("CANCEL")}}</button>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
<!-- Include validation rules -->
|
<!-- Include validation rules -->
|
||||||
|
|||||||
@@ -3,6 +3,12 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
|
{% if admin_fallback %}
|
||||||
|
<hr style="color: #990000" />
|
||||||
|
<h3 style="color: #990000">You are receiving this email as an organisation/site administrator!</h3>
|
||||||
|
<p style="color: #990000">This email has been sent to you in lieu of <b>{{organisation.name}}</b> as there are currently no approved administrators for the organisation.</p>
|
||||||
|
<hr style="color: #990000" />
|
||||||
|
{% endif %}
|
||||||
<p>
|
<p>
|
||||||
Dear {{recipient.first_name}},
|
Dear {{recipient.first_name}},
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@@ -7,10 +7,10 @@
|
|||||||
{% include "forms/csrf.html.twig" %}
|
{% include "forms/csrf.html.twig" %}
|
||||||
<div class="js-form-alerts">
|
<div class="js-form-alerts">
|
||||||
</div>
|
</div>
|
||||||
<h4>
|
<p>
|
||||||
{{translate("ORGANISATION.JOIN_REQUEST.ACCEPT_CONFIRM", {name: organisation.name, agent_name: agent.name})}}<br>
|
{{translate("ORGANISATION.JOIN_REQUEST.ACCEPT_CONFIRM", {name: organisation.name, agent_name: agent.name})}}<br>
|
||||||
<small>{{translate("ORGANISATION.JOIN_REQUEST.ACCEPT_CONFIRM_EXTRA", {name: organisation.name, agent_name: agent.name})}}</small>
|
<small>{{translate("ORGANISATION.JOIN_REQUEST.ACCEPT_CONFIRM_EXTRA", {name: organisation.name, agent_name: agent.name})}}</small>
|
||||||
</h4>
|
</p>
|
||||||
<br>
|
<br>
|
||||||
<div class="btn-group-action">
|
<div class="btn-group-action">
|
||||||
<button type="submit" class="btn btn-success btn-lg btn-block">{{translate("ORGANISATION.JOIN_REQUEST.ACCEPT_YES")}}</button>
|
<button type="submit" class="btn btn-success btn-lg btn-block">{{translate("ORGANISATION.JOIN_REQUEST.ACCEPT_YES")}}</button>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
{% include "forms/csrf.html.twig" %}
|
{% include "forms/csrf.html.twig" %}
|
||||||
<div class="js-form-alerts">
|
<div class="js-form-alerts">
|
||||||
</div>
|
</div>
|
||||||
<h4>{{translate("ORGANISATION.JOIN_REQUEST.CANCEL_CONFIRM", {name: organisation.name})}}{% if delete_hard %}<br><small>{{translate("ACTION_CANNOT_UNDONE")}}</small>{% endif %}</h4>
|
<p>{{translate("ORGANISATION.JOIN_REQUEST.CANCEL_CONFIRM", {name: organisation.name})}}{% if delete_hard %}<br><small>{{translate("ACTION_CANNOT_UNDONE")}}</small>{% endif %}</p>
|
||||||
<br>
|
<br>
|
||||||
<div class="btn-group-action">
|
<div class="btn-group-action">
|
||||||
<button type="submit" class="btn btn-danger btn-lg btn-block">{{translate("ORGANISATION.JOIN_REQUEST.CANCEL_YES")}}</button>
|
<button type="submit" class="btn btn-danger btn-lg btn-block">{{translate("ORGANISATION.JOIN_REQUEST.CANCEL_YES")}}</button>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
{% include "forms/csrf.html.twig" %}
|
{% include "forms/csrf.html.twig" %}
|
||||||
<div class="js-form-alerts">
|
<div class="js-form-alerts">
|
||||||
</div>
|
</div>
|
||||||
<h4>{{translate("ORGANISATION.REGISTRATION.CANCEL_CONFIRM", {name: organisation.name})}}{% if delete_hard %}<br><small>{{translate("ACTION_CANNOT_UNDONE")}}</small>{% endif %}</h4>
|
<p>{{translate("ORGANISATION.REGISTRATION.CANCEL_CONFIRM", {name: organisation.name})}}{% if delete_hard %}<br><small>{{translate("ACTION_CANNOT_UNDONE")}}</small>{% endif %}</p>
|
||||||
<br>
|
<br>
|
||||||
<div class="btn-group-action">
|
<div class="btn-group-action">
|
||||||
<button type="submit" class="btn btn-danger btn-lg btn-block">{{translate("ORGANISATION.REGISTRATION.CANCEL_YES")}}</button>
|
<button type="submit" class="btn btn-danger btn-lg btn-block">{{translate("ORGANISATION.REGISTRATION.CANCEL_YES")}}</button>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
{% include "forms/csrf.html.twig" %}
|
{% include "forms/csrf.html.twig" %}
|
||||||
<div class="js-form-alerts">
|
<div class="js-form-alerts">
|
||||||
</div>
|
</div>
|
||||||
<h4>{{translate("ORGANISATION.DELETE_CONFIRM", {name: organisation.name})}}{% if delete_hard %}<br><small>{{translate("DELETE_CANNOT_UNDONE")}}</small>{% endif %}</h4>
|
<p>{{translate("ORGANISATION.DELETE_CONFIRM", {name: organisation.name})}}{% if delete_hard %}<br><small>{{translate("DELETE_CANNOT_UNDONE")}}</small>{% endif %}</p>
|
||||||
<br>
|
<br>
|
||||||
<div class="btn-group-action">
|
<div class="btn-group-action">
|
||||||
<button type="submit" class="btn btn-danger btn-lg btn-block">{{translate("ORGANISATION.DELETE_YES")}}</button>
|
<button type="submit" class="btn btn-danger btn-lg btn-block">{{translate("ORGANISATION.DELETE_YES")}}</button>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
{% include "forms/csrf.html.twig" %}
|
{% include "forms/csrf.html.twig" %}
|
||||||
<div class="js-form-alerts">
|
<div class="js-form-alerts">
|
||||||
</div>
|
</div>
|
||||||
<h4>{{translate("ORGANISATION.MEMBER.DEMOTE_CONFIRM", {user_name: user.user_name, name: organisation.name})}}<br><small>{{translate("ORGANISATION.MEMBER.DEMOTE_CONFIRM_EXTRA")}}</small></h4>
|
<p>{{translate("ORGANISATION.MEMBER.DEMOTE_CONFIRM", {user_name: user.user_name, name: organisation.name})}}<br><small>{{translate("ORGANISATION.MEMBER.DEMOTE_CONFIRM_EXTRA")}}</small></p>
|
||||||
<br>
|
<br>
|
||||||
<div class="btn-group-action">
|
<div class="btn-group-action">
|
||||||
<button type="submit" class="btn btn-danger btn-lg btn-block">{{translate("ORGANISATION.MEMBER.DEMOTE_YES")}}</button>
|
<button type="submit" class="btn btn-danger btn-lg btn-block">{{translate("ORGANISATION.MEMBER.DEMOTE_YES")}}</button>
|
||||||
|
|||||||
@@ -8,12 +8,12 @@
|
|||||||
<div class="js-form-alerts">
|
<div class="js-form-alerts">
|
||||||
</div>
|
</div>
|
||||||
{% if approval_required %}
|
{% if approval_required %}
|
||||||
<h4>
|
<p>
|
||||||
{{translate("ORGANISATION.JOIN_REQUEST.REQUEST_CONFIRM", {name: organisation.name})}}
|
{{translate("ORGANISATION.JOIN_REQUEST.REQUEST_CONFIRM", {name: organisation.name})}}
|
||||||
<small>{{translate("ORGANISATION.JOIN_REQUEST.APPROVAL_REQUIRED")}}</small>
|
<small>{{translate("ORGANISATION.JOIN_REQUEST.APPROVAL_REQUIRED")}}</small>
|
||||||
</h4>
|
</p>
|
||||||
{% else %}
|
{% else %}
|
||||||
<h4>{{translate("ORGANISATION.JOIN_CONFIRM", {name: organisation.name})}}</h4>
|
<p>{{translate("ORGANISATION.JOIN_CONFIRM", {name: organisation.name})}}</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<br>
|
<br>
|
||||||
<div class="btn-group-action">
|
<div class="btn-group-action">
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
{% include "forms/csrf.html.twig" %}
|
{% include "forms/csrf.html.twig" %}
|
||||||
<div class="js-form-alerts">
|
<div class="js-form-alerts">
|
||||||
</div>
|
</div>
|
||||||
<h4>{{translate("ORGANISATION.LEAVE_CONFIRM", {name: organisation.name})}}<br><small>{{translate("ACTION_CANNOT_UNDONE")}}</small></h4>
|
<p>{{translate("ORGANISATION.LEAVE_CONFIRM", {name: organisation.name})}}<br><small>{{translate("ACTION_CANNOT_UNDONE")}}</small></p>
|
||||||
<br>
|
<br>
|
||||||
<div class="btn-group-action">
|
<div class="btn-group-action">
|
||||||
<button type="submit" class="btn btn-danger btn-lg btn-block">{{translate("ORGANISATION.LEAVE_YES")}}</button>
|
<button type="submit" class="btn btn-danger btn-lg btn-block">{{translate("ORGANISATION.LEAVE_YES")}}</button>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
{% include "forms/csrf.html.twig" %}
|
{% include "forms/csrf.html.twig" %}
|
||||||
<div class="js-form-alerts">
|
<div class="js-form-alerts">
|
||||||
</div>
|
</div>
|
||||||
<h4>{{translate("ORGANISATION.PERMENENT_DELETE_CONFIRM", {name: organisation.name})}}<br><small>{{translate("ACTION_CANNOT_UNDONE")}}</small></h4>
|
<p>{{translate("ORGANISATION.PERMENENT_DELETE_CONFIRM", {name: organisation.name})}}<br><small>{{translate("ACTION_CANNOT_UNDONE")}}</small></p>
|
||||||
<br>
|
<br>
|
||||||
<div class="btn-group-action">
|
<div class="btn-group-action">
|
||||||
<button type="submit" class="btn btn-danger btn-lg btn-block">{{translate("ORGANISATION.PERMENENT_DELETE_YES")}}</button>
|
<button type="submit" class="btn btn-danger btn-lg btn-block">{{translate("ORGANISATION.PERMENENT_DELETE_YES")}}</button>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
{% include "forms/csrf.html.twig" %}
|
{% include "forms/csrf.html.twig" %}
|
||||||
<div class="js-form-alerts">
|
<div class="js-form-alerts">
|
||||||
</div>
|
</div>
|
||||||
<h4>{{translate("ORGANISATION.MEMBER.PROMOTE_CONFIRM", {user_name: user.user_name, name: organisation.name})}}</h4>
|
<p>{{translate("ORGANISATION.MEMBER.PROMOTE_CONFIRM", {user_name: user.user_name, name: organisation.name})}}</p>
|
||||||
<br>
|
<br>
|
||||||
<p>{{translate("ORGANISATION.MEMBER.PROMOTE_CONFIRM_EXTRA")}}</p>
|
<p>{{translate("ORGANISATION.MEMBER.PROMOTE_CONFIRM_EXTRA")}}</p>
|
||||||
<br>
|
<br>
|
||||||
|
|||||||
@@ -7,10 +7,10 @@
|
|||||||
{% include "forms/csrf.html.twig" %}
|
{% include "forms/csrf.html.twig" %}
|
||||||
<div class="js-form-alerts">
|
<div class="js-form-alerts">
|
||||||
</div>
|
</div>
|
||||||
<h4>
|
<p>
|
||||||
{{translate("ORGANISATION.JOIN_REQUEST.REJECT_CONFIRM", {name: organisation.name, agent_name: agent.name})}}<br>
|
{{translate("ORGANISATION.JOIN_REQUEST.REJECT_CONFIRM", {name: organisation.name, agent_name: agent.name})}}<br>
|
||||||
<small>{{translate("ORGANISATION.JOIN_REQUEST.REJECT_CONFIRM_EXTRA", {name: organisation.name, agent_name: agent.name})}}</small>
|
<small>{{translate("ORGANISATION.JOIN_REQUEST.REJECT_CONFIRM_EXTRA", {name: organisation.name, agent_name: agent.name})}}</small>
|
||||||
</h4>
|
</p>
|
||||||
<br>
|
<br>
|
||||||
<div class="btn-group-action">
|
<div class="btn-group-action">
|
||||||
<button type="submit" class="btn btn-success btn-lg btn-block">{{translate("ORGANISATION.JOIN_REQUEST.REJECT_YES")}}</button>
|
<button type="submit" class="btn btn-success btn-lg btn-block">{{translate("ORGANISATION.JOIN_REQUEST.REJECT_YES")}}</button>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
{% include "forms/csrf.html.twig" %}
|
{% include "forms/csrf.html.twig" %}
|
||||||
<div class="js-form-alerts">
|
<div class="js-form-alerts">
|
||||||
</div>
|
</div>
|
||||||
<h4>{{translate("ORGANISATION.MEMBER.REMOVE_CONFIRM", {user_name: user.user_name, name: organisation.name})}}<br><small>{{translate("ACTION_CANNOT_UNDONE")}}</small></h4>
|
<p>{{translate("ORGANISATION.MEMBER.REMOVE_CONFIRM", {user_name: user.user_name, name: organisation.name})}}<br><small>{{translate("ACTION_CANNOT_UNDONE")}}</small></p>
|
||||||
<br>
|
<br>
|
||||||
<div class="btn-group-action">
|
<div class="btn-group-action">
|
||||||
<button type="submit" class="btn btn-danger btn-lg btn-block">{{translate("ORGANISATION.MEMBER.REMOVE_YES")}}</button>
|
<button type="submit" class="btn btn-danger btn-lg btn-block">{{translate("ORGANISATION.MEMBER.REMOVE_YES")}}</button>
|
||||||
|
|||||||
32
templates/modals/member-reset-password.html.twig
Normal file
32
templates/modals/member-reset-password.html.twig
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
{% extends "modals/modal.html.twig" %}
|
||||||
|
|
||||||
|
{% block modal_title %}{{translate("ORGANISATION.MEMBER.RESET_PASSWORD")}}{% endblock %}
|
||||||
|
|
||||||
|
{% block modal_body %}
|
||||||
|
<form class="js-form" method="POST" action="{{site.uri.public}}/api/organisations/o/{{organisation.slug}}/members/m/{{user.user_name}}/password-reset">
|
||||||
|
{% include "forms/csrf.html.twig" %}
|
||||||
|
<div class="js-form-alerts">
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
{{translate("ORGANISATION.MEMBER.SEND_PASSWORD_LINK_CONFIRM", {
|
||||||
|
'user_name': user.user_name,
|
||||||
|
'email': user.email
|
||||||
|
})}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xs-8 col-sm-4">
|
||||||
|
<button type="submit" class="btn btn-block btn-lg btn-success">{{translate('CONFIRM')}}</button>
|
||||||
|
</div>
|
||||||
|
<div class="col-xs-4 col-sm-3 pull-right">
|
||||||
|
<button type="button" class="btn btn-block btn-lg btn-link" data-dismiss="modal">{{translate('CANCEL')}}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<!-- Include validation rules -->
|
||||||
|
<script>
|
||||||
|
{% include "pages/partials/page.js.twig" %}
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
<div class="js-form-alerts">
|
<div class="js-form-alerts">
|
||||||
</div>
|
</div>
|
||||||
<div class="js-form-organisations">
|
<div class="js-form-organisations">
|
||||||
<h4>{{translate("ORGANISATION.MERGE_INFORM", {name: organisation.name})}}<br><small>{{translate("MERGE_CANNOT_UNDONE")}}</small></h4>
|
<p>{{translate("ORGANISATION.MERGE_INFORM", {name: organisation.name})}}<br><small>{{translate("MERGE_CANNOT_UNDONE")}}</small></p>
|
||||||
<div class="padding-bottom">
|
<div class="padding-bottom">
|
||||||
<label>{{translate("MERGE_INTO")}}:</label>
|
<label>{{translate("MERGE_INTO")}}:</label>
|
||||||
<select class="form-control js-select-new" type="text" name="target_slug"></select>
|
<select class="form-control js-select-new" type="text" name="target_slug"></select>
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
{% if checkAccess('uri_organisations') %}
|
||||||
|
<li>
|
||||||
|
<a href="{{site.uri.public}}/organisations"><i class="fas fa-sitemap fa-fw"></i> <span>{{ translate("ORGANISATION", 2) }}</span></a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
{% if current_user.organisations.count() > 0 %}
|
||||||
|
{% if organisationConfig.membership.single_membership == false %}
|
||||||
|
<li>
|
||||||
|
<a href="#" data-toggle="collapse" data-target="#submenu-organisations" aria-expanded="false"><i class="fa fa-fw fa-sitemap"></i> <span>{{ translate("ORGANISATION.SELF") }}</span> <i class="fa fa-fw pull-right fa-angle-down"></i></a>
|
||||||
|
<ul id="submenu-organisations" class="collapsable collapse" aria-expanded="false" style="height: 1px;">
|
||||||
|
{% for organisation in current_user.organisations %}
|
||||||
|
{% if organisation.flag_approved or isOrganisationRegistrant(organisation) %}
|
||||||
|
<li>
|
||||||
|
<a href="{{site.uri.public}}/organisations/o/{{organisation.slug}}"><i class="fas fa-angle-double-right"></i> <span>{{organisation.name}}</span></a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
{% else %}
|
||||||
|
{% set organisation = current_user.organisations.0 %}
|
||||||
|
{% if organisation.flag_approved or isOrganisationRegistrant(organisation) %}
|
||||||
|
<li>
|
||||||
|
<a href="{{site.uri.public}}/organisations/o/{{organisation.slug}}"><i class="fas fa-sitemap fa-fw"></i> <span>{{ translate("ORGANISATION.SELF") }}</span></a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
{% if checkAccess('uri_organisations') %}
|
||||||
|
<a href="{{site.uri.public}}/organisations" class="btn btn-default btn-flat btn-block">{{ translate("ORGANISATION", 2) }}</a>
|
||||||
|
{% endif %}
|
||||||
@@ -1,37 +1,9 @@
|
|||||||
{% extends "@admin/navigation/sidebar-menu.html.twig" %}
|
{% extends "@admin/navigation/sidebar-menu.html.twig" %}
|
||||||
|
|
||||||
{% block organisations_nav %}
|
|
||||||
{% if checkAccess('uri_organisations') %}
|
|
||||||
<li>
|
|
||||||
<a href="{{site.uri.public}}/organisations"><i class="fas fa-sitemap fa-fw"></i> <span>{{ translate("ORGANISATION", 2) }}</span></a>
|
|
||||||
</li>
|
|
||||||
{% endif %}
|
|
||||||
{% if current_user.organisations.count() > 0 %}
|
|
||||||
{% if organisationConfig.membership.single_membership == false %}
|
|
||||||
<li>
|
|
||||||
<a href="#" data-toggle="collapse" data-target="#submenu-organisations" aria-expanded="false"><i class="fa fa-fw fa-sitemap"></i> <span>{{ translate("ORGANISATION.SELF") }}</span> <i class="fa fa-fw pull-right fa-angle-down"></i></a>
|
|
||||||
<ul id="submenu-organisations" class="collapsable collapse" aria-expanded="false" style="height: 1px;">
|
|
||||||
{% for organisation in current_user.organisations %}
|
|
||||||
{% if organisation.flag_approved or isOrganisationRegistrant(organisation) %}
|
|
||||||
<li>
|
|
||||||
<a href="{{site.uri.public}}/organisations/o/{{organisation.slug}}"><i class="fas fa-angle-double-right"></i> <span>{{organisation.name}}</span></a>
|
|
||||||
</li>
|
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
{% else %}
|
|
||||||
{% set organisation = current_user.organisations.0 %}
|
|
||||||
{% if organisation.flag_approved or isOrganisationRegistrant(organisation) %}
|
|
||||||
<li>
|
|
||||||
<a href="{{site.uri.public}}/organisations/o/{{organisation.slug}}"><i class="fas fa-sitemap fa-fw"></i> <span>{{ translate("ORGANISATION.SELF") }}</span></a>
|
|
||||||
</li>
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block navigation %}
|
{% block navigation %}
|
||||||
{{ parent() }}
|
{{ parent() }}
|
||||||
{{ block('organisations_nav') }}
|
|
||||||
|
{% block navigation_organisations %}
|
||||||
|
{% include "navigation/partials/sidebar-organisations.html.twig" %}
|
||||||
|
{% endblock %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
11
templates/navigation/user-card.html.twig
Normal file
11
templates/navigation/user-card.html.twig
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{% extends "@admin/navigation/user-card.html.twig" %}
|
||||||
|
|
||||||
|
{% block userCard_menu %}
|
||||||
|
<a href="{{site.uri.public}}" class="btn btn-default btn-flat btn-block">Homepage</a>
|
||||||
|
|
||||||
|
{% block navigation_organisations %}
|
||||||
|
{% include "navigation/partials/user-card-organisations.html.twig" %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{{ parent() }}
|
||||||
|
{% endblock %}
|
||||||
15
templates/pages/account-settings.html.twig
Normal file
15
templates/pages/account-settings.html.twig
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
{% extends "@account/pages/account-settings.html.twig" %}
|
||||||
|
|
||||||
|
{% block body_matter %}
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-6">
|
||||||
|
{% block settings_profile_box %} {{ parent() }} {% endblock %}
|
||||||
|
{% block user_organisations_box %}
|
||||||
|
{% include "pages/partials/settings-organisations.html.twig" %}
|
||||||
|
{% endblock %}
|
||||||
|
</div>
|
||||||
|
<div class="col-lg-6">
|
||||||
|
{% block settings_account_box %} {{ parent() }} {% endblock %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
@@ -1,10 +1,12 @@
|
|||||||
{% extends "@blockier-templates/pages/dashboard.html.twig" %}
|
{% extends "@uf-tweaks/pages/dashboard.html.twig" %}
|
||||||
|
|
||||||
{% block info_boxes_users %}
|
{% block body_matter %}
|
||||||
{% if hasRole('site-admin') or hasRole('organisations-admin') %}
|
{% set dashboard_is_empty = true %}
|
||||||
|
|
||||||
|
<!-- Info boxes -->
|
||||||
<div class="row">
|
<div class="row">
|
||||||
{% block info_box_users %}
|
|
||||||
{% if checkAccess('uri_users') %}
|
{% if checkAccess('uri_users') %}
|
||||||
|
{% set dashboard_is_empty = false %}
|
||||||
<div class="col-lg-3 col-md-6 col-xs-12">
|
<div class="col-lg-3 col-md-6 col-xs-12">
|
||||||
<a href="{{site.uri.public}}/users">
|
<a href="{{site.uri.public}}/users">
|
||||||
<div class="info-box">
|
<div class="info-box">
|
||||||
@@ -20,10 +22,9 @@
|
|||||||
</div>
|
</div>
|
||||||
<!-- /.col -->
|
<!-- /.col -->
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block info_box_roles %}
|
|
||||||
{% if checkAccess('uri_roles') %}
|
{% if checkAccess('uri_roles') %}
|
||||||
|
{% set dashboard_is_empty = false %}
|
||||||
<div class="col-lg-3 col-md-6 col-xs-12">
|
<div class="col-lg-3 col-md-6 col-xs-12">
|
||||||
<a href="{{site.uri.public}}/roles">
|
<a href="{{site.uri.public}}/roles">
|
||||||
<div class="info-box">
|
<div class="info-box">
|
||||||
@@ -39,14 +40,13 @@
|
|||||||
</div>
|
</div>
|
||||||
<!-- /.col -->
|
<!-- /.col -->
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block info_box_groups %}
|
|
||||||
{% if checkAccess('uri_groups') %}
|
{% if checkAccess('uri_groups') %}
|
||||||
|
{% set dashboard_is_empty = false %}
|
||||||
<div class="col-lg-3 col-md-6 col-xs-12">
|
<div class="col-lg-3 col-md-6 col-xs-12">
|
||||||
<a href="{{site.uri.public}}/groups">
|
<a href="{{site.uri.public}}/groups">
|
||||||
<div class="info-box">
|
<div class="info-box">
|
||||||
<span class="info-box-icon bg-yellow"><i class="fas fa-users"></i></span>
|
<span class="info-box-icon bg-green"><i class="fas fa-users"></i></span>
|
||||||
<div class="info-box-content">
|
<div class="info-box-content">
|
||||||
<span class="info-box-text">{{ translate("GROUP", 2) }}</span>
|
<span class="info-box-text">{{ translate("GROUP", 2) }}</span>
|
||||||
<span class="info-box-number">{{counter.groups}}</span>
|
<span class="info-box-number">{{counter.groups}}</span>
|
||||||
@@ -58,14 +58,13 @@
|
|||||||
</div>
|
</div>
|
||||||
<!-- /.col -->
|
<!-- /.col -->
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block info_box_organisations %}
|
|
||||||
{% if checkAccess('uri_organisations') %}
|
{% if checkAccess('uri_organisations') %}
|
||||||
|
{% set dashboard_is_empty = false %}
|
||||||
<div class="col-lg-3 col-md-6 col-xs-12">
|
<div class="col-lg-3 col-md-6 col-xs-12">
|
||||||
<a href="{{site.uri.public}}/organisations">
|
<a href="{{site.uri.public}}/organisations">
|
||||||
<div class="info-box">
|
<div class="info-box">
|
||||||
<span class="info-box-icon bg-green"><i class="fas fa-users"></i></span>
|
<span class="info-box-icon bg-purple"><i class="fas fa-sitemap"></i></span>
|
||||||
<div class="info-box-content">
|
<div class="info-box-content">
|
||||||
<span class="info-box-text">{{ translate("ORGANISATION", 2) }}</span>
|
<span class="info-box-text">{{ translate("ORGANISATION", 2) }}</span>
|
||||||
<span class="info-box-number">{{counter.organisations}}</span>
|
<span class="info-box-number">{{counter.organisations}}</span>
|
||||||
@@ -77,18 +76,100 @@
|
|||||||
</div>
|
</div>
|
||||||
<!-- /.col -->
|
<!-- /.col -->
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
|
||||||
</div>
|
</div>
|
||||||
<!-- /.row -->
|
<!-- /.row -->
|
||||||
{% endif %}
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
|
<!-- Main panels -->
|
||||||
|
|
||||||
{% block latest_organisations %}
|
|
||||||
{% if (hasRole('site-admin') or hasRole('organisations-admin')) %}
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-12">
|
{% if checkAccess('view_system_info') %}
|
||||||
|
{% set dashboard_is_empty = false %}
|
||||||
|
<div class="col-md-6 col-sm-12 col-xs-12">
|
||||||
|
<div class="box box-primary">
|
||||||
|
<div class="box-header with-border">
|
||||||
|
<h3 class="box-title">{{translate("SYSTEM_INFO")}}</h3>
|
||||||
|
</div>
|
||||||
|
<!-- /.box-header -->
|
||||||
|
<div class="box-body">
|
||||||
|
<dl class="dl-horizontal">
|
||||||
|
<dt>{{translate("SYSTEM_INFO.UF_VERSION")}}</dt>
|
||||||
|
<dd>{{info.version.UF}}</dd>
|
||||||
|
|
||||||
|
<dt>{{translate("SYSTEM_INFO.PHP_VERSION")}}</dt>
|
||||||
|
<dd>{{info.version.php}}</dd>
|
||||||
|
|
||||||
|
<dt>{{translate("SYSTEM_INFO.SERVER")}}</dt>
|
||||||
|
<dd>{{info.environment.SERVER_SOFTWARE}}</dd>
|
||||||
|
|
||||||
|
<dt>{{translate("SYSTEM_INFO.DB_VERSION")}}</dt>
|
||||||
|
<dd>{{info.version.database.type}} {{info.version.database.version}}</dd>
|
||||||
|
|
||||||
|
<dt>{{translate("SYSTEM_INFO.DB_NAME")}}</dt>
|
||||||
|
<dd>{{info.database.name}}</dd>
|
||||||
|
|
||||||
|
<dt>{{translate("SYSTEM_INFO.DIRECTORY")}}</dt>
|
||||||
|
<dd>{{info.path.project}}</dd>
|
||||||
|
|
||||||
|
<dt>{{translate("SYSTEM_INFO.URL")}}</dt>
|
||||||
|
<dd>{{site.uri.public}}</dd>
|
||||||
|
|
||||||
|
<dt>{{translate("SYSTEM_INFO.SPRINKLES")}}</dt>
|
||||||
|
<dd>
|
||||||
|
<ul class="list-unstyled">
|
||||||
|
{% for sprinkle in sprinkles %}
|
||||||
|
<li>
|
||||||
|
{{sprinkle}}
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
</div>
|
||||||
|
<!-- /.box-body -->
|
||||||
|
<div class="box-footer text-center">
|
||||||
|
<a href="javascript:void(0)" class="js-clear-cache uppercase">{{ translate("CACHE.CLEAR") }}</a>
|
||||||
|
</div>
|
||||||
|
<!-- /.box-footer -->
|
||||||
|
</div>
|
||||||
|
<!--/.box -->
|
||||||
|
</div>
|
||||||
|
<!-- /.col -->
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if checkAccess('uri_users') %}
|
||||||
|
{% set dashboard_is_empty = false %}
|
||||||
|
<div class="col-md-6 col-sm-12 col-xs-12">
|
||||||
|
<!-- USERS LIST -->
|
||||||
|
<div class="box box-info">
|
||||||
|
<div class="box-header with-border">
|
||||||
|
<h3 class="box-title">{{translate("USER.LATEST")}}</h3>
|
||||||
|
</div>
|
||||||
|
<!-- /.box-header -->
|
||||||
|
<div class="box-body no-padding">
|
||||||
|
<ul class="users-list clearfix">
|
||||||
|
{% for user in users %}
|
||||||
|
<li>
|
||||||
|
<img src="{{ user.avatar }}" alt="User Image">
|
||||||
|
<a class="users-list-name" href="{{site.uri.public}}/users/u/{{user.user_name}}">{{user.first_name}} {{user.last_name}}</a>
|
||||||
|
<span class="users-list-date">{{ user.registered }}</span>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
<!-- /.users-list -->
|
||||||
|
</div>
|
||||||
|
<!-- /.box-body -->
|
||||||
|
<div class="box-footer text-center">
|
||||||
|
<a href="{{site.uri.public}}/users" class="uppercase">{{translate("USER.VIEW_ALL")}}</a>
|
||||||
|
</div>
|
||||||
|
<!-- /.box-footer -->
|
||||||
|
</div>
|
||||||
|
<!--/.box -->
|
||||||
|
</div>
|
||||||
|
<!-- /.col -->
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if hasRole('organisations-admin') %}
|
||||||
|
{% set dashboard_is_empty = false %}
|
||||||
|
<div class="col-md-6 col-sm-12 col-xs-12">
|
||||||
<!-- ORGANISTIONS LIST -->
|
<!-- ORGANISTIONS LIST -->
|
||||||
<div class="box box-info">
|
<div class="box box-info">
|
||||||
<div class="box-header with-border">
|
<div class="box-header with-border">
|
||||||
@@ -97,10 +178,9 @@
|
|||||||
<!-- /.box-header -->
|
<!-- /.box-header -->
|
||||||
<div class="box-body no-padding clearfix">
|
<div class="box-body no-padding clearfix">
|
||||||
{% for organisation in organisations %}
|
{% for organisation in organisations %}
|
||||||
|
|
||||||
<div class="col-sm-6 col-xs-12">
|
<div class="col-sm-6 col-xs-12">
|
||||||
<div class="box box-widget widget-user-2 widget-organisations">
|
<div class="box box-widget widget-user-2 widget-organisations">
|
||||||
<div class="widget-user-header bg-green">
|
<div class="widget-user-header bg-purple">
|
||||||
<h3 class="widget-user-username">{{organisation.name}}</h3>
|
<h3 class="widget-user-username">{{organisation.name}}</h3>
|
||||||
<h5 class="widget-user-desc">{{organisation.description}}</h5>
|
<h5 class="widget-user-desc">{{organisation.description}}</h5>
|
||||||
</div>
|
</div>
|
||||||
@@ -114,7 +194,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
<!-- /.organistions-list -->
|
<!-- /.organistions-list -->
|
||||||
</div>
|
</div>
|
||||||
@@ -127,49 +206,11 @@
|
|||||||
<!--/.box -->
|
<!--/.box -->
|
||||||
</div>
|
</div>
|
||||||
<!-- /.col -->
|
<!-- /.col -->
|
||||||
</div>
|
|
||||||
<!-- /.row -->
|
|
||||||
{% endif %}
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{% set empty_dashboard = true %}
|
|
||||||
{% block main_panels %}
|
|
||||||
{% if
|
|
||||||
checkAccess('uri_users') or
|
|
||||||
checkAccess('view_group_field', {
|
|
||||||
'group': current_user.group,
|
|
||||||
'property': 'users'
|
|
||||||
}) or
|
|
||||||
hasRole('site-admin') or
|
|
||||||
hasRole('organisations-admin')
|
|
||||||
%}
|
|
||||||
{% set empty_dashboard = false %}
|
|
||||||
<div class="row">
|
|
||||||
{% block left_panels %}
|
|
||||||
<div class="col-md-6 col-sm-12 col-xs-12">
|
|
||||||
{{ block("latest_users") }}
|
|
||||||
|
|
||||||
{{ block("group_users_summary") }}
|
|
||||||
</div>
|
|
||||||
<!-- /.col -->
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block right_panels %}
|
|
||||||
<div class="col-md-6 col-sm-12 col-xs-12">
|
|
||||||
{{ block("latest_organisations") }}
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
||||||
</div>
|
|
||||||
<!-- /.row -->
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if checkAccess('uri_activities') %}
|
{% if checkAccess('uri_activities') %}
|
||||||
{% set empty_dashboard = false %}
|
{% set dashboard_is_empty = false %}
|
||||||
<div class="row">
|
<div class="col-md-{% if (hasRole('auditer')) %}12{% else %}6{% endif %} col-sm-12 col-xs-12">
|
||||||
{% if checkAccess('uri_activities') %}
|
|
||||||
<div class="col-md-12 col-sm-12 col-xs-12">
|
|
||||||
<div id="widget-activities" class="box box-primary">
|
<div id="widget-activities" class="box box-primary">
|
||||||
<div class="box-header">
|
<div class="box-header">
|
||||||
<h3 class="box-title"><i class="fas fa-tasks fa-fw"></i> {{translate('ACTIVITY', 2)}}</h3>
|
<h3 class="box-title"><i class="fas fa-tasks fa-fw"></i> {{translate('ACTIVITY', 2)}}</h3>
|
||||||
@@ -189,23 +230,111 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<!-- /.row -->
|
<!-- /.row -->
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if
|
|
||||||
checkAccess('view_system_info') or
|
{% if current_user.group %}
|
||||||
hasRole('site-admin')
|
<!-- Group info boxes -->
|
||||||
%}
|
|
||||||
{% set empty_dashboard = false %}
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-6 col-sm-12 col-xs-12">
|
{% if checkAccess('uri_group', {
|
||||||
{{ block("system_info") }}
|
'group': current_user.group
|
||||||
|
}) %}
|
||||||
|
{% set dashboard_is_empty = false %}
|
||||||
|
<div class="col-sm-6 col-xs-12">
|
||||||
|
<div class="info-box">
|
||||||
|
<span class="info-box-icon bg-aqua"><i class="{{current_user.group.icon}}"></i></span>
|
||||||
|
<div class="info-box-content">
|
||||||
|
<h1>{{current_user.group.name}}</h1>
|
||||||
|
</div>
|
||||||
|
<!-- /.info-box-content -->
|
||||||
|
</div>
|
||||||
|
<!-- /.info-box -->
|
||||||
</div>
|
</div>
|
||||||
<!-- /.col -->
|
<!-- /.col -->
|
||||||
|
|
||||||
|
<div class="col-sm-6 col-xs-12">
|
||||||
|
<div class="info-box">
|
||||||
|
<span class="info-box-icon bg-aqua"><i class="fas fa-user fa-fw"></i></span>
|
||||||
|
<div class="info-box-content">
|
||||||
|
<span class="info-box-text">{{ translate("USER", 2) }}</span>
|
||||||
|
<span class="info-box-number">{{current_user.group.users.count}}</span>
|
||||||
|
</div>
|
||||||
|
<!-- /.info-box-content -->
|
||||||
|
</div>
|
||||||
|
<!-- /.info-box -->
|
||||||
|
</div>
|
||||||
|
<!-- /.col -->
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<!-- /.row -->
|
||||||
|
|
||||||
|
<!-- Main panels -->
|
||||||
|
<div class="row">
|
||||||
|
{% if checkAccess('view_group_field', {
|
||||||
|
'group': current_user.group,
|
||||||
|
'property': 'users'
|
||||||
|
}) %}
|
||||||
|
{% set dashboard_is_empty = false %}
|
||||||
|
<div class="col-md-offset-3 col-md-6 col-sm-12 col-xs-12">
|
||||||
|
<div id="widget-group-users" class="box box-primary">
|
||||||
|
<div class="box-header">
|
||||||
|
<h3 class="box-title"><i class="fas fa-fw fa-user"></i> {{translate('GROUP')}} {{translate('USER', 2)}}</h3>
|
||||||
|
{% include "tables/table-tool-menu.html.twig" %}
|
||||||
|
</div>
|
||||||
|
<div class="box-body">
|
||||||
|
{% include "tables/users.html.twig" with {
|
||||||
|
"table" : {
|
||||||
|
"id" : "table-group-users",
|
||||||
|
"columns" : [
|
||||||
|
(checkAccess('view_user_field', { "property" : 'activities' }) ? "last_activity" : "")
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
%}
|
||||||
|
</div>
|
||||||
|
<div class="box-footer">
|
||||||
|
<button type="button" class="btn btn-success js-user-create">
|
||||||
|
<i class="fas fa-plus-square"></i> {{translate("USER.CREATE")}}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<!-- /.row -->
|
||||||
|
<!-- /User's group -->
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
{% if dashboard_is_empty %}
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-4 col-sm-offset-4 col-xs-12">
|
||||||
|
<div class="box box-widget widget-user">
|
||||||
|
<!-- Add the bg color to the header using any of the bg-* classes -->
|
||||||
|
<div class="widget-user-header bg-black-active">
|
||||||
|
<h3 class="widget-user-username">
|
||||||
|
{{translate("WELCOME", {
|
||||||
|
'first_name': current_user.first_name
|
||||||
|
})}}
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
<div class="widget-user-image">
|
||||||
|
<img class="img-circle" src="{{assets.url('assets://userfrosting/images/cupcake.png')}}" alt="User Avatar">
|
||||||
|
</div>
|
||||||
|
<div class="box-footer">
|
||||||
|
<h4>
|
||||||
|
{{translate("WELCOME_TO", {
|
||||||
|
'title': site.title
|
||||||
|
})}}
|
||||||
|
</h4>
|
||||||
|
<p>
|
||||||
|
{{translate("NO_FEATURES_YET")}}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- /.widget-user -->
|
||||||
|
</div>
|
||||||
|
<!-- /.column -->
|
||||||
</div>
|
</div>
|
||||||
<!-- /.row -->
|
<!-- /.row -->
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if empty_dashboard == true %}
|
|
||||||
{{ block("user_welcome") }}
|
|
||||||
{% endif %}
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -21,7 +21,8 @@
|
|||||||
<div class="box-body">
|
<div class="box-body">
|
||||||
{% include "tables/deleted-organisations.html.twig" with {
|
{% include "tables/deleted-organisations.html.twig" with {
|
||||||
"table" : {
|
"table" : {
|
||||||
"id" : "table-organisations"
|
"id" : "table-organisations",
|
||||||
|
"columns" : table.columns
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
%}
|
%}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{% extends "@blockier-templates/pages/abstract/dashboard.html.twig" %}
|
{% extends "pages/abstract/dashboard.html.twig" %}
|
||||||
|
|
||||||
{% block stylesheets_page %}
|
{% block stylesheets_page %}
|
||||||
<!-- Page-specific CSS asset bundle -->
|
<!-- Page-specific CSS asset bundle -->
|
||||||
@@ -16,12 +16,12 @@
|
|||||||
{% block summary %}
|
{% block summary %}
|
||||||
<div id="view-organisation" class="box box-primary">
|
<div id="view-organisation" class="box box-primary">
|
||||||
<div class="box-header with-border">
|
<div class="box-header with-border">
|
||||||
<h3 class="box-title">{{translate('ORGANISATION.SUMMARY')}}</h3>
|
<h2 class="box-title">{{translate('ORGANISATION.SUMMARY')}}</h2>
|
||||||
{% block menu_tools %}
|
{% block menu_tools %}
|
||||||
{% if 'tools' not in tools.hidden %}
|
{% if 'tools' not in tools.hidden %}
|
||||||
<div class="box-tools pull-right">
|
<div class="box-tools pull-right">
|
||||||
<div class="btn-group">
|
<div class="btn-group">
|
||||||
<button type="button" class="btn btn-sm dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
<button type="button" class="btn btn-sm dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" aria-label="Expand organisation tools menu">
|
||||||
<i class="fas fa-cog"></i> <span class="caret"></span>
|
<i class="fas fa-cog"></i> <span class="caret"></span>
|
||||||
</button>
|
</button>
|
||||||
<ul class="dropdown-menu box-tool-menu">
|
<ul class="dropdown-menu box-tool-menu">
|
||||||
@@ -117,7 +117,7 @@
|
|||||||
{% block members %}
|
{% block members %}
|
||||||
<div id="widget-organisation-members" class="box box-primary">
|
<div id="widget-organisation-members" class="box box-primary">
|
||||||
<div class="box-header">
|
<div class="box-header">
|
||||||
<h3 class="box-title"><i class="fas fa-fw fa-user"></i> {{translate('MEMBER', 2)}}</h3>
|
<h2 class="box-title"><i class="fas fa-fw fa-user"></i> {{translate('MEMBER', 2)}}</h2>
|
||||||
{% include "tables/table-tool-menu.html.twig" %}
|
{% include "tables/table-tool-menu.html.twig" %}
|
||||||
</div>
|
</div>
|
||||||
<div class="box-body">
|
<div class="box-body">
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{% extends "@blockier-templates/pages/abstract/dashboard.html.twig" %}
|
{% extends "pages/abstract/dashboard.html.twig" %}
|
||||||
|
|
||||||
{% block stylesheets_page %}
|
{% block stylesheets_page %}
|
||||||
<!-- Page-specific CSS asset bundle -->
|
<!-- Page-specific CSS asset bundle -->
|
||||||
@@ -15,13 +15,14 @@
|
|||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
<div id="widget-organisations" class="box box-primary">
|
<div id="widget-organisations" class="box box-primary">
|
||||||
<div class="box-header">
|
<div class="box-header">
|
||||||
<h3 class="box-title"><i class="fas fa-fw fa-sitemap"></i> {{translate('ORGANISATION', 2)}}</h3>
|
<h2 class="box-title"><i class="fas fa-fw fa-sitemap"></i> {{translate('ORGANISATION', 2)}}</h2>
|
||||||
{% include "tables/table-tool-menu.html.twig" %}
|
{% include "tables/table-tool-menu.html.twig" %}
|
||||||
</div>
|
</div>
|
||||||
<div class="box-body">
|
<div class="box-body">
|
||||||
{% include "tables/organisations.html.twig" with {
|
{% include "tables/organisations.html.twig" with {
|
||||||
"table" : {
|
"table" : {
|
||||||
"id" : "table-organisations"
|
"id" : "table-organisations",
|
||||||
|
"columns" : table.columns
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
%}
|
%}
|
||||||
@@ -31,9 +32,6 @@
|
|||||||
<button type="button" class="btn btn-success js-organisation-create">
|
<button type="button" class="btn btn-success js-organisation-create">
|
||||||
<i class="fas fa-plus-square"></i> {{translate("ORGANISATION.CREATE")}}
|
<i class="fas fa-plus-square"></i> {{translate("ORGANISATION.CREATE")}}
|
||||||
</button>
|
</button>
|
||||||
<button type="button" class="btn btn-danger js-organisation-viewDeleted">
|
|
||||||
<i class="fas fa-minus-square"></i> {{translate("VIEW_DELETED")}}
|
|
||||||
</button>
|
|
||||||
{% elseif checkAccess('register_organisation') %}
|
{% elseif checkAccess('register_organisation') %}
|
||||||
{% if (organisationConfig.membership.single_membership == 0) or ((current_user.organisations.count == 0) and (current_user.pendingOrganisations.count == 0)) %}
|
{% if (organisationConfig.membership.single_membership == 0) or ((current_user.organisations.count == 0) and (current_user.pendingOrganisations.count == 0)) %}
|
||||||
<button type="button" class="btn btn-success js-organisation-register">
|
<button type="button" class="btn btn-success js-organisation-register">
|
||||||
@@ -41,6 +39,11 @@
|
|||||||
</button>
|
</button>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if checkAccess('uri_deleted_organisations') %}
|
||||||
|
<button type="button" class="btn btn-danger js-organisation-viewDeleted">
|
||||||
|
<i class="fas fa-minus-square"></i> {{translate("VIEW_DELETED")}}
|
||||||
|
</button>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
28
templates/pages/partials/settings-organisations.html.twig
Normal file
28
templates/pages/partials/settings-organisations.html.twig
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<div class="box box-primary">
|
||||||
|
<div class="box-header with-border">
|
||||||
|
<h3 class="box-title"><i class="fas fa-sitemap"></i> {{translate('ORGANISATION', 2)}}</h3>
|
||||||
|
</div>
|
||||||
|
<div class="box-body">
|
||||||
|
<p class="box-profile-property">
|
||||||
|
{% for organisation in current_user.organisations %}
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xs-9">
|
||||||
|
<a href="{{site.uri.public}}/organisations/o/{{organisation.slug}}" class="label bg-primary {% if organisation.flag_approved != 1 %}organisation-pending{% endif %} {% if organisation.pivot.flag_admin %}organisation-admin{% endif %}" title="{{organisation.description}}" data-text="{{organisation.name}}" style="font-size: 100%;">{{organisation.name}}</a>
|
||||||
|
|
||||||
|
<small class="user-organisation-description">{{organisation.description}}</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr class="row-divider">
|
||||||
|
{% endfor %}
|
||||||
|
{% for organisation in current_user.pendingOrganisations %}
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xs-9">
|
||||||
|
<a href="{{site.uri.public}}/organisations/o/{{organisation.slug}}" class="label bg-primary {% if organisation.flag_approved != 1 %}organisation-pending{% endif %} {% if organisation.pivot.flag_admin %}organisation-admin{% endif %}" title="{{organisation.description}}" data-text="{{organisation.name}}" style="font-size: 100%;">{{organisation.name}}</a>
|
||||||
|
<small class="user-organisation-description">{{organisation.description}}</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr class="row-divider">
|
||||||
|
{% endfor %}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -1,6 +1,23 @@
|
|||||||
{% extends "@blockier-templates/pages/user.html.twig" %}
|
{% extends "@admin/pages/user.html.twig" %}
|
||||||
|
|
||||||
|
|
||||||
|
{% block body_matter %}
|
||||||
|
{% block group_box %}
|
||||||
|
{% endblock %}
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-4">
|
||||||
|
<div id="view-user">
|
||||||
|
{% block user_box %}
|
||||||
|
<div class="box box-primary">
|
||||||
|
<div class="box-header with-border">
|
||||||
|
<h3 class="box-title">{{translate('USER.SUMMARY')}}</h3>
|
||||||
|
{% if 'tools' not in tools.hidden %}
|
||||||
|
<div class="box-tools pull-right">
|
||||||
|
<div class="btn-group">
|
||||||
|
<button type="button" class="btn btn-sm dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||||
|
<i class="fas fa-cog"></i> <span class="caret"></span>
|
||||||
|
</button>
|
||||||
|
<ul class="dropdown-menu box-tool-menu">
|
||||||
{% block tools %}
|
{% block tools %}
|
||||||
<li>
|
<li>
|
||||||
<a href="#" class="js-user-edit" data-user_name="{{user.user_name}}">
|
<a href="#" class="js-user-edit" data-user_name="{{user.user_name}}">
|
||||||
@@ -58,10 +75,57 @@
|
|||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div class="box-body box-profile">
|
||||||
|
<img class="profile-user-img img-responsive img-circle" src="{{user.avatar}}" alt="{{user.user_name}}">
|
||||||
|
|
||||||
|
<h3 class="profile-username text-center">{{user.full_name}}</h3>
|
||||||
|
<div class="text-center">
|
||||||
|
{% if user.flag_enabled == 0 %}
|
||||||
|
<i class="fas fa-fw fa-minus-circle fa-lg text-red" title="{{translate('DISABLED')}}"></i>
|
||||||
|
{% endif %}
|
||||||
|
{% if user.flag_verified == 0 %}
|
||||||
|
<i class="fas fa-fw fa-bolt fa-lg text-yellow" title="{{translate('UNACTIVATED')}}"></i>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<h4 class="text-muted text-center">{{user.user_name}}{% if 'group' not in fields.hidden and user.group.name is not null %} • {{user.group.name}}{% endif %}</h4>
|
||||||
|
|
||||||
{% block user_box %}
|
{% if 'email' not in fields.hidden %}
|
||||||
{{ parent() }}
|
<hr>
|
||||||
|
<strong><i class="fas fa-envelope margin-r-5"></i> {{translate("EMAIL")}}</strong>
|
||||||
|
<p class="text-muted box-profile-property js-copy-container">
|
||||||
|
<i class="fas fa-copy uf-copy-trigger js-copy-trigger"></i>
|
||||||
|
<span class="js-copy-target">{{user.email}}</span>
|
||||||
|
</p>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if 'locale' not in fields.hidden %}
|
||||||
|
<hr>
|
||||||
|
<strong><i class="fas fa-language margin-r-5"></i> {{translate("LOCALE")}}</strong>
|
||||||
|
<p class="text-muted box-profile-property">
|
||||||
|
{{locales[user.locale]}}
|
||||||
|
</p>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% block user_profile %}{% endblock %}
|
||||||
|
|
||||||
|
{% if 'roles' not in fields.hidden %}
|
||||||
|
<hr>
|
||||||
|
<strong><i class="fas fa-id-card margin-r-5"></i> {{translate("ROLE", 2)}}</strong>
|
||||||
|
<p class="box-profile-property">
|
||||||
|
{% for role in user.roles %}
|
||||||
|
<span class="label label-primary" title="{{role.description}}">{{role.name}}</span>
|
||||||
|
{% endfor %}
|
||||||
|
</p>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
{% block organisations_box %}
|
||||||
<div class="box box-primary">
|
<div class="box box-primary">
|
||||||
<div class="box-header with-border">
|
<div class="box-header with-border">
|
||||||
<h3 class="box-title"><i class="fas fa-sitemap"></i> {{translate('USER.ORGANISATIONS')}}</h3>
|
<h3 class="box-title"><i class="fas fa-sitemap"></i> {{translate('USER.ORGANISATIONS')}}</h3>
|
||||||
@@ -75,7 +139,7 @@
|
|||||||
<br>
|
<br>
|
||||||
<small class="user-organisation-description">{{organisation.description}}</small>
|
<small class="user-organisation-description">{{organisation.description}}</small>
|
||||||
</div>
|
</div>
|
||||||
{% if hasRole('site-admin') or hasRole('organisations-admin') -%}
|
{% if checkAccess('update_user_field', { 'user' : user, 'fields' : ['organisations'] }) or hasRole('organisations-admin') -%}
|
||||||
<div class="col-xs-3" style="margin-top: -5px;">
|
<div class="col-xs-3" style="margin-top: -5px;">
|
||||||
<button type="button" data-slug="{{organisation.slug}}" data-user_name="{{user.user_name}}" class="btn btn-danger js-member-remove margin-r-5" style="min-width: 70px">{{translate("REMOVE")}}</button>
|
<button type="button" data-slug="{{organisation.slug}}" data-user_name="{{user.user_name}}" class="btn btn-danger js-member-remove margin-r-5" style="min-width: 70px">{{translate("REMOVE")}}</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -90,7 +154,7 @@
|
|||||||
<br>
|
<br>
|
||||||
<small class="user-organisation-description">{{organisation.description}}</small>
|
<small class="user-organisation-description">{{organisation.description}}</small>
|
||||||
</div>
|
</div>
|
||||||
{% if hasRole('site-admin') or hasRole('organisations-admin') -%}
|
{% if checkAccess('update_user_field', { 'user' : user, 'fields' : ['organisations'] }) or hasRole('organisations-admin') -%}
|
||||||
<div class="col-xs-3" style="margin-top: -5px;">
|
<div class="col-xs-3" style="margin-top: -5px;">
|
||||||
<button type="button" data-slug="{{organisation.slug}}" data-user_name="{{user.user_name}}" class="btn btn-danger js-member-remove margin-r-5" style="min-width: 70px">{{translate("REMOVE")}}</button>
|
<button type="button" data-slug="{{organisation.slug}}" data-user_name="{{user.user_name}}" class="btn btn-danger js-member-remove margin-r-5" style="min-width: 70px">{{translate("REMOVE")}}</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -102,3 +166,50 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% if checkAccess('view_user_field', { 'user': user, 'property': 'activities' }) %}
|
||||||
|
{% if 'activities' not in widgets.hidden %}
|
||||||
|
<div class="col-lg-8">
|
||||||
|
{% block activity_box %}
|
||||||
|
<div id="widget-user-activities" class="box box-primary">
|
||||||
|
<div class="box-header">
|
||||||
|
<h3 class="box-title"><i class="fas fa-fw fa-tasks"></i> {{translate('ACTIVITY', 2)}}</h3>
|
||||||
|
{% include "tables/table-tool-menu.html.twig" %}
|
||||||
|
</div>
|
||||||
|
<div class="box-body">
|
||||||
|
{% include "tables/activities.html.twig" with {
|
||||||
|
"table" : {
|
||||||
|
"id" : "table-user-activities"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
%}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% if 'permissions' not in widgets.hidden %}
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<div id="widget-permissions" class="box box-primary">
|
||||||
|
<div class="box-header">
|
||||||
|
<h3 class="box-title pull-left"><i class="fas fa-key fa-fw"></i> {{translate('PERMISSION', 2)}}</h3>
|
||||||
|
{% include "tables/table-tool-menu.html.twig" %}
|
||||||
|
</div>
|
||||||
|
<div class="box-body">
|
||||||
|
{% include "tables/permissions.html.twig" with {
|
||||||
|
"table" : {
|
||||||
|
"id" : "table-permissions",
|
||||||
|
"columns" : ["via_roles"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
%}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
{% block table_cell_template_actions %}
|
|
||||||
<script id="{{table.id}}-column-actions" type="text/x-handlebars-template">
|
<script id="{{table.id}}-column-actions" type="text/x-handlebars-template">
|
||||||
{%- verbatim %}
|
{% verbatim %}
|
||||||
<td>
|
<td>
|
||||||
<div class="btn-group">
|
<div class="btn-group">
|
||||||
<button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown">
|
<button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown">
|
||||||
@@ -21,6 +20,5 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
{% endverbatim -%}
|
{% endverbatim %}
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
|
||||||
@@ -1,11 +1,9 @@
|
|||||||
{% block table_cell_template_info %}
|
|
||||||
<script id="{{table.id}}-column-info" type="text/x-handlebars-template">
|
<script id="{{table.id}}-column-info" type="text/x-handlebars-template">
|
||||||
{%- verbatim %}
|
{% verbatim %}
|
||||||
<td data-text="{{row.name}}">
|
<td data-text="{{row.name}}">
|
||||||
<strong>
|
<strong>
|
||||||
<a href="{{site.uri.public}}/organisations/o/{{row.slug}}">{{row.name}}</a>
|
<a href="{{site.uri.public}}/organisations/o/{{row.slug}}">{{row.name}}</a>
|
||||||
</strong>
|
</strong>
|
||||||
</td>
|
</td>
|
||||||
{% endverbatim -%}
|
{% endverbatim %}
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
<script id="{{table.id}}-column-actions" type="text/x-handlebars-template">
|
||||||
|
{% if checkAccess('update_organisation_field', { 'organisation': organisation, 'fields': [ 'members' ] }) or isOrganisationAdmin(organisation) %}
|
||||||
|
{% verbatim %}
|
||||||
|
<td class="uf-table-fit-width">
|
||||||
|
<div class="btn-group">
|
||||||
|
<button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-label="{% endverbatim %}{{translate("ACTIONS_FOR")}}{% verbatim %} {{row.full_name}} ({{row.user_name}})">{% endverbatim %}{{translate("ACTIONS")}}{% verbatim %}<span class="caret"></span></button>
|
||||||
|
<ul class="dropdown-menu dropdown-menu-right-responsive" role="menu">
|
||||||
|
{{#ifx row.membership_approved '!=' 1 }}
|
||||||
|
<li role="menuitem">
|
||||||
|
<a href="#" data-slug="{% endverbatim %}{{organisation.slug}}{% verbatim %}" data-user_name="{{row.user_name}}" class="js-member-accept" aria-label="{% endverbatim %}{{translate("ORGANISATION.JOIN_REQUEST.ACCEPT")}}{% verbatim %} {{row.full_name}} ({{row.user_name}})">
|
||||||
|
<i class="fas fa-thumbs-up"></i> {% endverbatim %}{{translate("ORGANISATION.JOIN_REQUEST.ACCEPT")}}{% verbatim %}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li role="menuitem">
|
||||||
|
<a href="#" data-slug="{% endverbatim %}{{organisation.slug}}{% verbatim %}" data-user_name="{{row.user_name}}" class="js-member-reject" aria-label="{% endverbatim %}{{translate("ORGANISATION.JOIN_REQUEST.REJECT")}}{% verbatim %} {{row.full_name}} ({{row.user_name}})">
|
||||||
|
<i class="fas fa-thumbs-down"></i> {% endverbatim %}{{translate("ORGANISATION.JOIN_REQUEST.REJECT")}}{% verbatim %}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{{ else }}
|
||||||
|
{{#ifx row.organisation_admin '==' 1 }}
|
||||||
|
<li role="menuitem">
|
||||||
|
<a href="#" data-slug="{% endverbatim %}{{organisation.slug}}{% verbatim %}" data-user_name="{{row.user_name}}" class="js-member-demote" aria-label="{% endverbatim %}{{translate("MEMBER.DEMOTE")}}{% verbatim %}: {{row.full_name}} ({{row.user_name}})">
|
||||||
|
<i class="fas fa-angle-double-down"></i> {% endverbatim %}{{translate("MEMBER.DEMOTE")}}{% verbatim %}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{{ else }}
|
||||||
|
<li role="menuitem">
|
||||||
|
<a href="#" data-slug="{% endverbatim %}{{organisation.slug}}{% verbatim %}" data-user_name="{{row.user_name}}" class="js-member-promote" aria-label="{% endverbatim %}{{translate("MEMBER.PROMOTE")}}{% verbatim %}: {{row.full_name}} ({{row.user_name}})">
|
||||||
|
<i class="fas fa-angle-double-up"></i> {% endverbatim %}{{translate("MEMBER.PROMOTE")}}{% verbatim %}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{{/ifx}}
|
||||||
|
<li role="menuitem">
|
||||||
|
<a href="#" data-slug="{% endverbatim %}{{organisation.slug}}{% verbatim %}" data-user_name="{{row.user_name}}" class="js-user-edit" aria-label="{% endverbatim %}{{translate("MEMBER.EDIT")}}{% verbatim %}: {{row.full_name}} ({{row.user_name}})">
|
||||||
|
<i class="fas fa-edit"></i> {% endverbatim %}{{translate("MEMBER.EDIT")}}{% verbatim %}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li role="menuitem">
|
||||||
|
<a href="#" data-slug="{% endverbatim %}{{organisation.slug}}{% verbatim %}" data-user_name="{{row.user_name}}" class="js-member-password" aria-label="{% endverbatim %}{{translate("MEMBER.RESET_PASSWORD")}}{% verbatim %}: {{row.full_name}} ({{row.user_name}})">
|
||||||
|
<i class="fas fa-key"></i> {% endverbatim %}{{translate("MEMBER.RESET_PASSWORD")}}{% verbatim %}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li role="menuitem">
|
||||||
|
<a href="#" data-slug="{% endverbatim %}{{organisation.slug}}{% verbatim %}" data-user_name="{{row.user_name}}" class="js-member-remove" aria-label="{% endverbatim %}{{translate("MEMBER.REMOVE")}}{% verbatim %}: {{row.full_name}} ({{row.user_name}})">
|
||||||
|
<i class="fas fa-door-open"></i> {% endverbatim %}{{translate("MEMBER.REMOVE")}}{% verbatim %}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{{/ifx}}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
{% endverbatim %}
|
||||||
|
{% endif %}
|
||||||
|
</script>
|
||||||
@@ -1,19 +1,19 @@
|
|||||||
{% block table_cell_template_info %}
|
|
||||||
<script id="{{table.id}}-column-info" type="text/x-handlebars-template">
|
<script id="{{table.id}}-column-info" type="text/x-handlebars-template">
|
||||||
{%- verbatim %}
|
{% verbatim %}
|
||||||
<td data-text="{{row.last_name}}">
|
<td data-text="{{row.last_name}}">
|
||||||
<strong>
|
<strong>
|
||||||
{% endverbatim -%}{% if isOrganisationAdmin(organisation) %}{%- verbatim %}
|
{% endverbatim -%}{% if isOrganisationAdmin(organisation) %}{%- verbatim %}
|
||||||
<a href="{{site.uri.public}}/users/u/{{row.user_name}}">{{row.first_name}} {{row.last_name}} ({{row.user_name}})</a>
|
<a href="{{site.uri.public}}/users/u/{{row.user_name}}">{{row.first_name}} {{row.last_name}} ({{row.user_name}})</a>
|
||||||
|
{% endverbatim -%}{% elseif checkAccess('uri_user') %}{%- verbatim %}
|
||||||
|
<a href="{{site.uri.public}}/users/u/{{row.user_name}}">{{row.first_name}} {{row.last_name}} ({{row.user_name}})</a>
|
||||||
{% endverbatim -%}{% else %}{%- verbatim %}
|
{% endverbatim -%}{% else %}{%- verbatim %}
|
||||||
{{row.first_name}} {{row.last_name}} ({{row.user_name}})
|
{{row.first_name}} {{row.last_name}} ({{row.user_name}})
|
||||||
{% endverbatim -%}{% endif %}{%- verbatim %}
|
{% endverbatim -%}{% endif %}{%- verbatim %}
|
||||||
</strong>
|
</strong>
|
||||||
<div class="js-copy-container">
|
<div class="js-copy-container">
|
||||||
<span class="js-copy-target">{{row.email}}</span>
|
<span class="js-copy-target">{{row.email}}</span>
|
||||||
<button class="btn btn-xs uf-copy-trigger js-copy-trigger"><i class="fas fa-copy"></i></button>
|
<button class="btn btn-xs uf-copy-trigger js-copy-trigger" aria-label="Copy email address"><i class="fas fa-copy"></i></button>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
{% endverbatim -%}
|
{% endverbatim %}
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
{% block table_cell_template_status %}
|
|
||||||
<script id="{{table.id}}-column-status" type="text/x-handlebars-template">
|
<script id="{{table.id}}-column-status" type="text/x-handlebars-template">
|
||||||
{%- verbatim %}
|
{% verbatim %}
|
||||||
<td
|
<td
|
||||||
{{#ifx row.membership_approved '==' 0 }}
|
{{#ifx row.membership_approved '==' 0 }}
|
||||||
data-text="pending"
|
data-text="pending"
|
||||||
@@ -15,6 +14,5 @@
|
|||||||
{{#ifx row.organisation_admin '==' 1 }}<span class="text-secondary">({% endverbatim %}{{translate("ADMIN")}}{% verbatim %})</span>{{/ifx}}
|
{{#ifx row.organisation_admin '==' 1 }}<span class="text-secondary">({% endverbatim %}{{translate("ADMIN")}}{% verbatim %})</span>{{/ifx}}
|
||||||
{{/ifx }}
|
{{/ifx }}
|
||||||
</td>
|
</td>
|
||||||
{% endverbatim -%}
|
{% endverbatim %}
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
|
||||||
134
templates/tables/columns/organisations-actions.html.twig
Normal file
134
templates/tables/columns/organisations-actions.html.twig
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
<script id="{{table.id}}-column-actions" type="text/x-handlebars-template">
|
||||||
|
{% if 'actions' in table.columns %}
|
||||||
|
<td>
|
||||||
|
{% if not organisationConfig.combine_action_buttons %}
|
||||||
|
{% if not (checkAccess('delete_organisation') or checkAccess('approve_organisation') or checkAccess('merge_organisations')) %}
|
||||||
|
{% verbatim %}{{#ifx row.is_admin '==' 1 }}{% endverbatim %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<div class="btn-group">
|
||||||
|
<button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown">
|
||||||
|
{{translate("ACTIONS")}}
|
||||||
|
<span class="caret"></span>
|
||||||
|
</button>
|
||||||
|
<ul class="dropdown-menu dropdown-menu-right" role="menu">
|
||||||
|
|
||||||
|
{% block organisation_membership_actions %}
|
||||||
|
{% if organisationConfig.combine_action_buttons %}
|
||||||
|
{% verbatim %}{{#ifx row.is_pending '==' 1 }}{% endverbatim %}
|
||||||
|
<li role="menuitem">
|
||||||
|
<a href="#" data-slug="{% verbatim %}{{row.slug}}{% endverbatim %}" class="js-organisation-cancelJoin">
|
||||||
|
<i class="fas fa-window-close"></i>
|
||||||
|
{{translate("JOIN.CANCEL")}}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{% verbatim %}{{ else }}{% endverbatim %}
|
||||||
|
{% verbatim %}{{#ifx row.is_member '==' 1 }}{% endverbatim %}
|
||||||
|
<li role="menuitem">
|
||||||
|
<a href="#" data-slug="{% verbatim %}{{row.slug}}{% endverbatim %}" class="js-organisation-leave">
|
||||||
|
<i class="fas fa-sign-out-alt"></i>
|
||||||
|
{{translate("LEAVE")}}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{% verbatim %}{{ else }}{% endverbatim %}
|
||||||
|
{% if (organisationConfig.membership.single_membership == 0) or ((current_user.organisations.count == 0) and (current_user.pendingOrganisations.count == 0)) %}
|
||||||
|
<li role="menuitem">
|
||||||
|
<a href="#" data-slug="{% verbatim %}{{row.slug}}{% endverbatim %}" class="js-organisation-join">
|
||||||
|
<i class="fas fa-sign-in-alt"></i>
|
||||||
|
{{translate("JOIN")}}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
{% verbatim %}{{/ifx}}{% endverbatim %}
|
||||||
|
{% verbatim %}{{/ifx}}{% endverbatim %}
|
||||||
|
|
||||||
|
{% if checkAccess('merge_organisations') or checkAccess('approve_organisation') or checkAccess('delete_organisation') %}
|
||||||
|
<li class="divider"></li>
|
||||||
|
{% else %}
|
||||||
|
{% if organisationConfig.combine_action_buttons %}
|
||||||
|
{% if not (checkAccess('delete_organisation') or checkAccess('approve_organisation') or checkAccess('merge_organisations')) %}
|
||||||
|
{% verbatim %}{{#ifx row.is_admin '==' 1 }}<li class="divider"></li>{{/ifx}}{% endverbatim %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
|
||||||
|
{% block organisation_administration_actions %}
|
||||||
|
{% if organisationConfig.combine_action_buttons %}
|
||||||
|
{% if not (checkAccess('delete_organisation') or checkAccess('approve_organisation') or checkAccess('merge_organisations')) %}
|
||||||
|
{% verbatim %}{{#ifx row.is_admin '==' 1 }}{% endverbatim %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
<li role="menuitem">
|
||||||
|
<a href="#" data-slug="{% verbatim %}{{row.slug}}{% endverbatim %}" class="js-organisation-edit">
|
||||||
|
<i class="fas fa-edit"></i>
|
||||||
|
{{translate("ORGANISATION.EDIT")}}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{% if organisationConfig.combine_action_buttons %}
|
||||||
|
{% if not (checkAccess('delete_organisation') or checkAccess('approve_organisation') or checkAccess('merge_organisations')) %}
|
||||||
|
{% verbatim %}{{/ifx }}{% endverbatim %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if checkAccess('approve_organisation') %}
|
||||||
|
{% verbatim %}{{#ifx row.flag_approved '==' 0 }}{% endverbatim %}
|
||||||
|
{% verbatim %}{{#ifx row.registrant_id '==' {% endverbatim %}{{current_user.id}}{% verbatim %} }}{% endverbatim %}
|
||||||
|
<li role="menuitem">
|
||||||
|
<a href="#" data-slug="{% verbatim %}{{row.slug}}{% endverbatim %}" class="js-organisation-cancelRegistration">
|
||||||
|
<i class="fas fa-trash-alt"></i>
|
||||||
|
{{translate("ORGANISATION.REGISTRATION.CANCEL")}}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{% verbatim %}{{/ifx}}{% endverbatim %}
|
||||||
|
|
||||||
|
<li role="menuitem">
|
||||||
|
<a href="#" data-slug="{% verbatim %}{{row.slug}}{% endverbatim %}" class="js-organisation-approveRegistration">
|
||||||
|
<i class="fas fa-thumbs-up"></i> {{translate("ORGANISATION.REGISTRATION.APPROVE")}}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li role="menuitem">
|
||||||
|
<a href="#" data-slug="{% verbatim %}{{row.slug}}{% endverbatim %}" class="js-organisation-denyRegistration">
|
||||||
|
<i class="fas fa-thumbs-down"></i>
|
||||||
|
{{translate("ORGANISATION.REGISTRATION.DENY")}}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{% verbatim %}{{/ifx}}{% endverbatim %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
{% if checkAccess('merge_organisations') %}
|
||||||
|
<li role="menuitem">
|
||||||
|
<a href="#" data-slug="{% verbatim %}{{row.slug}}{% endverbatim %}" class="js-organisation-merge">
|
||||||
|
<i class="fas fa-object-group"></i>
|
||||||
|
{{translate("ORGANISATION.MERGE")}}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if checkAccess('delete_organisation') %}
|
||||||
|
{% verbatim %}{{#ifx row.flag_approved '==' 1 }}{% endverbatim %}
|
||||||
|
<li role="menuitem">
|
||||||
|
<a href="#" data-slug="{% verbatim %}{{row.slug}}{% endverbatim %}" class="js-organisation-delete">
|
||||||
|
<i class="fas fa-trash-alt"></i>
|
||||||
|
{{translate("ORGANISATION.DELETE")}}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{% verbatim %}{{/ifx }}{% endverbatim %}
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% if not organisationConfig.combine_action_buttons %}
|
||||||
|
{% if not (checkAccess('delete_organisation') or checkAccess('approve_organisation') or checkAccess('merge_organisations')) %}
|
||||||
|
{% verbatim %}{{/ifx}}{% endverbatim %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
{% endif %}
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
<script id="{{table.id}}-column-adminCount" type="text/x-handlebars-template">
|
||||||
|
{% if checkAccess('view_organisation_field', { 'property' : 'members' }) %}
|
||||||
|
{% verbatim %}
|
||||||
|
<td>
|
||||||
|
{{row.admin_count}}
|
||||||
|
</td>
|
||||||
|
{% endverbatim %}
|
||||||
|
{% endif %}
|
||||||
|
</script>
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{% include "@uf-tweaks/tables/columns/abstract/description.html.twig" %}
|
||||||
17
templates/tables/columns/organisations-info.html.twig
Normal file
17
templates/tables/columns/organisations-info.html.twig
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<script id="{{table.id}}-column-info" type="text/x-handlebars-template">
|
||||||
|
{% verbatim %}
|
||||||
|
<td data-text="{{row.name}}">
|
||||||
|
<strong>
|
||||||
|
{{#ifx row.is_member '==' 1 }}
|
||||||
|
<a href="{{site.uri.public}}/organisations/o/{{row.slug}}">{{row.name}}</a>
|
||||||
|
{{ else }}
|
||||||
|
{% endverbatim %}{% if checkAccess('uri_organisation') %}{% verbatim %}
|
||||||
|
<a href="{{site.uri.public}}/organisations/o/{{row.slug}}">{{row.name}}</a>
|
||||||
|
{% endverbatim %}{% else %}{% verbatim %}
|
||||||
|
{{row.name}}
|
||||||
|
{% endverbatim %}{% endif %}{% verbatim %}
|
||||||
|
{{/ifx }}
|
||||||
|
</strong>
|
||||||
|
</td>
|
||||||
|
{% endverbatim %}
|
||||||
|
</script>
|
||||||
29
templates/tables/columns/organisations-join.html.twig
Normal file
29
templates/tables/columns/organisations-join.html.twig
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
<script id="{{table.id}}-column-join" type="text/x-handlebars-template">
|
||||||
|
{% if not organisationConfig.combine_action_buttons %}
|
||||||
|
{% if 'join' in table.columns %}
|
||||||
|
{% verbatim %}
|
||||||
|
<td>
|
||||||
|
<div class="btn-group">
|
||||||
|
{{#ifx row.is_pending '==' 1 }}
|
||||||
|
<button type="button" data-slug="{{row.slug}}" class="btn btn-danger js-organisation-cancelJoin" style="min-width: 70px">
|
||||||
|
{% endverbatim %}{{translate("CANCEL")}}{% verbatim %}
|
||||||
|
</button>
|
||||||
|
{{ else }}
|
||||||
|
{{#ifx row.is_member '==' 1 }}
|
||||||
|
<button type="button" data-slug="{{row.slug}}" class="btn btn-danger js-organisation-leave" style="min-width: 70px" title="{% endverbatim %}{{translate("LEAVE")}}{% verbatim %} {{row.name}}" aria-label="{% endverbatim %}{{translate("LEAVE")}}{% verbatim %} {{row.name}}">
|
||||||
|
{% endverbatim %}{{translate("LEAVE")}}{% verbatim %}
|
||||||
|
</button>
|
||||||
|
{{ else }}
|
||||||
|
{% endverbatim %}{% if (organisationConfig.membership.single_membership == 0) or ((current_user.organisations.count == 0) and (current_user.pendingOrganisations.count == 0)) %}{% verbatim %}
|
||||||
|
<button type="button" data-slug="{{row.slug}}" class="btn btn-success js-organisation-join" style="min-width: 70px" title="{% endverbatim %}{{translate("JOIN")}}{% verbatim %} {{row.name}}" aria-label="{% endverbatim %}{{translate("JOIN")}}{% verbatim %} {{row.name}}">
|
||||||
|
{% endverbatim %}{{translate("JOIN")}}{% verbatim %}
|
||||||
|
</button>
|
||||||
|
{% endverbatim %}{% endif %}{% verbatim %}
|
||||||
|
{{/ifx}}
|
||||||
|
{{/ifx}}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
{% endverbatim %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
<script id="{{table.id}}-column-memberCount" type="text/x-handlebars-template">
|
||||||
|
{% if checkAccess('view_organisation_field', { 'property' : 'members' }) %}
|
||||||
|
{% verbatim %}
|
||||||
|
<td>
|
||||||
|
{{row.member_count}}
|
||||||
|
</td>
|
||||||
|
{% endverbatim %}
|
||||||
|
{% endif %}
|
||||||
|
</script>
|
||||||
25
templates/tables/columns/organisations-status.html.twig
Normal file
25
templates/tables/columns/organisations-status.html.twig
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<script id="{{table.id}}-column-status" type="text/x-handlebars-template">
|
||||||
|
{% if 'status' in table.columns %}
|
||||||
|
{% verbatim %}
|
||||||
|
<td
|
||||||
|
{{#ifx row.flag_approved '==' 1 }}
|
||||||
|
data-text="approved"
|
||||||
|
{{ else }}
|
||||||
|
data-text="pending"
|
||||||
|
{{/ifx }}
|
||||||
|
>
|
||||||
|
{% endverbatim %}{# {{# ifx row.flag_admin '==' 1 }} #}{% verbatim %}
|
||||||
|
{{#ifx row.flag_approved '==' 1 }}
|
||||||
|
<span>
|
||||||
|
{% endverbatim %}{{translate("APPROVED")}}{% verbatim %}
|
||||||
|
</span>
|
||||||
|
{{ else }}
|
||||||
|
<span class="text-yellow">
|
||||||
|
{% endverbatim %}{{translate("PENDING")}}{% verbatim %}
|
||||||
|
</span>
|
||||||
|
{{/ifx }}
|
||||||
|
{% endverbatim %}{# {{/ifx }} #}{% verbatim %}
|
||||||
|
</td>
|
||||||
|
{% endverbatim %}
|
||||||
|
{% endif %}
|
||||||
|
</script>
|
||||||
@@ -1,38 +1,37 @@
|
|||||||
{% block table_cell_template_actions %}
|
|
||||||
<script id="{{table.id}}-column-actions" type="text/x-handlebars-template">
|
<script id="{{table.id}}-column-actions" type="text/x-handlebars-template">
|
||||||
{%- verbatim %}
|
{% verbatim %}
|
||||||
<td class="uf-table-fit-width">
|
<td class="uf-table-fit-width">
|
||||||
<div class="btn-group">
|
<div class="btn-group">
|
||||||
<button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown">{% endverbatim %}{{translate("ACTIONS")}}{% verbatim %}<span class="caret"></span></button>
|
<button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown">{% endverbatim %}{{translate("ACTIONS")}}{% verbatim %}<span class="caret"></span></button>
|
||||||
<ul class="dropdown-menu dropdown-menu-right-responsive" role="menu">
|
<ul class="dropdown-menu dropdown-menu-right-responsive" role="menu">
|
||||||
{{#ifx row.flag_verified '==' 0 }}
|
{{#ifx row.flag_verified '==' 0 }}
|
||||||
<li>
|
<li role="menuitem">
|
||||||
<a href="#" data-user_name="{{row.user_name}}" class="js-user-activate">
|
<a href="#" data-user_name="{{row.user_name}}" class="js-user-activate">
|
||||||
<i class="fas fa-bolt"></i> {% endverbatim %}{{translate("USER.ACTIVATE")}}{% verbatim %}
|
<i class="fas fa-bolt"></i> {% endverbatim %}{{translate("USER.ACTIVATE")}}{% verbatim %}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{{/ifx }}
|
{{/ifx }}
|
||||||
<li>
|
<li role="menuitem">
|
||||||
<a href="#" data-user_name="{{row.user_name}}" class="js-user-edit">
|
<a href="#" data-user_name="{{row.user_name}}" class="js-user-edit">
|
||||||
<i class="fas fa-edit"></i> {% endverbatim %}{{translate("USER.EDIT")}}{% verbatim %}
|
<i class="fas fa-edit"></i> {% endverbatim %}{{translate("USER.EDIT")}}{% verbatim %}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li role="menuitem">
|
||||||
<a href="#" data-user_name="{{row.user_name}}" class="js-user-roles">
|
<a href="#" data-user_name="{{row.user_name}}" class="js-user-roles">
|
||||||
<i class="fas fa-id-card"></i> {% endverbatim %}{{translate("ROLE.MANAGE")}}{% verbatim %}
|
<i class="fas fa-id-card"></i> {% endverbatim %}{{translate("ROLE.MANAGE")}}{% verbatim %}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li role="menuitem">
|
||||||
<a href="#" data-user_name="{{row.user_name}}" class="js-user-organisations">
|
<a href="#" data-user_name="{{row.user_name}}" class="js-user-organisations">
|
||||||
<i class="fas fa-sitemap"></i> {% endverbatim %}{{translate("ORGANISATION.MANAGE")}}{% verbatim %}
|
<i class="fas fa-sitemap"></i> {% endverbatim %}{{translate("ORGANISATION.MANAGE")}}{% verbatim %}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li role="menuitem">
|
||||||
<a href="#" data-user_name="{{row.user_name}}" class="js-user-password">
|
<a href="#" data-user_name="{{row.user_name}}" class="js-user-password">
|
||||||
<i class="fas fa-key"></i> {% endverbatim %}{{translate("USER.ADMIN.CHANGE_PASSWORD")}}{% verbatim %}
|
<i class="fas fa-key"></i> {% endverbatim %}{{translate("USER.ADMIN.CHANGE_PASSWORD")}}{% verbatim %}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li role="menuitem">
|
||||||
{{#ifx row.flag_enabled '==' 1 }}
|
{{#ifx row.flag_enabled '==' 1 }}
|
||||||
<a href="#" data-user_name="{{row.user_name}}" class="js-user-disable">
|
<a href="#" data-user_name="{{row.user_name}}" class="js-user-disable">
|
||||||
<i class="fas fa-minus-circle"></i> {% endverbatim %}{{translate("USER.DISABLE")}}{% verbatim %}
|
<i class="fas fa-minus-circle"></i> {% endverbatim %}{{translate("USER.DISABLE")}}{% verbatim %}
|
||||||
@@ -43,7 +42,7 @@
|
|||||||
</a>
|
</a>
|
||||||
{{/ifx }}
|
{{/ifx }}
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li role="menuitem">
|
||||||
<a href="#" data-user_name="{{row.user_name}}" class="js-user-delete">
|
<a href="#" data-user_name="{{row.user_name}}" class="js-user-delete">
|
||||||
<i class="fas fa-trash-alt"></i> {% endverbatim %}{{translate("USER.DELETE")}}{% verbatim %}
|
<i class="fas fa-trash-alt"></i> {% endverbatim %}{{translate("USER.DELETE")}}{% verbatim %}
|
||||||
</a>
|
</a>
|
||||||
@@ -51,6 +50,5 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
{% endverbatim -%}
|
{% endverbatim %}
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
|
||||||
16
templates/tables/columns/users-organisations.html.twig
Normal file
16
templates/tables/columns/users-organisations.html.twig
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<script id="{{table.id}}-column-organisations" type="text/x-handlebars-template">
|
||||||
|
{% verbatim %}
|
||||||
|
<td style="line-height: 2em;">
|
||||||
|
{{#if row.organisations.length }}
|
||||||
|
{{#each row.organisations }}
|
||||||
|
<a href="{% endverbatim %}{{site.uri.public}}{% verbatim %}/organisations/o/{{this.slug}}" class="label bg-primary user-organisation-button {{#ifx this.flag_approved '!=' 1 }}organisation-pending{{/ifx}} {{#if this.pivot.flag_admin }}organisation-admin{{/if}}" title="{{this.description}}" data-text="{{this.name}}">{{this.name}}</a><br>
|
||||||
|
{{/each}}
|
||||||
|
{{/if }}
|
||||||
|
{{#if row.pending_organisations.length }}
|
||||||
|
{{#each row.pending_organisations }}
|
||||||
|
<a href="{% endverbatim %}{{site.uri.public}}{% verbatim %}/organisations/o/{{this.slug}}" class="label bg-primary user-organisation-button {{#ifx this.flag_approved '!=' 1 }}organisation-pending{{/ifx}} {{#if this.pivot.flag_admin }}organisation-admin{{/if}} membership-pending" title="{{this.description}}" data-text="{{this.name}}">{{this.name}}</a><br>
|
||||||
|
{{/each}}
|
||||||
|
{{/if }}
|
||||||
|
</td>
|
||||||
|
{% endverbatim %}
|
||||||
|
</script>
|
||||||
@@ -1,8 +1,5 @@
|
|||||||
{% extends "tables/organisations.html.twig" %}
|
{% extends "tables/organisations.html.twig" %}
|
||||||
|
|
||||||
{% use 'tables/partials/deleted-organisations/column-info.html.twig' %}
|
|
||||||
{% use 'tables/partials/deleted-organisations/column-actions.html.twig' %}
|
|
||||||
|
|
||||||
{% block table %}
|
{% block table %}
|
||||||
<table id="{{table.id}}" class="tablesorter table table-bordered table-hover table-striped" data-sortlist="{{table.sortlist}}">
|
<table id="{{table.id}}" class="tablesorter table table-bordered table-hover table-striped" data-sortlist="{{table.sortlist}}">
|
||||||
<thead>
|
<thead>
|
||||||
@@ -20,4 +17,12 @@
|
|||||||
</table>
|
</table>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block table_cell_template_join %}{% endblock %}
|
{% block table_organisations_column_info %}
|
||||||
|
{% include 'tables/columns/deleted_organisations-info.html.twig' %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block table_organisations_column_actions %}
|
||||||
|
{% include 'tables/columns/deleted_organisations-actions.html.twig' %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block table_organisations_column_join %}{% endblock %}
|
||||||
@@ -1,9 +1,5 @@
|
|||||||
{% extends "tables/users.html.twig" %}
|
{% extends "tables/users.html.twig" %}
|
||||||
|
|
||||||
{% use 'tables/partials/organisation-members/column-info.html.twig' %}
|
|
||||||
{% use 'tables/partials/organisation-members/column-status.html.twig' %}
|
|
||||||
{% use 'tables/partials/organisation-members/column-actions.html.twig' %}
|
|
||||||
|
|
||||||
{% block table %}
|
{% block table %}
|
||||||
<table id="{{table.id}}" class="tablesorter table table-bordered table-hover table-striped" data-sortlist="{{table.sortlist}}">
|
<table id="{{table.id}}" class="tablesorter table table-bordered table-hover table-striped" data-sortlist="{{table.sortlist}}">
|
||||||
<thead>
|
<thead>
|
||||||
@@ -11,7 +7,7 @@
|
|||||||
<th class="sorter-metatext" data-column-name="name" data-column-template="#{{table.id}}-column-info" data-priority="1">{{translate('USER')}} <i class="fas fa-sort"></i></th>
|
<th class="sorter-metatext" data-column-name="name" data-column-template="#{{table.id}}-column-info" data-priority="1">{{translate('USER')}} <i class="fas fa-sort"></i></th>
|
||||||
<th class="filter-metatext" data-column-name="organisations" data-sorter="false" data-column-template="#{{table.id}}-column-organisations" data-priority="2">{{translate("ORGANISATION", 2)}}</th>
|
<th class="filter-metatext" data-column-name="organisations" data-sorter="false" data-column-template="#{{table.id}}-column-organisations" data-priority="2">{{translate("ORGANISATION", 2)}}</th>
|
||||||
{% if 'last_activity' in table.columns %}
|
{% if 'last_activity' in table.columns %}
|
||||||
<th class="sorter-metanum" data-column-name="last_activity" data-column-template="#{{table.id}}-column-last-activity" data-priority="3">{{translate("ACTIVITY.LAST")}} <i class="fas fa-sort"></i></th>
|
<th class="sorter-metanum" data-column-name="last_activity" data-column-template="#{{table.id}}-column-lastActivity" data-priority="3">{{translate("ACTIVITY.LAST")}} <i class="fas fa-sort"></i></th>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<th class="filter-select filter-metatext" data-column-name="status" data-column-template="#{{table.id}}-column-status" data-priority="2">{{translate("STATUS")}} <i class="fas fa-sort"></i></th>
|
<th class="filter-select filter-metatext" data-column-name="status" data-column-template="#{{table.id}}-column-status" data-priority="2">{{translate("STATUS")}} <i class="fas fa-sort"></i></th>
|
||||||
{% if checkAccess('update_organisation_field', { 'organisation': organisation, 'fields': [ 'members' ] }) or isOrganisationAdmin(organisation) %}
|
{% if checkAccess('update_organisation_field', { 'organisation': organisation, 'fields': [ 'members' ] }) or isOrganisationAdmin(organisation) %}
|
||||||
@@ -23,3 +19,15 @@
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block table_users_column_info %}
|
||||||
|
{% include 'tables/columns/organisation_members-info.html.twig' %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block table_users_column_status %}
|
||||||
|
{% include 'tables/columns/organisation_members-status.html.twig' %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block table_users_column_actions %}
|
||||||
|
{% include 'tables/columns/organisation_members-actions.html.twig' %}
|
||||||
|
{% endblock %}
|
||||||
@@ -7,36 +7,28 @@
|
|||||||
|
|
||||||
{% extends "tables/table-paginated.html.twig" %}
|
{% extends "tables/table-paginated.html.twig" %}
|
||||||
|
|
||||||
{% use 'tables/partials/organisations/column-info.html.twig' %}
|
|
||||||
{% use 'tables/partials/organisations/column-description.html.twig' %}
|
|
||||||
{% use 'tables/partials/organisations/column-status.html.twig' %}
|
|
||||||
{% use 'tables/partials/organisations/column-member_count.html.twig' %}
|
|
||||||
{% use 'tables/partials/organisations/column-admin_count.html.twig' %}
|
|
||||||
{% use 'tables/partials/organisations/column-join.html.twig' %}
|
|
||||||
{% use 'tables/partials/organisations/column-actions.html.twig' %}
|
|
||||||
|
|
||||||
{% block table %}
|
{% block table %}
|
||||||
<table id="{{table.id}}" class="tablesorter table table-bordered table-hover table-striped" data-sortlist="{{table.sortlist}}">
|
<table id="{{table.id}}" class="tablesorter table table-bordered table-hover table-striped" data-sortlist="{{table.sortlist}}">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="sorter-metatext filter-metatext" data-column-name="name" data-column-template="#{{table.id}}-column-info" data-priority="1">{{translate('ORGANISATION')}} <i class="fas fa-sort"></i></th>
|
<th class="sorter-metatext filter-metatext" data-column-name="name" data-column-template="#{{table.id}}-column-info" data-priority="1">{{translate('ORGANISATION')}} <i class="fas fa-sort"></i></th>
|
||||||
{% if 'description' not in table.hidden_columns %}
|
{% if 'description' in table.columns %}
|
||||||
<th class="sorter-metatext filter-metatext" data-column-name="description" data-column-template="#{{table.id}}-column-description" data-priority="2">{{translate("DESCRIPTION")}} <i class="fas fa-sort"></i></th>
|
<th class="sorter-metatext filter-metatext" data-column-name="description" data-column-template="#{{table.id}}-column-description" data-priority="2">{{translate("DESCRIPTION")}} <i class="fas fa-sort"></i></th>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if hasRole('site-admin') or hasRole('organisations-admin') or (current_user.adminForOrganisations.count > 0) -%}
|
{% if 'status' in table.columns %}
|
||||||
<th class="filter-select filter-metatext" data-column-name="status" data-column-template="#{{table.id}}-column-status" data-priority="2">{{translate("STATUS")}} <i class="fas fa-sort"></i></th>
|
<th class="filter-select filter-metatext" data-column-name="status" data-column-template="#{{table.id}}-column-status" data-priority="2">{{translate("STATUS")}} <i class="fas fa-sort"></i></th>
|
||||||
{% endif -%}
|
{% endif %}
|
||||||
{% if checkAccess('view_organisation_members') -%}
|
{% if checkAccess('view_organisation_field', { 'property' : 'members' }) %}
|
||||||
<th class="sorter-metanum" data-column-name="member_count" data-column-template="#{{table.id}}-column-member_count" data-priority="2" style="min-width: 180px">{{translate("ORGANISATION.MEMBER_COUNT")}} <i class="fas fa-sort"></i></th>
|
<th class="sorter-metanum" data-column-name="member_count" data-column-template="#{{table.id}}-column-memberCount" data-priority="2" style="min-width: 180px">{{translate("ORGANISATION.MEMBER_COUNT")}} <i class="fas fa-sort"></i></th>
|
||||||
<th class="sorter-metanum" data-column-name="admin_count" data-column-template="#{{table.id}}-column-admin_count" data-priority="2">{{translate("ORGANISATION.ADMIN_COUNT")}} <i class="fas fa-sort"></i></th>
|
<th class="sorter-metanum" data-column-name="admin_count" data-column-template="#{{table.id}}-column-adminCount" data-priority="2">{{translate("ORGANISATION.ADMIN_COUNT")}} <i class="fas fa-sort"></i></th>
|
||||||
{% endif -%}
|
{% endif %}
|
||||||
|
{% if not organisationConfig.combine_action_buttons %}
|
||||||
{% if 'join' in table.columns %}
|
{% if 'join' in table.columns %}
|
||||||
<th data-column-template="#{{table.id}}-column-join" data-column-name="join" data-sorter="false" data-filter="false" data-priority="3">{{translate("JOIN")}}/{{translate("LEAVE")}}</th>
|
<th data-column-template="#{{table.id}}-column-join" data-column-name="join" data-sorter="false" data-filter="false" data-priority="3">{{translate("JOIN")}}/{{translate("LEAVE")}}</th>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
{% if 'actions' in table.columns %}
|
{% if 'actions' in table.columns %}
|
||||||
{% if hasRole('site-admin') or hasRole('organisations-admin') or (current_user.adminForOrganisations.count > 0) -%}
|
|
||||||
<th data-column-template="#{{table.id}}-column-actions" data-sorter="false" data-filter="false" data-priority="1">{{translate("ACTIONS")}}</th>
|
<th data-column-template="#{{table.id}}-column-actions" data-sorter="false" data-filter="false" data-priority="1">{{translate("ACTIONS")}}</th>
|
||||||
{% endif -%}
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
@@ -46,13 +38,27 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block table_cell_templates %}
|
{% block table_cell_templates %}
|
||||||
{{ block('table_cell_template_info') }}
|
{% block table_organisations_column_info %}
|
||||||
{{ block('table_cell_template_description') }}
|
{% include "tables/columns/organisations-info.html.twig" %}
|
||||||
{{ block('table_cell_template_status') }}
|
{% endblock %}
|
||||||
{{ block('table_cell_template_member_count') }}
|
{% block table_organisations_column_description %}
|
||||||
{{ block('table_cell_template_admin_count') }}
|
{% include "tables/columns/organisations-description.html.twig" %}
|
||||||
{{ block('table_cell_template_join') }}
|
{% endblock %}
|
||||||
{{ block('table_cell_template_actions') }}
|
{% block table_organisations_column_status %}
|
||||||
|
{% include "tables/columns/organisations-status.html.twig" %}
|
||||||
|
{% endblock %}
|
||||||
|
{% block table_organisations_column_member_count %}
|
||||||
|
{% include "tables/columns/organisations-member_count.html.twig" %}
|
||||||
|
{% endblock %}
|
||||||
|
{% block table_organisations_column_admin_count %}
|
||||||
|
{% include "tables/columns/organisations-admin_count.html.twig" %}
|
||||||
|
{% endblock %}
|
||||||
|
{% block table_organisations_column_join %}
|
||||||
|
{% include "tables/columns/organisations-join.html.twig" %}
|
||||||
|
{% endblock %}
|
||||||
|
{% block table_organisations_column_actions %}
|
||||||
|
{% include "tables/columns/organisations-actions.html.twig" %}
|
||||||
|
{% endblock %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,56 +0,0 @@
|
|||||||
{% block table_cell_template_actions %}
|
|
||||||
{% if checkAccess('update_organisation_field', { 'organisation': organisation, 'fields': [ 'members' ] }) or isOrganisationAdmin(organisation) %}
|
|
||||||
<script id="{{table.id}}-column-actions" type="text/x-handlebars-template">
|
|
||||||
{%- verbatim %}
|
|
||||||
<td class="uf-table-fit-width">
|
|
||||||
<div class="btn-group">
|
|
||||||
<button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown">{% endverbatim %}{{translate("ACTIONS")}}{% verbatim %}<span class="caret"></span></button>
|
|
||||||
<ul class="dropdown-menu dropdown-menu-right-responsive" role="menu">
|
|
||||||
{{#ifx row.membership_approved '!=' 1 }}
|
|
||||||
<li>
|
|
||||||
<a href="#" data-slug="{% endverbatim %}{{organisation.slug}}{% verbatim %}" data-user_name="{{row.user_name}}" class="js-member-accept">
|
|
||||||
<i class="fas fa-thumbs-up"></i> {% endverbatim %}{{translate("ORGANISATION.JOIN_REQUEST.ACCEPT")}}{% verbatim %}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a href="#" data-slug="{% endverbatim %}{{organisation.slug}}{% verbatim %}" data-user_name="{{row.user_name}}" class="js-member-reject">
|
|
||||||
<i class="fas fa-thumbs-down"></i> {% endverbatim %}{{translate("ORGANISATION.JOIN_REQUEST.REJECT")}}{% verbatim %}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
{{ else }}
|
|
||||||
{{#ifx row.organisation_admin '==' 1 }}
|
|
||||||
<li>
|
|
||||||
<a href="#" data-slug="{% endverbatim %}{{organisation.slug}}{% verbatim %}" data-user_name="{{row.user_name}}" class="js-member-demote">
|
|
||||||
<i class="fas fa-angle-double-down"></i> {% endverbatim %}{{translate("MEMBER.DEMOTE")}}{% verbatim %}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
{{ else }}
|
|
||||||
<li>
|
|
||||||
<a href="#" data-slug="{% endverbatim %}{{organisation.slug}}{% verbatim %}" data-user_name="{{row.user_name}}" class="js-member-promote">
|
|
||||||
<i class="fas fa-angle-double-up"></i> {% endverbatim %}{{translate("MEMBER.PROMOTE")}}{% verbatim %}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
{{/ifx}}
|
|
||||||
<li>
|
|
||||||
<a href="#" data-slug="{% endverbatim %}{{organisation.slug}}{% verbatim %}" data-user_name="{{row.user_name}}" class="js-user-edit">
|
|
||||||
<i class="fas fa-edit"></i> {% endverbatim %}{{translate("MEMBER.EDIT")}}{% verbatim %}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a href="#" data-slug="{% endverbatim %}{{organisation.slug}}{% verbatim %}" data-user_name="{{row.user_name}}" class="js-user-password">
|
|
||||||
<i class="fas fa-key"></i> {% endverbatim %}{{translate("MEMBER.CHANGE_PASSWORD")}}{% verbatim %}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a href="#" data-slug="{% endverbatim %}{{organisation.slug}}{% verbatim %}" data-user_name="{{row.user_name}}" class="js-member-remove">
|
|
||||||
<i class="fas fa-door-open"></i> {% endverbatim %}{{translate("MEMBER.REMOVE")}}{% verbatim %}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
{{/ifx}}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
{% endverbatim -%}
|
|
||||||
</script>
|
|
||||||
{% endif %}
|
|
||||||
{% endblock %}
|
|
||||||
@@ -1,86 +0,0 @@
|
|||||||
{% block table_cell_template_actions %}
|
|
||||||
{%- if hasRole('site-admin') or hasRole('organisations-admin') %}
|
|
||||||
<script id="{{table.id}}-column-actions" type="text/x-handlebars-template">
|
|
||||||
{%- verbatim %}
|
|
||||||
<td>
|
|
||||||
<div class="btn-group">
|
|
||||||
<button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown">
|
|
||||||
{% endverbatim %}{{translate("ACTIONS")}}{% verbatim %}
|
|
||||||
<span class="caret"></span>
|
|
||||||
</button>
|
|
||||||
<ul class="dropdown-menu dropdown-menu-right" role="menu">
|
|
||||||
{% endverbatim %}{% if checkAccess('update_organisation_field') %}{% verbatim %}
|
|
||||||
<li>
|
|
||||||
<a href="#" data-slug="{{row.slug}}" class="js-organisation-edit">
|
|
||||||
<i class="fas fa-edit"></i> {% endverbatim %}{{translate("ORGANISATION.EDIT")}}{% verbatim %}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
{% endverbatim %}{% endif %}{% verbatim %}
|
|
||||||
{% endverbatim %}{% if checkAccess('merge_organisations') %}{% verbatim %}
|
|
||||||
<li>
|
|
||||||
<a href="#" data-slug="{{row.slug}}" class="js-organisation-merge">
|
|
||||||
<i class="fas fa-object-group"></i> {% endverbatim %}{{translate("ORGANISATION.MERGE")}}{% verbatim %}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
{% endverbatim %}{% endif %}{% verbatim %}
|
|
||||||
{% endverbatim %}{% if checkAccess('approve_organisation') %}{% verbatim %}
|
|
||||||
{{#ifx row.flag_approved '==' 0 }}
|
|
||||||
<li>
|
|
||||||
<a href="#" data-slug="{{row.slug}}" class="js-organisation-approveRegistration">
|
|
||||||
<i class="fas fa-thumbs-up"></i> {% endverbatim %}{{translate("ORGANISATION.REGISTRATION.APPROVE")}}{% verbatim %}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a href="#" data-slug="{{row.slug}}" class="js-organisation-denyRegistration">
|
|
||||||
<i class="fas fa-thumbs-down"></i> {% endverbatim %}{{translate("ORGANISATION.REGISTRATION.DENY")}}{% verbatim %}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
{{/ifx }}
|
|
||||||
{% endverbatim %}{% endif %}{% verbatim %}
|
|
||||||
{% endverbatim %}{% if checkAccess('delete_organisation') %}{% verbatim %}
|
|
||||||
{{#ifx row.flag_approved '==' 1 }}
|
|
||||||
<li>
|
|
||||||
<a href="#" data-slug="{{row.slug}}" class="js-organisation-delete">
|
|
||||||
<i class="fas fa-trash-alt"></i> {% endverbatim %}{{translate("ORGANISATION.DELETE")}}{% verbatim %}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
{{/ifx }}
|
|
||||||
{% endverbatim %}{% endif %}{% verbatim %}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
{% endverbatim -%}
|
|
||||||
</script>
|
|
||||||
{%- elseif (current_user.adminForOrganisations.count > 0) -%}
|
|
||||||
<script id="{{table.id}}-column-actions" type="text/x-handlebars-template">
|
|
||||||
{%- verbatim %}
|
|
||||||
<td>
|
|
||||||
{{#ifx row.is_admin '==' 1 }}
|
|
||||||
<div class="btn-group">
|
|
||||||
<button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown">
|
|
||||||
{% endverbatim %}{{translate("ACTIONS")}}{% verbatim %}
|
|
||||||
<span class="caret"></span>
|
|
||||||
</button>
|
|
||||||
<ul class="dropdown-menu dropdown-menu-right" role="menu">
|
|
||||||
<li>
|
|
||||||
<a href="#" data-slug="{{row.slug}}" class="js-organisation-edit">
|
|
||||||
<i class="fas fa-edit"></i> {% endverbatim %}{{translate("ORGANISATION.EDIT")}}{% verbatim %}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
{{#ifx row.flag_approved '==' 0 }}
|
|
||||||
{{#ifx row.registrant_id '==' {% endverbatim %}{{current_user.id}}{% verbatim %} }}
|
|
||||||
<li>
|
|
||||||
<a href="#" data-slug="{{row.slug}}" class="js-organisation-cancelRegistration">
|
|
||||||
<i class="fas fa-trash-alt"></i> {% endverbatim %}{{translate("ORGANISATION.REGISTRATION.CANCEL")}}{% verbatim %}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
{{/ifx}}
|
|
||||||
{{/ifx}}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
{{/ifx }}
|
|
||||||
</td>
|
|
||||||
{% endverbatim -%}
|
|
||||||
</script>
|
|
||||||
{% endif -%}
|
|
||||||
{% endblock %}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
{% block table_cell_template_admin_count %}
|
|
||||||
{%- if checkAccess('view_organisation_members') -%}
|
|
||||||
<script id="{{table.id}}-column-adminCount" type="text/x-handlebars-template">
|
|
||||||
{%- verbatim %}
|
|
||||||
<td>
|
|
||||||
{{row.admin_count}}
|
|
||||||
</td>
|
|
||||||
{% endverbatim -%}
|
|
||||||
</script>
|
|
||||||
{% endif -%}
|
|
||||||
{% endblock %}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
{% block table_cell_template_description %}
|
|
||||||
<script id="{{table.id}}-column-description" type="text/x-handlebars-template">
|
|
||||||
{%- verbatim %}
|
|
||||||
<td>
|
|
||||||
{{row.description}}
|
|
||||||
</td>
|
|
||||||
{% endverbatim -%}
|
|
||||||
</script>
|
|
||||||
{% endblock %}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
{% block table_cell_template_info %}
|
|
||||||
<script id="{{table.id}}-column-info" type="text/x-handlebars-template">
|
|
||||||
{%- verbatim %}
|
|
||||||
<td data-text="{{row.name}}">
|
|
||||||
<strong>
|
|
||||||
{{#ifx row.is_member '==' 1 }}
|
|
||||||
<a href="{{site.uri.public}}/organisations/o/{{row.slug}}">{{row.name}}</a>
|
|
||||||
{{ else }}
|
|
||||||
{% endverbatim %}{% if hasRole('organisations-admin') or hasRole('site-admin') %}{% verbatim %}
|
|
||||||
<a href="{{site.uri.public}}/organisations/o/{{row.slug}}">{{row.name}}</a>
|
|
||||||
{% endverbatim %}{% else %}{% verbatim %}
|
|
||||||
{{row.name}}
|
|
||||||
{% endverbatim %}{% endif %}{% verbatim %}
|
|
||||||
{{/ifx }}
|
|
||||||
</strong>
|
|
||||||
</td>
|
|
||||||
{% endverbatim -%}
|
|
||||||
</script>
|
|
||||||
{% endblock %}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
{% block table_cell_template_join %}
|
|
||||||
<script id="{{table.id}}-column-join" type="text/x-handlebars-template">
|
|
||||||
{%- verbatim %}
|
|
||||||
<td>
|
|
||||||
<div class="btn-group">
|
|
||||||
{{#ifx row.is_pending '==' 1 }}
|
|
||||||
<button type="button" data-slug="{{row.slug}}" class="btn btn-danger js-organisation-cancelJoin" style="min-width: 70px">
|
|
||||||
{% endverbatim %}{{translate("CANCEL")}}{% verbatim %}
|
|
||||||
</button>
|
|
||||||
{{ else }}
|
|
||||||
{{#ifx row.is_member '==' 1 }}
|
|
||||||
<button type="button" data-slug="{{row.slug}}" class="btn btn-danger js-organisation-leave" style="min-width: 70px">
|
|
||||||
{% endverbatim %}{{translate("LEAVE")}}{% verbatim %}
|
|
||||||
</button>
|
|
||||||
{{ else }}
|
|
||||||
{% endverbatim %}{% if (organisationConfig.membership.single_membership == 0) or ((current_user.organisations.count == 0) and (current_user.pendingOrganisations.count == 0)) %}{% verbatim %}
|
|
||||||
<button type="button" data-slug="{{row.slug}}" class="btn btn-success js-organisation-join" style="min-width: 70px">
|
|
||||||
{% endverbatim %}{{translate("JOIN")}}{% verbatim %}
|
|
||||||
</button>
|
|
||||||
{% endverbatim %}{% endif %}{% verbatim %}
|
|
||||||
{{/ifx}}
|
|
||||||
{{/ifx}}
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
{% endverbatim -%}
|
|
||||||
</script>
|
|
||||||
{% endblock %}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
{% block table_cell_template_member_count %}
|
|
||||||
{%- if checkAccess('view_organisation_members') -%}
|
|
||||||
<script id="{{table.id}}-column-memberCount" type="text/x-handlebars-template">
|
|
||||||
{%- verbatim %}
|
|
||||||
<td>
|
|
||||||
{{row.member_count}}
|
|
||||||
</td>
|
|
||||||
{% endverbatim -%}
|
|
||||||
</script>
|
|
||||||
{% endif -%}
|
|
||||||
{% endblock %}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
{% block table_cell_template_status %}
|
|
||||||
{%- if hasRole('site-admin') or hasRole('organisations-admin') or (current_user.adminForOrganisations.count > 0) %}
|
|
||||||
<script id="{{table.id}}-column-status" type="text/x-handlebars-template">
|
|
||||||
{%- verbatim %}
|
|
||||||
<td
|
|
||||||
{{#ifx row.flag_approved '==' 1 }}
|
|
||||||
data-text="approved"
|
|
||||||
{{ else }}
|
|
||||||
data-text="pending"
|
|
||||||
{{/ifx }}
|
|
||||||
>
|
|
||||||
{{#ifx row.flag_approved '==' 1 }}
|
|
||||||
<span>
|
|
||||||
{% endverbatim %}{{translate("APPROVED")}}{% verbatim %}
|
|
||||||
</span>
|
|
||||||
{{ else }}
|
|
||||||
<span class="text-yellow">
|
|
||||||
{% endverbatim %}{{translate("PENDING")}}{% verbatim %}
|
|
||||||
</span>
|
|
||||||
{{/ifx }}
|
|
||||||
</td>
|
|
||||||
{% endverbatim -%}
|
|
||||||
</script>
|
|
||||||
{% endif -%}
|
|
||||||
{% endblock %}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
{% block table_cell_template_organisations %}
|
|
||||||
<script id="{{table.id}}-column-organisations" type="text/x-handlebars-template">
|
|
||||||
{%- verbatim %}
|
|
||||||
<td style="line-height: 2em;">
|
|
||||||
{{#if row.organisations.length }}
|
|
||||||
{{#each row.organisations }}
|
|
||||||
<a href="{% endverbatim %}{{site.uri.public}}{% verbatim %}/organisations/o/{{this.slug}}" class="label bg-primary {{#ifx this.flag_approved '!=' 1 }}organisation-pending{{/ifx}} {{#if this.pivot.flag_admin }}organisation-admin{{/if}}" title="{{this.description}}" data-text="{{this.name}}" style="font-size: 100%;">{{this.name}}</a><br>
|
|
||||||
{{/each}}
|
|
||||||
{{/if }}
|
|
||||||
{{#if row.pending_organisations.length }}
|
|
||||||
{{#each row.pending_organisations }}
|
|
||||||
<a href="{% endverbatim %}{{site.uri.public}}{% verbatim %}/organisations/o/{{this.slug}}" class="label bg-primary {{#ifx this.flag_approved '!=' 1 }}organisation-pending{{/ifx}} {{#if this.pivot.flag_admin }}organisation-admin{{/if}} membership-pending" title="{{this.description}}" data-text="{{this.name}}" style="font-size: 100%;">{{this.name}}</a><br>
|
|
||||||
{{/each}}
|
|
||||||
{{/if }}
|
|
||||||
</td>
|
|
||||||
{% endverbatim -%}
|
|
||||||
</script>
|
|
||||||
{% endblock %}
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
{% extends "@blockier-templates/tables/users.html.twig" %}
|
{% extends "@uf-tweaks/tables/users.html.twig" %}
|
||||||
|
|
||||||
{% block table %}
|
{% block table %}
|
||||||
<table id="{{table.id}}" class="tablesorter table table-bordered table-hover table-striped" data-sortlist="{{table.sortlist}}">
|
<table id="{{table.id}}" class="tablesorter table table-bordered table-hover table-striped" data-sortlist="{{table.sortlist}}">
|
||||||
@@ -7,10 +7,10 @@
|
|||||||
<th class="sorter-metatext" data-column-name="name" data-column-template="#{{table.id}}-column-info" data-priority="1">{{translate('USER')}} <i class="fas fa-sort"></i></th>
|
<th class="sorter-metatext" data-column-name="name" data-column-template="#{{table.id}}-column-info" data-priority="1">{{translate('USER')}} <i class="fas fa-sort"></i></th>
|
||||||
<th class="filter-metatext" data-column-name="organisations" data-sorter="false" data-column-template="#{{table.id}}-column-organisations" data-priority="2">{{translate("ORGANISATION", 2)}}</th>
|
<th class="filter-metatext" data-column-name="organisations" data-sorter="false" data-column-template="#{{table.id}}-column-organisations" data-priority="2">{{translate("ORGANISATION", 2)}}</th>
|
||||||
{% if 'last_activity' in table.columns %}
|
{% if 'last_activity' in table.columns %}
|
||||||
<th class="sorter-metanum" data-column-name="last_activity" data-column-template="#{{table.id}}-column-last-activity" data-priority="3">{{translate("ACTIVITY.LAST")}} <i class="fas fa-sort"></i></th>
|
<th class="sorter-metanum" data-column-name="last_activity" data-column-template="#{{table.id}}-column-lastActivity" data-priority="3">{{translate("ACTIVITY.LAST")}} <i class="fas fa-sort"></i></th>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if 'via_roles' in table.columns %}
|
{% if 'via_roles' in table.columns %}
|
||||||
<th data-column-template="#{{table.id}}-column-via-roles" data-sorter="false" data-filter="false" data-priority="1">{{translate('PERMISSION.VIA_ROLES')}}</th>
|
<th data-column-template="#{{table.id}}-column-viaRoles" data-sorter="false" data-filter="false" data-priority="1">{{translate('PERMISSION.VIA_ROLES')}}</th>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<th class="filter-select filter-metatext" data-column-name="status" data-column-template="#{{table.id}}-column-status" data-priority="2">{{translate("STATUS")}} <i class="fas fa-sort"></i></th>
|
<th class="filter-select filter-metatext" data-column-name="status" data-column-template="#{{table.id}}-column-status" data-priority="2">{{translate("STATUS")}} <i class="fas fa-sort"></i></th>
|
||||||
<th data-column-name="actions" data-column-template="#{{table.id}}-column-actions" data-sorter="false" data-filter="false" data-priority="1">{{translate("ACTIONS")}}</th>
|
<th data-column-name="actions" data-column-template="#{{table.id}}-column-actions" data-sorter="false" data-filter="false" data-priority="1">{{translate("ACTIONS")}}</th>
|
||||||
@@ -23,6 +23,9 @@
|
|||||||
|
|
||||||
{% block table_cell_templates %}
|
{% block table_cell_templates %}
|
||||||
{{ parent() }}
|
{{ parent() }}
|
||||||
{{ block('table_cell_template_organisations', 'tables/partials/users/column-organisations.html.twig') }}
|
|
||||||
|
{% block table_users_column_organisations %}
|
||||||
|
{% include 'tables/columns/users-organisations.html.twig' %}
|
||||||
|
{% endblock %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user