mirror of
https://gitlab.linphone.org/BC/public/flexisip-account-manager.git
synced 2026-01-17 01:58:07 +00:00
Add call logs browsing, general and per account
This commit is contained in:
parent
95707c7749
commit
179c76251d
19 changed files with 466 additions and 109 deletions
|
|
@ -32,6 +32,7 @@ use Awobaz\Compoships\Compoships;
|
|||
use App\ApiKey;
|
||||
use App\Password;
|
||||
use App\Http\Controllers\Account\AuthenticateController as WebAuthenticateController;
|
||||
use Doctrine\DBAL\Query;
|
||||
|
||||
class Account extends Authenticatable
|
||||
{
|
||||
|
|
@ -91,6 +92,16 @@ class Account extends Authenticatable
|
|||
return $query->where('id', '<', 0);
|
||||
}
|
||||
|
||||
public static function subByContactsList($query, int $contactsListId)
|
||||
{
|
||||
return $query->from('accounts')
|
||||
->whereIn('id', function ($query) use ($contactsListId) {
|
||||
$query->select('contact_id')
|
||||
->from('contacts_list_contact')
|
||||
->where('contacts_list_id', $contactsListId);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Relations
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -5,7 +5,9 @@ namespace App\Http\Controllers\Admin;
|
|||
use App\Account;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Libraries\StatisticsGraphFactory;
|
||||
use App\StatisticsCall;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class AccountStatisticsController extends Controller
|
||||
{
|
||||
|
|
@ -59,4 +61,41 @@ class AccountStatisticsController extends Controller
|
|||
'callsToGraph' => $callsToGraph,
|
||||
]);
|
||||
}
|
||||
|
||||
public function editCallLogs(Request $request, int $accountId)
|
||||
{
|
||||
return redirect()->route('admin.account.statistics.show_call_logs', [
|
||||
'from' => $request->get('from'),
|
||||
'to' => $request->get('to'),
|
||||
'account' => $accountId
|
||||
]);
|
||||
}
|
||||
|
||||
public function showCallLogs(Request $request, int $accountId)
|
||||
{
|
||||
$account = Account::findOrFail($accountId);
|
||||
$toQuery = DB::table('statistics_calls')
|
||||
->where('to_domain', $account->domain)
|
||||
->where('to_username', $account->username);
|
||||
$calls = StatisticsCall::where('from_domain', $account->domain)
|
||||
->where('from_username', $account->username);
|
||||
|
||||
if ($request->get('to')) {
|
||||
$toQuery = $toQuery->where('initiated_at', '<=', $request->get('to'));
|
||||
$calls = $calls->where('initiated_at', '<=', $request->get('to'));
|
||||
}
|
||||
|
||||
if ($request->get('from')) {
|
||||
$toQuery = $toQuery->where('initiated_at', '>=', $request->get('from'));
|
||||
$calls = $calls->where('initiated_at', '>=', $request->get('from'));
|
||||
}
|
||||
|
||||
$calls = $calls->union($toQuery);
|
||||
|
||||
return view('admin.account.statistics.show_call_logs', [
|
||||
'account' => $account,
|
||||
'calls' => $calls->orderBy('initiated_at', 'desc')->paginate(30),
|
||||
'request' => $request,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,21 @@
|
|||
<?php
|
||||
/*
|
||||
Flexisip Account Manager is a set of tools to manage SIP accounts.
|
||||
Copyright (C) 2020 Belledonne Communications SARL, All rights reserved.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
|
|
@ -32,11 +49,6 @@ class StatisticsController extends Controller
|
|||
]);
|
||||
}
|
||||
|
||||
/*public function search(Request $request)
|
||||
{
|
||||
return redirect()->route('admin.statistics.search', $request->except('_token', 'query'));
|
||||
}*/
|
||||
|
||||
public function show(Request $request, string $type = 'messages')
|
||||
{
|
||||
$request->validate([
|
||||
|
|
@ -45,7 +57,7 @@ class StatisticsController extends Controller
|
|||
'by' => 'in:day,week,month,year',
|
||||
]);
|
||||
|
||||
$graph = new StatisticsGraphFactory($request, $type, fromDomain: $request->get('domain'));
|
||||
$graph = new StatisticsGraphFactory($request, type: $type, domain: $request->get('domain'));
|
||||
$config = $graph->getConfig();
|
||||
$domains = collect();
|
||||
|
||||
|
|
@ -77,4 +89,49 @@ class StatisticsController extends Controller
|
|||
'request' => $request
|
||||
]);
|
||||
}
|
||||
|
||||
public function editCallLogs(Request $request)
|
||||
{
|
||||
return redirect()->route('admin.statistics.show_call_logs', [
|
||||
'from' => $request->get('from'),
|
||||
'to' => $request->get('to'),
|
||||
'domain' => $request->get('domain'),
|
||||
'contacts_list' => $request->get('contacts_list'),
|
||||
]);
|
||||
}
|
||||
|
||||
public function showCallLogs(Request $request)
|
||||
{
|
||||
$fromQuery = StatisticsCall::query();
|
||||
$toQuery = StatisticsCall::query();
|
||||
|
||||
if ($request->get('domain')) {
|
||||
$fromQuery->where('to_domain', $request->get('domain'));
|
||||
$toQuery->where('from_domain', $request->get('domain'));
|
||||
}
|
||||
|
||||
if ($request->get('to')) {
|
||||
$fromQuery->where('initiated_at', '<=', $request->get('to'));
|
||||
$toQuery->where('initiated_at', '<=', $request->get('to'));
|
||||
}
|
||||
|
||||
if ($request->get('from')) {
|
||||
$fromQuery->where('initiated_at', '>=', $request->get('from'));
|
||||
$toQuery->where('initiated_at', '>=', $request->get('from'));
|
||||
}
|
||||
|
||||
if ($request->has('contacts_list')) {
|
||||
$fromQuery->fromByContactsList($request->get('contacts_list'));
|
||||
$toQuery->toByContactsList($request->get('contacts_list'));
|
||||
}
|
||||
|
||||
$calls = $fromQuery->union($toQuery);
|
||||
|
||||
return view('admin.statistics.show_call_logs', [
|
||||
'calls' => $calls->orderBy('initiated_at', 'desc')->paginate(30),
|
||||
'domains' => StatisticsCall::groupBy('from_domain')->pluck('from_domain'),
|
||||
'contacts_lists' => ContactsList::all()->pluck('title', 'id'),
|
||||
'request' => $request,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@
|
|||
namespace App\Libraries;
|
||||
|
||||
use App\Account;
|
||||
use App\ContactsList;
|
||||
use App\StatisticsCall;
|
||||
use App\StatisticsMessage;
|
||||
use Carbon\Carbon;
|
||||
|
|
@ -37,6 +36,7 @@ class StatisticsGraphFactory
|
|||
public function __construct(
|
||||
private Request $request,
|
||||
private string $type = 'messages',
|
||||
public ?string $domain = null, // both from and to filter
|
||||
public ?string $fromUsername = null,
|
||||
public ?string $fromDomain = null,
|
||||
public ?string $toUsername = null,
|
||||
|
|
@ -53,58 +53,82 @@ class StatisticsGraphFactory
|
|||
case 'messages':
|
||||
$dateColumn = 'sent_at';
|
||||
$label = 'Messages';
|
||||
$this->data = StatisticsMessage::orderBy($dateColumn, 'asc');
|
||||
$fromQuery = StatisticsMessage::query();
|
||||
$toQuery = StatisticsMessage::query();
|
||||
|
||||
if (!config('app.admins_manage_multi_domains')) {
|
||||
$this->data->where('from_domain', config('app.sip_domain'));
|
||||
$fromQuery->where('from_domain', config('app.sip_domain'));
|
||||
$toQuery->toDomain($this->domain);
|
||||
} elseif ($this->domain) {
|
||||
$fromQuery->where('from_domain', $this->domain);
|
||||
$toQuery->toDomain($this->domain);
|
||||
} elseif ($this->fromDomain) {
|
||||
$this->data->where('from_domain', $this->fromDomain)->orderBy('from_domain');
|
||||
$fromQuery->where('from_domain', $this->fromDomain)->orderBy('from_domain');
|
||||
|
||||
if ($this->fromUsername) {
|
||||
$this->data->where('from_username', $this->fromUsername);
|
||||
$fromQuery->where('from_username', $this->fromUsername);
|
||||
}
|
||||
} elseif ($this->toDomain && $this->toUsername) {
|
||||
$this->data->whereIn('id', function ($query) {
|
||||
$query->select('message_id')
|
||||
->from('statistics_message_devices')
|
||||
->where('to_username', $this->toUsername)
|
||||
->where('to_domain', $this->toDomain);
|
||||
});
|
||||
$toQuery->toUsernameDomain($this->toUsername, $this->toDomain);
|
||||
}
|
||||
|
||||
if ($this->request->has('contacts_list')) {
|
||||
$fromQuery = $fromQuery->fromByContactsList($this->request->get('contacts_list'));
|
||||
$toQuery = $toQuery->toByContactsList($this->request->get('contacts_list'));
|
||||
}
|
||||
|
||||
$this->data = $fromQuery; //->union($toQuery);
|
||||
$this->data->orderBy($dateColumn, 'asc');
|
||||
|
||||
break;
|
||||
|
||||
case 'calls':
|
||||
$dateColumn = 'initiated_at';
|
||||
$label = 'Calls';
|
||||
$this->data = StatisticsCall::orderBy($dateColumn, 'asc');
|
||||
$fromQuery = StatisticsCall::query();
|
||||
$toQuery = StatisticsCall::query();
|
||||
|
||||
if (!config('app.admins_manage_multi_domains')) {
|
||||
$this->data->where('from_domain', config('app.sip_domain'));
|
||||
$fromQuery->where('from_domain', config('app.sip_domain'));
|
||||
$toQuery->where('to_domain', config('app.sip_domain'));
|
||||
} elseif ($this->domain) {
|
||||
$fromQuery = $fromQuery->where('to_domain', $this->domain);
|
||||
$toQuery = $toQuery->where('from_domain', $this->domain);
|
||||
} elseif ($this->fromDomain) {
|
||||
$this->data->where('from_domain', $this->fromDomain)->orderBy('from_domain');
|
||||
$fromQuery->where('from_domain', $this->fromDomain)->orderBy('from_domain');
|
||||
|
||||
if ($this->fromUsername) {
|
||||
$this->data->where('from_username', $this->fromUsername);
|
||||
$fromQuery->where('from_username', $this->fromUsername);
|
||||
}
|
||||
} elseif ($this->toDomain) {
|
||||
$this->data->where('to_domain', $this->toDomain)->orderBy('to_domain');
|
||||
$toQuery->where('to_domain', $this->toDomain)->orderBy('to_domain');
|
||||
|
||||
if ($this->toUsername) {
|
||||
$this->data->where('to_username', $this->toUsername);
|
||||
$toQuery->where('to_username', $this->toUsername);
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->request->has('contacts_list')) {
|
||||
$fromQuery = $fromQuery->fromByContactsList($this->request->get('contacts_list'));
|
||||
$toQuery = $toQuery->toByContactsList($this->request->get('contacts_list'));
|
||||
}
|
||||
|
||||
$this->data = $fromQuery; //->union($toQuery);
|
||||
$this->data->orderBy($dateColumn, 'asc');
|
||||
|
||||
break;
|
||||
|
||||
case 'accounts':
|
||||
$label = 'Accounts';
|
||||
$this->data = Account::orderBy($dateColumn, 'asc');
|
||||
|
||||
// Accounts doesn't have a from and to
|
||||
$this->domain = $this->domain ?? $this->fromDomain;
|
||||
|
||||
if (!config('app.admins_manage_multi_domains')) {
|
||||
$this->data->where('domain', config('app.sip_domain'));
|
||||
} elseif ($this->fromDomain) {
|
||||
$this->data->where('domain', $this->fromDomain)->orderBy('domain');
|
||||
} elseif ($this->domain) {
|
||||
$this->data->where('domain', $this->domain);
|
||||
|
||||
if ($this->fromUsername) {
|
||||
$this->data->where('username', $this->fromUsername);
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
use Awobaz\Compoships\Compoships;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class StatisticsCall extends Model
|
||||
{
|
||||
|
|
@ -42,4 +43,36 @@ class StatisticsCall extends Model
|
|||
{
|
||||
return $this->belongsTo(Account::class, ['username', 'domain'], ['to_username', 'to_domain']);
|
||||
}
|
||||
|
||||
public function getFromAttribute()
|
||||
{
|
||||
return $this->attributes['from_username'] . '@' . $this->attributes['from_domain'];
|
||||
}
|
||||
|
||||
public function getToAttribute()
|
||||
{
|
||||
return $this->attributes['to_username'] . '@' . $this->attributes['to_domain'];
|
||||
}
|
||||
|
||||
public function scopeToByContactsList(Builder $query, int $contactsListId)
|
||||
{
|
||||
return $query->whereIn('to_domain', function ($query) use ($contactsListId) {
|
||||
Account::subByContactsList($query, $contactsListId)
|
||||
->select('domain');
|
||||
})->whereIn('to_username', function ($query) use ($contactsListId) {
|
||||
Account::subByContactsList($query, $contactsListId)
|
||||
->select('username');
|
||||
});
|
||||
}
|
||||
|
||||
public function scopeFromByContactsList(Builder $query, int $contactsListId)
|
||||
{
|
||||
return $query->whereIn('from_domain', function ($query) use ($contactsListId) {
|
||||
Account::subByContactsList($query, $contactsListId)
|
||||
->select('domain');
|
||||
})->whereIn('from_username', function ($query) use ($contactsListId) {
|
||||
Account::subByContactsList($query, $contactsListId)
|
||||
->select('username');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|||
|
||||
use Awobaz\Compoships\Compoships;
|
||||
use Awobaz\Compoships\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class StatisticsMessage extends Model
|
||||
{
|
||||
|
|
@ -37,4 +38,48 @@ class StatisticsMessage extends Model
|
|||
{
|
||||
return $this->belongsTo(Account::class, ['username', 'domain'], ['to_username', 'to_domain']);
|
||||
}
|
||||
|
||||
public function scopeToUsernameDomain(Builder $query, ?string $username, ?string $domain)
|
||||
{
|
||||
return $query->whereIn('id', function ($query) use ($username, $domain) {
|
||||
$query->select('message_id')
|
||||
->from('statistics_message_devices')
|
||||
->where('to_username', $username)
|
||||
->where('to_domain', $domain);
|
||||
});
|
||||
}
|
||||
|
||||
public function scopeToDomain(Builder $query, ?string $domain)
|
||||
{
|
||||
return $query->whereIn('id', function ($query) use ($domain) {
|
||||
$query->select('message_id')
|
||||
->from('statistics_message_devices')
|
||||
->where('to_domain', $domain);
|
||||
});
|
||||
}
|
||||
public function scopeToByContactsList(Builder $query, int $contactsListId)
|
||||
{
|
||||
return $query->whereIn('id', function ($query) use ($contactsListId) {
|
||||
$query->select('message_id')
|
||||
->from('statistics_message_devices')
|
||||
->whereIn('to_domain', function ($query) use ($contactsListId) {
|
||||
Account::subByContactsList($query, $contactsListId)
|
||||
->select('domain');
|
||||
})->whereIn('to_username', function ($query) use ($contactsListId) {
|
||||
Account::subByContactsList($query, $contactsListId)
|
||||
->select('username');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public function scopeFromByContactsList(Builder $query, int $contactsListId)
|
||||
{
|
||||
return $query->whereIn('from_domain', function ($query) use ($contactsListId) {
|
||||
Account::subByContactsList($query, $contactsListId)
|
||||
->select('domain');
|
||||
})->whereIn('from_username', function ($query) use ($contactsListId) {
|
||||
Account::subByContactsList($query, $contactsListId)
|
||||
->select('username');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
80
flexiapi/composer.lock
generated
80
flexiapi/composer.lock
generated
|
|
@ -461,16 +461,16 @@
|
|||
},
|
||||
{
|
||||
"name": "doctrine/dbal",
|
||||
"version": "3.7.0",
|
||||
"version": "3.7.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/doctrine/dbal.git",
|
||||
"reference": "00d03067f07482f025d41ab55e4ba0db5eca2cdf"
|
||||
"reference": "5b7bd66c9ff58c04c5474ab85edce442f8081cb2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/doctrine/dbal/zipball/00d03067f07482f025d41ab55e4ba0db5eca2cdf",
|
||||
"reference": "00d03067f07482f025d41ab55e4ba0db5eca2cdf",
|
||||
"url": "https://api.github.com/repos/doctrine/dbal/zipball/5b7bd66c9ff58c04c5474ab85edce442f8081cb2",
|
||||
"reference": "5b7bd66c9ff58c04c5474ab85edce442f8081cb2",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -554,7 +554,7 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/doctrine/dbal/issues",
|
||||
"source": "https://github.com/doctrine/dbal/tree/3.7.0"
|
||||
"source": "https://github.com/doctrine/dbal/tree/3.7.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
|
@ -570,7 +570,7 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-09-26T20:56:55+00:00"
|
||||
"time": "2023-10-06T05:06:20+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/deprecations",
|
||||
|
|
@ -1320,21 +1320,21 @@
|
|||
},
|
||||
{
|
||||
"name": "fruitcake/php-cors",
|
||||
"version": "v1.2.0",
|
||||
"version": "v1.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/fruitcake/php-cors.git",
|
||||
"reference": "58571acbaa5f9f462c9c77e911700ac66f446d4e"
|
||||
"reference": "3d158f36e7875e2f040f37bc0573956240a5a38b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/fruitcake/php-cors/zipball/58571acbaa5f9f462c9c77e911700ac66f446d4e",
|
||||
"reference": "58571acbaa5f9f462c9c77e911700ac66f446d4e",
|
||||
"url": "https://api.github.com/repos/fruitcake/php-cors/zipball/3d158f36e7875e2f040f37bc0573956240a5a38b",
|
||||
"reference": "3d158f36e7875e2f040f37bc0573956240a5a38b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.4|^8.0",
|
||||
"symfony/http-foundation": "^4.4|^5.4|^6"
|
||||
"symfony/http-foundation": "^4.4|^5.4|^6|^7"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/phpstan": "^1.4",
|
||||
|
|
@ -1344,7 +1344,7 @@
|
|||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "1.1-dev"
|
||||
"dev-master": "1.2-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
|
|
@ -1375,7 +1375,7 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/fruitcake/php-cors/issues",
|
||||
"source": "https://github.com/fruitcake/php-cors/tree/v1.2.0"
|
||||
"source": "https://github.com/fruitcake/php-cors/tree/v1.3.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
|
@ -1387,7 +1387,7 @@
|
|||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2022-02-20T15:07:15+00:00"
|
||||
"time": "2023-10-12T05:21:21+00:00"
|
||||
},
|
||||
{
|
||||
"name": "graham-campbell/result-type",
|
||||
|
|
@ -1858,16 +1858,16 @@
|
|||
},
|
||||
{
|
||||
"name": "laravel/framework",
|
||||
"version": "v9.52.15",
|
||||
"version": "v9.52.16",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel/framework.git",
|
||||
"reference": "e3350e87a52346af9cc655a3012d2175d2d05ad7"
|
||||
"reference": "082345d76fc6a55b649572efe10b11b03e279d24"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laravel/framework/zipball/e3350e87a52346af9cc655a3012d2175d2d05ad7",
|
||||
"reference": "e3350e87a52346af9cc655a3012d2175d2d05ad7",
|
||||
"url": "https://api.github.com/repos/laravel/framework/zipball/082345d76fc6a55b649572efe10b11b03e279d24",
|
||||
"reference": "082345d76fc6a55b649572efe10b11b03e279d24",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -2052,7 +2052,7 @@
|
|||
"issues": "https://github.com/laravel/framework/issues",
|
||||
"source": "https://github.com/laravel/framework"
|
||||
},
|
||||
"time": "2023-08-08T14:28:40+00:00"
|
||||
"time": "2023-10-03T13:02:30+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laravel/serializable-closure",
|
||||
|
|
@ -2304,16 +2304,16 @@
|
|||
},
|
||||
{
|
||||
"name": "league/flysystem",
|
||||
"version": "3.16.0",
|
||||
"version": "3.17.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/thephpleague/flysystem.git",
|
||||
"reference": "4fdf372ca6b63c6e281b1c01a624349ccb757729"
|
||||
"reference": "bd4c9b26849d82364119c68429541f1631fba94b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/thephpleague/flysystem/zipball/4fdf372ca6b63c6e281b1c01a624349ccb757729",
|
||||
"reference": "4fdf372ca6b63c6e281b1c01a624349ccb757729",
|
||||
"url": "https://api.github.com/repos/thephpleague/flysystem/zipball/bd4c9b26849d82364119c68429541f1631fba94b",
|
||||
"reference": "bd4c9b26849d82364119c68429541f1631fba94b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -2331,8 +2331,8 @@
|
|||
"symfony/http-client": "<5.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"async-aws/s3": "^1.5",
|
||||
"async-aws/simple-s3": "^1.1",
|
||||
"async-aws/s3": "^1.5 || ^2.0",
|
||||
"async-aws/simple-s3": "^1.1 || ^2.0",
|
||||
"aws/aws-sdk-php": "^3.220.0",
|
||||
"composer/semver": "^3.0",
|
||||
"ext-fileinfo": "*",
|
||||
|
|
@ -2378,7 +2378,7 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/thephpleague/flysystem/issues",
|
||||
"source": "https://github.com/thephpleague/flysystem/tree/3.16.0"
|
||||
"source": "https://github.com/thephpleague/flysystem/tree/3.17.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
|
@ -2390,7 +2390,7 @@
|
|||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2023-09-07T19:22:17+00:00"
|
||||
"time": "2023-10-05T20:15:05+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/flysystem-local",
|
||||
|
|
@ -2838,16 +2838,16 @@
|
|||
},
|
||||
{
|
||||
"name": "nette/schema",
|
||||
"version": "v1.2.4",
|
||||
"version": "v1.2.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/nette/schema.git",
|
||||
"reference": "c9ff517a53903b3d4e29ec547fb20feecb05b8ab"
|
||||
"reference": "0462f0166e823aad657c9224d0f849ecac1ba10a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/nette/schema/zipball/c9ff517a53903b3d4e29ec547fb20feecb05b8ab",
|
||||
"reference": "c9ff517a53903b3d4e29ec547fb20feecb05b8ab",
|
||||
"url": "https://api.github.com/repos/nette/schema/zipball/0462f0166e823aad657c9224d0f849ecac1ba10a",
|
||||
"reference": "0462f0166e823aad657c9224d0f849ecac1ba10a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -2894,9 +2894,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/nette/schema/issues",
|
||||
"source": "https://github.com/nette/schema/tree/v1.2.4"
|
||||
"source": "https://github.com/nette/schema/tree/v1.2.5"
|
||||
},
|
||||
"time": "2023-08-05T18:56:25+00:00"
|
||||
"time": "2023-10-05T20:37:59+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nette/utils",
|
||||
|
|
@ -8724,16 +8724,16 @@
|
|||
},
|
||||
{
|
||||
"name": "composer/pcre",
|
||||
"version": "3.1.0",
|
||||
"version": "3.1.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/composer/pcre.git",
|
||||
"reference": "4bff79ddd77851fe3cdd11616ed3f92841ba5bd2"
|
||||
"reference": "00104306927c7a0919b4ced2aaa6782c1e61a3c9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/composer/pcre/zipball/4bff79ddd77851fe3cdd11616ed3f92841ba5bd2",
|
||||
"reference": "4bff79ddd77851fe3cdd11616ed3f92841ba5bd2",
|
||||
"url": "https://api.github.com/repos/composer/pcre/zipball/00104306927c7a0919b4ced2aaa6782c1e61a3c9",
|
||||
"reference": "00104306927c7a0919b4ced2aaa6782c1e61a3c9",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -8775,7 +8775,7 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/composer/pcre/issues",
|
||||
"source": "https://github.com/composer/pcre/tree/3.1.0"
|
||||
"source": "https://github.com/composer/pcre/tree/3.1.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
|
@ -8791,7 +8791,7 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-11-17T09:50:14+00:00"
|
||||
"time": "2023-10-11T07:11:09+00:00"
|
||||
},
|
||||
{
|
||||
"name": "composer/xdebug-handler",
|
||||
|
|
@ -9666,5 +9666,5 @@
|
|||
"platform-overrides": {
|
||||
"php": "8.0.2"
|
||||
},
|
||||
"plugin-api-version": "2.6.0"
|
||||
"plugin-api-version": "2.3.0"
|
||||
}
|
||||
|
|
|
|||
4
flexiapi/public/css/style.css
vendored
4
flexiapi/public/css/style.css
vendored
|
|
@ -113,6 +113,10 @@ pre {
|
|||
color: var(--second-7);
|
||||
}
|
||||
|
||||
b {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
em {
|
||||
font-style: italic;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,13 +19,7 @@
|
|||
<input form="create_edit" class="btn" type="submit" value="Update">
|
||||
</header>
|
||||
<p title="{{ $account->updated_at }}">Updated on {{ $account->updated_at->format('d/m/Y') }}
|
||||
@include('parts.tabs', [
|
||||
'items' => [
|
||||
route('admin.account.edit', $account->id) => 'Information',
|
||||
route('admin.account.device.index', $account->id) => 'Devices',
|
||||
route('admin.account.statistics.show', $account->id) => 'Statistics',
|
||||
],
|
||||
])
|
||||
@include('admin.account.parts.tabs')
|
||||
@else
|
||||
<header>
|
||||
<h1><i class="material-icons-outlined">people</i> Create an account</h1>
|
||||
|
|
|
|||
|
|
@ -17,13 +17,7 @@
|
|||
<a href="{{ route('admin.account.edit', $account->id) }}" class="btn btn-secondary oppose">Cancel</a>
|
||||
</header>
|
||||
|
||||
@include('parts.tabs', [
|
||||
'items' => [
|
||||
route('admin.account.edit', $account->id) => 'Information',
|
||||
route('admin.account.device.index', $account->id) => 'Devices',
|
||||
route('admin.account.statistics.show', $account->id) => 'Statistics',
|
||||
],
|
||||
])
|
||||
@include('admin.account.parts.tabs')
|
||||
|
||||
<table class="table">
|
||||
<thead>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
@include('parts.tabs', [
|
||||
'items' => [
|
||||
route('admin.account.edit', $account->id) => 'Information',
|
||||
route('admin.account.statistics.show_call_logs', $account->id) => 'Call Logs',
|
||||
route('admin.account.device.index', $account->id) => 'Devices',
|
||||
route('admin.account.statistics.show', $account->id) => 'Statistics',
|
||||
],
|
||||
])
|
||||
|
|
@ -16,13 +16,7 @@
|
|||
<h1><i class="material-icons-outlined">people</i> {{ $account->identifier }}</h1>
|
||||
</header>
|
||||
|
||||
@include('parts.tabs', [
|
||||
'items' => [
|
||||
route('admin.account.edit', $account->id) => 'Information',
|
||||
route('admin.account.device.index', $account->id) => 'Devices',
|
||||
route('admin.account.statistics.show', $account->id) => 'Statistics',
|
||||
],
|
||||
])
|
||||
@include('admin.account.parts.tabs')
|
||||
|
||||
<div>
|
||||
<form class="inline" method="POST" action="{{ route('admin.account.statistics.edit', $account) }}" accept-charset="UTF-8">
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
@extends('layouts.main')
|
||||
|
||||
@section('breadcrumb')
|
||||
<li class="breadcrumb-item">
|
||||
<a href="{{ route('admin.account.index') }}">Accounts</a>
|
||||
</li>
|
||||
<li class="breadcrumb-item active" aria-current="page">Call Logs</li>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<header>
|
||||
<h1><i class="material-icons-outlined">list</i> Call Logs</h1>
|
||||
</header>
|
||||
|
||||
@include('admin.account.parts.tabs')
|
||||
|
||||
<div>
|
||||
<form class="inline" method="POST" action="{{ route('admin.account.statistics.edit_call_logs', $account->id) }}" accept-charset="UTF-8">
|
||||
@csrf
|
||||
@method('post')
|
||||
|
||||
<div>
|
||||
<input type="date" name="from" value="{{ $request->get('from') }}" onchange="this.form.submit()">
|
||||
<label for="from">From</label>
|
||||
</div>
|
||||
<div>
|
||||
<input type="date" name="to" value="{{ $request->get('to') }}" onchange="this.form.submit()">
|
||||
<label for="to">To</label>
|
||||
</div>
|
||||
|
||||
<div class="oppose">
|
||||
<a class="btn btn-secondary" href="{{ route('admin.account.statistics.show_call_logs', $account->id) }}">Reset</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@include('parts.call_logs.table', ['calls' => $calls])
|
||||
@endsection
|
||||
|
|
@ -34,22 +34,20 @@
|
|||
</div>
|
||||
@endif
|
||||
|
||||
@if ($type == 'accounts')
|
||||
<div class="select">
|
||||
<select name="contacts_list" onchange="this.form.submit()">
|
||||
<option value="">
|
||||
Select a contacts list
|
||||
<div class="select">
|
||||
<select name="contacts_list" onchange="this.form.submit()">
|
||||
<option value="">
|
||||
Select a contacts list
|
||||
</option>
|
||||
@foreach ($contacts_lists as $key => $name)
|
||||
<option value="{{ $key }}"
|
||||
@if (request()->get('contacts_list', '') == $key) selected="selected" @endif>
|
||||
{{ $name }}
|
||||
</option>
|
||||
@foreach ($contacts_lists as $key => $name)
|
||||
<option value="{{ $key }}"
|
||||
@if (request()->get('contacts_list', '') == $key) selected="selected" @endif>
|
||||
{{ $name }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
<label for="contacts_list">Contacts list</label>
|
||||
</div>
|
||||
@endif
|
||||
@endforeach
|
||||
</select>
|
||||
<label for="contacts_list">Contacts list</label>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<a href="{{ route('admin.statistics.show', ['by' => 'day', 'type' => $type] + $request->only(['from', 'to', 'domain', 'contacts_list'])) }}"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
@include('parts.tabs', [
|
||||
'items' => [
|
||||
route('admin.statistics.show', ['type' => 'accounts']) => 'Accounts',
|
||||
route('admin.statistics.show', ['type' => 'calls']) => 'Calls',
|
||||
route('admin.statistics.show_call_logs') => 'Call Logs',
|
||||
route('admin.statistics.show', ['type' => 'messages']) => 'Messages',
|
||||
],
|
||||
])
|
||||
|
|
@ -9,15 +9,8 @@
|
|||
<h1><i class="material-icons-outlined">analytics</i> Statistics</h1>
|
||||
</header>
|
||||
|
||||
@include('parts.tabs', [
|
||||
'items' => [
|
||||
route('admin.statistics.show', ['type' => 'messages']) => 'Messages',
|
||||
route('admin.statistics.show', ['type' => 'accounts']) => 'Accounts',
|
||||
route('admin.statistics.show', ['type' => 'calls']) => 'Calls',
|
||||
],
|
||||
])
|
||||
@include('admin.statistics.parts.tabs')
|
||||
|
||||
@include('admin.statistics.parts.filters')
|
||||
|
||||
@include('parts.graph')
|
||||
@endsection
|
||||
|
|
|
|||
|
|
@ -0,0 +1,71 @@
|
|||
@extends('layouts.main')
|
||||
|
||||
@section('breadcrumb')
|
||||
<li class="breadcrumb-item active" aria-current="page">Statistics</li>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<header>
|
||||
<h1><i class="material-icons-outlined">analytics</i> Statistics</h1>
|
||||
</header>
|
||||
|
||||
@include('admin.statistics.parts.tabs')
|
||||
|
||||
<div>
|
||||
<form class="inline" method="POST" action="{{ route('admin.statistics.edit_call_logs') }}" accept-charset="UTF-8">
|
||||
@csrf
|
||||
@method('post')
|
||||
|
||||
<div>
|
||||
<input type="date" name="from" value="{{ $request->get('from') }}" onchange="this.form.submit()">
|
||||
<label for="from">From</label>
|
||||
</div>
|
||||
<div>
|
||||
<input type="date" name="to" value="{{ $request->get('to') }}" onchange="this.form.submit()">
|
||||
<label for="to">To</label>
|
||||
</div>
|
||||
|
||||
<div class="large on_desktop"></div>
|
||||
|
||||
@if (config('app.admins_manage_multi_domains'))
|
||||
<div class="select">
|
||||
<select name="domain" onchange="this.form.submit()">
|
||||
<option value="">
|
||||
Select a domain
|
||||
</option>
|
||||
@foreach ($domains as $d)
|
||||
<option value="{{ $d }}"
|
||||
@if (request()->get('domain', '') == $d) selected="selected" @endif>
|
||||
{{ $d }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
<label for="domain">Domain</label>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="select">
|
||||
<select name="contacts_list" onchange="this.form.submit()">
|
||||
<option value="">
|
||||
Select a contacts list
|
||||
</option>
|
||||
@foreach ($contacts_lists as $key => $name)
|
||||
<option value="{{ $key }}"
|
||||
@if (request()->get('contacts_list', '') == $key) selected="selected" @endif>
|
||||
{{ $name }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
<label for="contacts_list">Contacts list</label>
|
||||
</div>
|
||||
|
||||
<div class="on_desktop"></div>
|
||||
|
||||
<div class="oppose">
|
||||
<a class="btn btn-secondary" href="{{ route('admin.statistics.show_call_logs') }}">Reset</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@include('parts.call_logs.table', ['calls' => $calls])
|
||||
@endsection
|
||||
42
flexiapi/resources/views/parts/call_logs/table.blade.php
Normal file
42
flexiapi/resources/views/parts/call_logs/table.blade.php
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>From</th>
|
||||
<th>To</th>
|
||||
<th>Time</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@if ($calls->isEmpty())
|
||||
<tr class="empty">
|
||||
<td colspan="3">No Calls</td>
|
||||
</tr>
|
||||
@endif
|
||||
@foreach ($calls as $call)
|
||||
<tr>
|
||||
<td class="line">
|
||||
@if (isset($account) && $account->identifier != $call->from)
|
||||
<b>{{ $call->from }}</b>
|
||||
@else
|
||||
{{ $call->from }}
|
||||
@endif
|
||||
</td>
|
||||
<td class="line">
|
||||
@if (isset($account) && $account->identifier != $call->to)
|
||||
<b>{{ $call->to }}</b>
|
||||
@else
|
||||
{{ $call->to }}
|
||||
@endif
|
||||
</td>
|
||||
<td class="line">
|
||||
{{ $call->initiated_at }}
|
||||
@if ($call->ended_at)
|
||||
({{ $call->ended_at->diffForHumans($call->initiated_at, true) }})
|
||||
@endif
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
{{ $calls->links('pagination::bootstrap-4') }}
|
||||
|
|
@ -135,6 +135,8 @@ if (config('app.web_panel')) {
|
|||
Route::name('admin.')->prefix('admin')->middleware(['auth.admin'])->group(function () {
|
||||
Route::name('statistics.')->controller(StatisticsController::class)->prefix('statistics')->group(function () {
|
||||
Route::get('/', 'index')->name('index');
|
||||
Route::post('call_logs', 'editCallLogs')->name('edit_call_logs');
|
||||
Route::get('call_logs', 'showCallLogs')->name('show_call_logs');
|
||||
Route::get('/{type?}', 'show')->name('show');
|
||||
Route::post('/', 'edit')->name('edit');
|
||||
//Route::post('search', 'search')->name('search');
|
||||
|
|
@ -208,6 +210,8 @@ if (config('app.web_panel')) {
|
|||
|
||||
Route::name('statistics.')->prefix('{account}/statistics')->controller(AccountStatisticsController::class)->group(function () {
|
||||
Route::get('/', 'show')->name('show');
|
||||
Route::post('call_logs', 'editCallLogs')->name('edit_call_logs');
|
||||
Route::get('call_logs', 'showCallLogs')->name('show_call_logs');
|
||||
Route::post('/', 'edit')->name('edit');
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue