From c1e355a829d4eb864ff21f8ff121799e34b7fea4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timoth=C3=A9e=20Jaussoin?=
Date: Tue, 4 Jul 2023 14:35:21 +0000
Subject: [PATCH] Add ContactList feature, complete the lists and attach them
to accounts
---
flexiapi/app/Account.php | 5 +
flexiapi/app/ContactsList.php | 18 ++
flexiapi/app/Helpers/Utils.php | 21 ++
.../Account/ContactVcardController.php | 5 +-
.../Admin/AccountAccountTypeController.php | 4 +-
.../Admin/AccountActionController.php | 6 +-
.../Admin/AccountContactController.php | 4 +-
.../Controllers/Admin/AccountController.php | 45 ++--
.../Admin/ContactsListContactController.php | 82 ++++++++
.../Admin/ContactsListController.php | 101 +++++++++
.../Api/Account/ContactController.php | 11 +-
.../factories/ContactsListFactory.php | 16 ++
..._27_134132_create_contacts_lists_table.php | 51 +++++
flexiapi/public/css/far.css | 193 +++++++++++++++---
flexiapi/public/css/form.css | 55 ++++-
.../views/account/dashboard.blade.php | 139 +++++++------
.../views/account/devices/index.blade.php | 6 +-
.../account/account_type/create.blade.php | 6 +-
.../account/action/create_edit.blade.php | 2 +-
.../admin/account/action/delete.blade.php | 2 +-
.../admin/account/contact/create.blade.php | 40 ++--
.../admin/account/contact/delete.blade.php | 2 +-
.../views/admin/account/create_edit.blade.php | 183 +++++++++++++++--
.../views/admin/account/delete.blade.php | 22 +-
.../views/admin/account/index.blade.php | 18 +-
.../views/admin/account/show.blade.php | 126 ------------
.../views/admin/account/type/index.blade.php | 6 +-
.../contacts_list/contacts/add.blade.php | 76 +++++++
.../admin/contacts_list/create_edit.blade.php | 92 +++++++++
.../admin/contacts_list/delete.blade.php | 22 ++
.../views/admin/contacts_list/index.blade.php | 49 +++++
.../resources/views/layouts/main.blade.php | 1 +
.../resources/views/parts/sidebar.blade.php | 1 +
flexiapi/routes/web.php | 78 ++++---
.../tests/Feature/ApiAccountContactsTest.php | 121 +++++++----
35 files changed, 1200 insertions(+), 409 deletions(-)
create mode 100644 flexiapi/app/ContactsList.php
create mode 100644 flexiapi/app/Http/Controllers/Admin/ContactsListContactController.php
create mode 100644 flexiapi/app/Http/Controllers/Admin/ContactsListController.php
create mode 100644 flexiapi/database/factories/ContactsListFactory.php
create mode 100644 flexiapi/database/migrations/2023_06_27_134132_create_contacts_lists_table.php
delete mode 100644 flexiapi/resources/views/admin/account/show.blade.php
create mode 100644 flexiapi/resources/views/admin/contacts_list/contacts/add.blade.php
create mode 100644 flexiapi/resources/views/admin/contacts_list/create_edit.blade.php
create mode 100644 flexiapi/resources/views/admin/contacts_list/delete.blade.php
create mode 100644 flexiapi/resources/views/admin/contacts_list/index.blade.php
diff --git a/flexiapi/app/Account.php b/flexiapi/app/Account.php
index eb58f47..e28687b 100644
--- a/flexiapi/app/Account.php
+++ b/flexiapi/app/Account.php
@@ -132,6 +132,11 @@ class Account extends Authenticatable
return $this->belongsToMany(Account::class, 'contacts', 'account_id', 'contact_id');
}
+ public function contactsLists()
+ {
+ return $this->belongsToMany(ContactsList::class, 'account_contacts_list', 'account_id', 'contacts_list_id');
+ }
+
public function nonces()
{
return $this->hasMany(DigestNonce::class);
diff --git a/flexiapi/app/ContactsList.php b/flexiapi/app/ContactsList.php
new file mode 100644
index 0000000..a1f3c61
--- /dev/null
+++ b/flexiapi/app/ContactsList.php
@@ -0,0 +1,18 @@
+belongsToMany(Account::class, 'contacts_list_contact', 'contacts_list_id', 'contact_id');
+ }
+}
diff --git a/flexiapi/app/Helpers/Utils.php b/flexiapi/app/Helpers/Utils.php
index d4ce249..4b662bc 100644
--- a/flexiapi/app/Helpers/Utils.php
+++ b/flexiapi/app/Helpers/Utils.php
@@ -27,6 +27,7 @@ use Illuminate\Support\Facades\Schema;
use League\CommonMark\CommonMarkConverter;
use League\CommonMark\Extension\HeadingPermalink\HeadingPermalinkExtension;
use League\CommonMark\Extension\TableOfContents\TableOfContentsExtension;
+use Illuminate\Support\Facades\DB;
function generateNonce(): string
{
@@ -130,3 +131,23 @@ function resolveDomain(Request $request): string
? $request->get('domain')
: config('app.sip_domain');
}
+
+function resolveUserContacts(Request $request)
+{
+ $selected = ['id', 'username', 'domain', 'activated', 'dtmf_protocol'];
+
+ return Account::whereIn('id', function ($query) use ($request) {
+ $query->select('contact_id')
+ ->from('contacts')
+ ->where('account_id', $request->user()->id)
+ ->union(
+ DB::table('contacts_list_contact')
+ ->select('contact_id')
+ ->whereIn('contacts_list_id', function ($query) use ($request) {
+ $query->select('contacts_list_id')
+ ->from('account_contacts_list')
+ ->where('account_id', $request->user()->id);
+ })
+ );
+ })->select($selected);
+}
diff --git a/flexiapi/app/Http/Controllers/Account/ContactVcardController.php b/flexiapi/app/Http/Controllers/Account/ContactVcardController.php
index 1051f85..e91130b 100644
--- a/flexiapi/app/Http/Controllers/Account/ContactVcardController.php
+++ b/flexiapi/app/Http/Controllers/Account/ContactVcardController.php
@@ -28,7 +28,7 @@ class ContactVcardController extends Controller
public function index(Request $request)
{
return response(
- $request->user()->contacts->map(function ($contact) {
+ resolveUserContacts($request)->get()->map(function ($contact) {
return $contact->toVcard4();
})->implode("\n")
);
@@ -36,8 +36,7 @@ class ContactVcardController extends Controller
public function show(Request $request, string $sip)
{
- return $request->user()
- ->contacts()
+ return resolveUserContacts($request)
->sip($sip)
->firstOrFail()
->toVcard4();
diff --git a/flexiapi/app/Http/Controllers/Admin/AccountAccountTypeController.php b/flexiapi/app/Http/Controllers/Admin/AccountAccountTypeController.php
index d64d955..b3c9982 100644
--- a/flexiapi/app/Http/Controllers/Admin/AccountAccountTypeController.php
+++ b/flexiapi/app/Http/Controllers/Admin/AccountAccountTypeController.php
@@ -56,7 +56,7 @@ class AccountAccountTypeController extends Controller
$request->session()->flash('success', 'Type successfully added');
Log::channel('events')->info('Web Admin: Account type attached', ['id' => $account->identifier, 'type_id' => $request->get('account_type_id')]);
- return redirect()->route('admin.account.show', $account);
+ return redirect()->route('admin.account.edit', $account);
}
public function destroy(Request $request, int $id, int $typeId)
@@ -68,6 +68,6 @@ class AccountAccountTypeController extends Controller
$request->session()->flash('success', 'Type successfully removed');
Log::channel('events')->info('Web Admin: Account type detached', ['id' => $account->identifier, 'type_id' => $request->get('account_type_id')]);
- return redirect()->route('admin.account.show', $account);
+ return redirect()->route('admin.account.edit', $account);
}
}
diff --git a/flexiapi/app/Http/Controllers/Admin/AccountActionController.php b/flexiapi/app/Http/Controllers/Admin/AccountActionController.php
index de94fae..60eb88e 100644
--- a/flexiapi/app/Http/Controllers/Admin/AccountActionController.php
+++ b/flexiapi/app/Http/Controllers/Admin/AccountActionController.php
@@ -57,7 +57,7 @@ class AccountActionController extends Controller
$request->session()->flash('success', 'Action successfully created');
Log::channel('events')->info('Web Admin: Account action created', ['id' => $account->identifier, 'action' => $accountAction->key]);
- return redirect()->route('admin.account.show', $accountAction->account);
+ return redirect()->route('admin.account.edit', $accountAction->account);
}
public function edit(int $id, int $actionId)
@@ -93,7 +93,7 @@ class AccountActionController extends Controller
$request->session()->flash('success', 'Action successfully updated');
Log::channel('events')->info('Web Admin: Account action updated', ['id' => $account->identifier, 'action' => $accountAction->key]);
- return redirect()->route('admin.account.show', $account);
+ return redirect()->route('admin.account.edit', $account);
}
public function delete(int $id, int $actionId)
@@ -120,6 +120,6 @@ class AccountActionController extends Controller
Log::channel('events')->info('Web Admin: Account action deleted', ['id' => $accountAction->account->identifier, 'action_id' => $accountAction->key]);
- return redirect()->route('admin.account.show', $accountAction->account);
+ return redirect()->route('admin.account.edit', $accountAction->account);
}
}
diff --git a/flexiapi/app/Http/Controllers/Admin/AccountContactController.php b/flexiapi/app/Http/Controllers/Admin/AccountContactController.php
index 44a03d4..40c7638 100644
--- a/flexiapi/app/Http/Controllers/Admin/AccountContactController.php
+++ b/flexiapi/app/Http/Controllers/Admin/AccountContactController.php
@@ -54,7 +54,7 @@ class AccountContactController extends Controller
Log::channel('events')->info('Web Admin: Account contact added', ['id' => $account->identifier, 'contact' => $contact->identifier]);
- return redirect()->route('admin.account.show', $account);
+ return redirect()->route('admin.account.edit', $account);
}
public function delete(int $id, int $contactId)
@@ -78,6 +78,6 @@ class AccountContactController extends Controller
$request->session()->flash('success', 'Type successfully removed');
Log::channel('events')->info('Web Admin: Account contact removed', ['id' => $account->identifier, 'contact' => $contact->identifier]);
- return redirect()->route('admin.account.show', $account);
+ return redirect()->route('admin.account.edit', $account);
}
}
diff --git a/flexiapi/app/Http/Controllers/Admin/AccountController.php b/flexiapi/app/Http/Controllers/Admin/AccountController.php
index 0bd7b04..e2cd144 100644
--- a/flexiapi/app/Http/Controllers/Admin/AccountController.php
+++ b/flexiapi/app/Http/Controllers/Admin/AccountController.php
@@ -25,7 +25,7 @@ use Illuminate\Support\Facades\Log;
use Carbon\Carbon;
use App\Account;
-use App\Admin;
+use App\ContactsList;
use App\ExternalAccount;
use App\Http\Requests\CreateAccountRequest;
use App\Http\Requests\UpdateAccountRequest;
@@ -58,14 +58,6 @@ class AccountController extends Controller
return redirect()->route('admin.account.index', $request->except('_token'));
}
- public function show(int $id)
- {
- return view('admin.account.show', [
- 'external_accounts_count' => ExternalAccount::where('used', false)->count(),
- 'account' => Account::findOrFail($id)
- ]);
- }
-
public function create(Request $request)
{
return view('admin.account.create_edit', [
@@ -93,14 +85,20 @@ class AccountController extends Controller
Log::channel('events')->info('Web Admin: Account created', ['id' => $account->identifier]);
- return redirect()->route('admin.account.show', $account->id);
+ return redirect()->route('admin.account.edit', $account->id);
}
public function edit(int $id)
{
return view('admin.account.create_edit', [
'account' => Account::findOrFail($id),
- 'protocols' => [null => 'None'] + Account::$dtmfProtocols
+ 'protocols' => [null => 'None'] + Account::$dtmfProtocols,
+ 'external_accounts_count' => ExternalAccount::where('used', false)->count(),
+ 'contacts_lists' => ContactsList::whereNotIn('id', function ($query) use ($id) {
+ $query->select('contacts_list_id')
+ ->from('account_contacts_list')
+ ->where('account_id', $id);
+ })->get()
]);
}
@@ -125,7 +123,7 @@ class AccountController extends Controller
Log::channel('events')->info('Web Admin: Account updated', ['id' => $account->identifier]);
- return redirect()->route('admin.account.show', $id);
+ return redirect()->route('admin.account.edit', $id);
}
public function attachExternalAccount(int $id)
@@ -146,7 +144,7 @@ class AccountController extends Controller
Log::channel('events')->info('Web Admin: Account provisioned', ['id' => $account->identifier]);
- return redirect()->back();
+ return redirect()->back()->withFragment('provisioning');
}
public function delete(int $id)
@@ -169,4 +167,25 @@ class AccountController extends Controller
return redirect()->route('admin.account.index');
}
+
+ public function attachContactsList(Request $request, int $id)
+ {
+ $request->validate([
+ 'contacts_list_id' => 'required|exists:contacts_lists,id'
+ ]);
+
+ $account = Account::findOrFail($id);
+ $account->contactsLists()->detach([$request->get('contacts_list_id')]);
+ $account->contactsLists()->attach([$request->get('contacts_list_id')]);
+
+ return redirect()->route('admin.account.edit', $id);
+ }
+
+ public function detachContactsList(Request $request, int $id)
+ {
+ $account = Account::findOrFail($id);
+ $account->contactsLists()->detach([$request->get('contacts_list_id')]);
+
+ return redirect()->route('admin.account.edit', $id);
+ }
}
diff --git a/flexiapi/app/Http/Controllers/Admin/ContactsListContactController.php b/flexiapi/app/Http/Controllers/Admin/ContactsListContactController.php
new file mode 100644
index 0000000..26c8190
--- /dev/null
+++ b/flexiapi/app/Http/Controllers/Admin/ContactsListContactController.php
@@ -0,0 +1,82 @@
+.
+*/
+
+namespace App\Http\Controllers\Admin;
+
+use App\Account;
+use App\ContactsList;
+use App\Http\Controllers\Controller;
+use Illuminate\Http\Request;
+
+class ContactsListContactController extends Controller
+{
+ public function add(Request $request, int $contactsListId)
+ {
+ $accounts = Account::orderBy('updated_at', $request->get('updated_at_order', 'desc'))
+ ->with('externalAccount');
+
+ if ($request->has('search')) {
+ $accounts = $accounts->where('username', 'like', '%' . $request->get('search') . '%');
+ }
+
+ return view('admin.contacts_list.contacts.add', [
+ 'contacts_list' => ContactsList::firstOrFail($contactsListId),
+ 'params' => [
+ 'search' => $request->get('search'),
+ 'contacts_list_id' => $contactsListId,
+ 'updated_at_order' => $request->get('updated_at_order') == 'desc' ? 'asc' : 'desc'
+ ],
+ 'accounts' => $accounts->whereNotIn('id', function ($query) use ($contactsListId) {
+ $query->select('contact_id')
+ ->from('contacts_list_contact')
+ ->where('contacts_list_id', $contactsListId);
+ })->paginate(20)->appends($request->query()),
+ ]);
+ }
+
+ public function search(Request $request, int $contactsListId)
+ {
+ return redirect()->route('admin.contacts_lists.contacts.add', ['contacts_list_id' => $contactsListId] + $request->except('_token'));
+ }
+
+ public function store(Request $request, int $contactsListId)
+ {
+ $request->validate([
+ 'contacts_ids' => 'required|exists:accounts,id'
+ ]);
+
+ $contactsList = ContactsList::firstOrFail($contactsListId);
+ $contactsList->contacts()->detach($request->get('contacts_ids')); // Just in case
+ $contactsList->contacts()->attach($request->get('contacts_ids'));
+
+ return redirect()->route('admin.contacts_lists.edit', $contactsList->id);
+ }
+
+ public function destroy(Request $request, int $contactsListId)
+ {
+ $request->validate([
+ 'contacts_ids' => 'required|exists:accounts,id'
+ ]);
+
+ $contactsList = ContactsList::findOrFail($contactsListId);
+ $contactsList->contacts()->detach($request->get('contacts_ids'));
+
+ return redirect()->route('admin.contacts_lists.edit', $contactsList->id);
+ }
+}
diff --git a/flexiapi/app/Http/Controllers/Admin/ContactsListController.php b/flexiapi/app/Http/Controllers/Admin/ContactsListController.php
new file mode 100644
index 0000000..667fc38
--- /dev/null
+++ b/flexiapi/app/Http/Controllers/Admin/ContactsListController.php
@@ -0,0 +1,101 @@
+.
+*/
+
+namespace App\Http\Controllers\Admin;
+
+use App\ContactsList;
+use App\Http\Controllers\Controller;
+use Illuminate\Http\Request;
+
+class ContactsListController extends Controller
+{
+ public function index(Request $request)
+ {
+ return view('admin.contacts_list.index', [
+ 'contacts_lists' => ContactsList::orderBy('updated_at', $request->get('updated_at_order', 'desc'))
+ ->paginate(20)
+ ->appends($request->query()),
+ 'updated_at_order' => $request->get('updated_at_order') == 'desc' ? 'asc' : 'desc'
+ ]);
+ }
+
+ public function show(int $id)
+ {
+ }
+
+ public function create(Request $request)
+ {
+ return view('admin.contacts_list.create_edit', [
+ 'contacts_list' => new ContactsList,
+ ]);
+ }
+
+ public function store(Request $request)
+ {
+ $request->validate([
+ 'title' => 'required',
+ 'description' => 'required'
+ ]);
+
+ $contactsList = new ContactsList;
+ $contactsList->title = $request->get('title');
+ $contactsList->description = $request->get('description');
+ $contactsList->save();
+
+ return redirect()->route('admin.contacts_lists.edit', $contactsList->id);
+ }
+
+ public function edit(int $id)
+ {
+ return view('admin.contacts_list.create_edit', [
+ 'contacts_list' => ContactsList::findOrFail($id),
+ ]);
+ }
+
+ public function update(Request $request, int $id)
+ {
+ $request->validate([
+ 'title' => 'required',
+ 'description' => 'required'
+ ]);
+
+ $contactsList = ContactsList::findOrFail($id);
+ $contactsList->title = $request->get('title');
+ $contactsList->description = $request->get('description');
+ $contactsList->save();
+
+ return redirect()->route('admin.contacts_lists.index');
+ }
+
+
+ public function delete(int $id)
+ {
+ return view('admin.contacts_list.delete', [
+ 'contacts_list' => ContactsList::findOrFail($id),
+ ]);
+ }
+
+ public function destroy(Request $request)
+ {
+ $contactsList = ContactsList::findOrFail($request->get('contacts_lists_id'));
+ $contactsList->delete();
+
+ return redirect()->route('admin.contacts_lists.index');
+ }
+}
diff --git a/flexiapi/app/Http/Controllers/Api/Account/ContactController.php b/flexiapi/app/Http/Controllers/Api/Account/ContactController.php
index 50f717a..343c992 100644
--- a/flexiapi/app/Http/Controllers/Api/Account/ContactController.php
+++ b/flexiapi/app/Http/Controllers/Api/Account/ContactController.php
@@ -20,24 +20,17 @@
namespace App\Http\Controllers\Api\Account;
use Illuminate\Http\Request;
-
use App\Http\Controllers\Controller;
class ContactController extends Controller
{
- private $selected = ['id', 'username', 'domain', 'activated', 'dtmf_protocol'];
-
public function index(Request $request)
{
- return $request->user()->contacts()->select($this->selected)->get();
+ return resolveUserContacts($request)->get();
}
public function show(Request $request, string $sip)
{
- return $request->user()
- ->contacts()
- ->select($this->selected)
- ->sip($sip)
- ->firstOrFail();
+ return resolveUserContacts($request)->sip($sip)->firstOrFail();
}
}
diff --git a/flexiapi/database/factories/ContactsListFactory.php b/flexiapi/database/factories/ContactsListFactory.php
new file mode 100644
index 0000000..0fafdcc
--- /dev/null
+++ b/flexiapi/database/factories/ContactsListFactory.php
@@ -0,0 +1,16 @@
+ $this->faker->title,
+ 'description' => $this->faker->paragraph,
+ ];
+ }
+}
diff --git a/flexiapi/database/migrations/2023_06_27_134132_create_contacts_lists_table.php b/flexiapi/database/migrations/2023_06_27_134132_create_contacts_lists_table.php
new file mode 100644
index 0000000..33067d7
--- /dev/null
+++ b/flexiapi/database/migrations/2023_06_27_134132_create_contacts_lists_table.php
@@ -0,0 +1,51 @@
+id();
+ $table->string('title');
+ $table->text('description');
+ $table->timestamps();
+ });
+
+ Schema::create('account_contacts_list', function (Blueprint $table) {
+ $table->integer('account_id')->unsigned();
+ $table->bigInteger('contacts_list_id')->unsigned();
+ $table->foreign('account_id')->references('id')
+ ->on('accounts')->onDelete('cascade');
+ $table->foreign('contacts_list_id')->references('id')
+ ->on('contacts_lists')->onDelete('cascade');
+ $table->unique(['account_id', 'contacts_list_id']);
+ $table->timestamps();
+ });
+
+ Schema::create('contacts_list_contact', function (Blueprint $table) {
+ $table->integer('contact_id')->unsigned();
+ $table->bigInteger('contacts_list_id')->unsigned();
+ $table->foreign('contact_id')->references('id')
+ ->on('accounts')->onDelete('cascade');
+ $table->foreign('contacts_list_id')->references('id')
+ ->on('contacts_lists')->onDelete('cascade');
+ $table->unique(['contact_id', 'contacts_list_id']);
+ $table->timestamps();
+ });
+ }
+
+ public function down()
+ {
+ Schema::dropIfExists('account_contacts_list');
+ Schema::dropIfExists('contacts_list_contact');
+ Schema::dropIfExists('contacts_lists');
+ }
+};
diff --git a/flexiapi/public/css/far.css b/flexiapi/public/css/far.css
index cf6c1a6..99eaa14 100644
--- a/flexiapi/public/css/far.css
+++ b/flexiapi/public/css/far.css
@@ -96,11 +96,26 @@ body.show_menu {
}
p,
-a {
+a,
+ul li,
+pre {
font-size: 1.5rem;
color: var(--second-7);
}
+ul li {
+ margin-left: 2rem;
+ list-style-type: disc;
+}
+
+ul li ul li {
+ list-style-type: circle;
+}
+
+ul li ul li ul li {
+ list-style-type: square;
+}
+
p {
margin-bottom: 1rem;
}
@@ -114,7 +129,13 @@ p i {
margin-right: 1rem;
}
+code {
+ color: var(--second-6);
+ font-family: monospace;
+}
+
p>a:not(.btn),
+table tr td a:hover,
label>a {
text-decoration: underline;
color: var(--main-5);
@@ -134,6 +155,20 @@ body.welcome content {
max-width: 1024px;
}
+hr {
+ border-bottom: 1px solid var(--grey-3);
+ margin: 2rem 0;
+}
+
+hr.clear {
+ clear: both;
+ border-bottom: none;
+}
+
+a.permalink {
+ margin-left: 1rem;
+}
+
/** Tabs **/
ul.tabs {
@@ -148,6 +183,7 @@ ul.tabs li {
font-weight: 800;
color: var(--main-6);
border-bottom: 2px solid transparent;
+ list-style-type: none;
line-height: 4rem;
font-size: 3rem;
margin: 0 1rem;
@@ -238,7 +274,7 @@ header nav a#logo span {
header nav a#logo {
position: absolute;
left: calc(50% - 1.5rem);
- top: 0.75rem;
+ top: 1.5rem;
padding: 0;
}
}
@@ -275,6 +311,25 @@ content section {
box-sizing: border-box;
}
+content section header {
+ display: flex;
+ gap: 1rem;
+ align-items: center;
+ margin-bottom: 1rem;
+}
+
+content section header p {
+ margin-bottom: 0;
+}
+
+content section header form {
+ display: inline-block;
+}
+
+content section header > *.oppose {
+ margin-left: auto;
+}
+
content nav + section {
min-width: calc(80% - 20rem);
}
@@ -309,6 +364,33 @@ content > nav a {
margin-left: 2rem;
padding-right: 2rem;
position: relative;
+ white-space: nowrap;
+}
+
+content > nav a.current {
+ background-color: white;
+ border-radius: 4rem;
+ color: var(--main-5);
+ box-shadow: 0 0 1rem rgba(0, 0, 0, 0.2);
+}
+
+content > nav a.current:after {
+ content: '';
+ display: block;
+ width: 1rem;
+ height: 1rem;
+ background-color: white;
+ border-radius: 1rem;
+ position: absolute;
+ left: -2rem;
+ top: calc(50% - 0.5rem);
+ box-shadow: 0 0 1rem rgba(0, 0, 0, 0.2);
+}
+
+content > nav a i {
+ margin: 0 1rem;
+ margin-left: 2rem;
+ font-size: 2rem;
}
@media screen and (max-width: 800px) {
@@ -326,37 +408,19 @@ content > nav a {
transform: translateX(-100%);
}
+ content > nav a {
+ margin-left: 0;
+ }
+
+ content > nav a.current:after {
+ display: none;
+ }
+
body.show_menu content > nav {
transform: translateX(0);
}
}
-content > nav a.current {
- background-color: white;
- border-radius: 4rem;
- color: var(--main-5);
- box-shadow: 0 0 1rem rgba(0, 0, 0, 0.2);
-}
-
-content > nav a.current:before {
- content: '';
- display: block;
- width: 1rem;
- height: 1rem;
- background-color: white;
- border-radius: 1rem;
- position: absolute;
- left: -2rem;
- top: 50% - 0.5rem;
- box-shadow: 0 0 1rem rgba(0, 0, 0, 0.2);
-}
-
-content > nav a i {
- margin: 0 1rem;
- margin-left: 2rem;
- font-size: 2rem;
-}
-
/** Footer **/
body.welcome::after {
@@ -378,7 +442,6 @@ h1 {
line-height: 4rem;
font-weight: 800;
color: var(--second-6);
- margin-bottom: 1rem;
display: flex;
align-items: center;
margin-right: 1rem;
@@ -401,6 +464,18 @@ h2 i {
margin-right: 1rem;
}
+h3 {
+ font-size: 1.75rem;
+ color: var(--second-6);
+ padding: 0.5rem 0;
+}
+
+h4 {
+ font-size: 1.6rem;
+ color: var(--second-9);
+ padding: 0.5rem 0;
+}
+
/** Badge **/
.badge {
@@ -420,13 +495,25 @@ table {
width: 100%;
}
+table tr td a {
+ display: block;
+}
+
table tr td,
-table tr th{
+table tr th {
line-height: 4rem;
- padding: 0 2rem;
+ padding: 0 1rem;
font-size: 1.5rem;
}
+table tr td.line,
+table tr th.line {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ max-width: 0;
+}
+
table tr th,
table tr th a {
text-transform: uppercase;
@@ -449,6 +536,29 @@ table tr:nth-child(2n) {
background-color: var(--grey-1);
}
+table tr.empty {
+ background-color: var(--grey-2);
+ text-align: center;
+ color: var(--second-4);
+}
+
+table tr.empty td {
+ font-size: 2rem;
+ padding-bottom: 9rem;
+}
+
+table tr.empty td:before {
+ content: '\e5c9';
+ font-family: 'Material Icons';
+ font-size: 8rem;
+ color: var(--second-4);
+ display: block;
+ text-align: center;
+ margin: 12rem;
+ margin-bottom: 1rem;
+ line-height: 8rem;
+}
+
/* Display/hide */
.on_mobile {
@@ -476,6 +586,21 @@ table tr:nth-child(2n) {
}
}
+/** Chips **/
+
+.chip {
+ display: inline-block;
+ background-color: var(--grey-1);
+ border: 1px solid var(--grey-2);
+ border-radius: 3rem;
+ line-height: 2.5rem;
+ padding: 0 1rem;
+}
+
+.chip i {
+ margin: 0;
+}
+
/** Pagination **/
ul.pagination {
@@ -517,3 +642,9 @@ ul.pagination li:not(.disabled):not(.active) .page-link:hover {
ul.pagination li:not(.disabled) .page-link:hover {
border-color: var(--main-5);
}
+
+/** List Toggle */
+
+select.list_toggle {
+ display: none;
+}
\ No newline at end of file
diff --git a/flexiapi/public/css/form.css b/flexiapi/public/css/form.css
index 21107c6..42956d5 100644
--- a/flexiapi/public/css/form.css
+++ b/flexiapi/public/css/form.css
@@ -10,7 +10,7 @@
line-height: 2rem;
padding: 1rem 2rem;
color: white;
- margin: 0 1rem;
+ white-space: nowrap;
}
.btn i {
@@ -58,10 +58,24 @@
color: white;
}
+.btn.btn-tertiary {
+ background-color: var(--main-1);
+ border-color: transparent;
+ color: var(--main-5);
+}
+
+.btn.btn-tertiary:hover {
+ background-color: var(--main-2);
+}
+
+.btn.btn-tertiary:active {
+ background-color: var(--main-3);
+}
+
form {
display: grid;
grid-template-columns: repeat(2, 1fr);
- gap: 1.5rem 0.5rem;
+ gap: 1.5rem 2.5rem;
}
form.inline {
@@ -85,6 +99,12 @@ form h2 {
grid-column: 1/-1;
}
+form .disabled {
+ opacity: 0.5;
+ pointer-events: none;
+ filter: blur(0.25rem);
+}
+
@media screen and (max-width: 1024px) {
form div {
grid-column: 1/-1;
@@ -110,6 +130,7 @@ form input[required]+label:after {
}
form input:not([type=checkbox]) ~ label,
+form textarea ~ label,
form select ~ label {
position: absolute;
top: 0;
@@ -127,12 +148,14 @@ form div .btn.oppose {
}
form div input,
+form div textarea,
form div select {
padding: 1rem 2rem;
background-color: var(--grey-1);
border-radius: 3rem;
border: 1px solid var(--grey-2);
font-size: 1.5rem;
+ resize: vertical;
}
form div select {
@@ -158,19 +181,24 @@ form div.select:after {
line-height: 4rem;
}
-form div input[disabled] {
+form div input[disabled],
+form div textarea[disabled] {
border-color: var(--grey-4);
color: var(--grey-4);
background-color: var(--grey-2);
pointer-events: none;
}
-form div input[type=checkbox] {
- margin-right: 1rem;
+input[type=checkbox] {
accent-color: var(--main-5);
}
+form div input[type=checkbox] {
+ margin-right: 1rem;
+}
+
form div input:not([type=checkbox]):not([type=radio]):not(.btn),
+form div textarea,
form div select {
margin-top: 2.5rem;
box-sizing: border-box;
@@ -193,24 +221,33 @@ form div input:autofill {
}
form div input:hover,
+form div textarea:hover,
form div select:hover {
border-color: var(--second-4);
}
-form div input:focus-visible, form div input:active {
+form div input:focus-visible,
+form div input:active,
+form div textarea:focus-visible,
+form div textarea:active {
color: var(--main-5);
border-color: var(--main-5);
}
-form div input:focus-visible+label, form div input:active+label {
+form div input:focus-visible+label,
+form div input:active+label,
+form div textarea:focus-visible+label,
+form div textarea:active+label {
color: var(--main-5);
}
-form div input:invalid {
+form div input:invalid,
+form div textarea:invalid {
border-color: var(--danger-6);
color: var(--danger-5);
}
-form div input:invalid+label {
+form div input:invalid+label,
+form div textarea:invalid+label {
color: var(--danger-5);
}
\ No newline at end of file
diff --git a/flexiapi/resources/views/account/dashboard.blade.php b/flexiapi/resources/views/account/dashboard.blade.php
index 0806227..b5339ac 100644
--- a/flexiapi/resources/views/account/dashboard.blade.php
+++ b/flexiapi/resources/views/account/dashboard.blade.php
@@ -1,94 +1,93 @@
@extends('layouts.main')
@section('content')
+
-dashboard Dashboard
-
- email
- @if (!empty($account->email))
- {{ $account->email }}
- @else
- No email yet
+
+ email
+ @if (!empty($account->email))
+ {{ $account->email }}
+ @else
+ No email yet
+ @endif
+ Change my current account email
+
+
+
+ call
+ @if (!empty($account->phone))
+ {{ $account->phone }}
+ @else
+ No phone yet
+ @endif
+ Change my current account phone
+
+ @if (config('app.devices_management') == true)
+
+ laptop
+ Manage my devices
+
@endif
- Change my current account email
-
+
+ lock
+
+ @if ($account->passwords()->count() > 0)
+ Change my password
+ @else
+ Set my password
+ @endif
+
+
+
-
- call
- @if (!empty($account->phone))
- {{ $account->phone }}
- @else
- No phone yet
+
+ delete
+ Delete my account
+
+
+ person Account information
+
+ alternate_email SIP address: sip:{{ $account->identifier }}
+ person Username: {{ $account->username }}
+ dns Domain: {{ $account->domain }}
+
+ @if (!empty(config('app.proxy_registrar_address')))
+ lan Proxy/registrar address: sip:{{ config('app.proxy_registrar_address') }}
@endif
- Change my current account phone
-
-@if (config('app.devices_management') == true)
-
- laptop
- Manage my devices
-
-@endif
-
- lock
-
- @if ($account->passwords()->count() > 0)
- Change my password
- @else
- Set my password
+ @if (!empty(config('app.transport_protocol_text')))
+ settings_ethernet Transport: {{ config('app.transport_protocol_text') }}
@endif
-
-
-
-
- delete
- Delete my account
-
+
+ {!! Form::open(['route' => 'account.auth_tokens.create']) !!}
+
+ {!! Form::close() !!}-->
-keyAPI Key
+ keyAPI Key
-You can generate an API key and use it to request the different API endpoints, check the related API documentation to know how to use that key.
+ You can generate an API key and use it to request the different API endpoints, check
+ the related API documentation to know how to use that key.
-{!! Form::open(['route' => 'account.api_key.generate']) !!}
+ {!! Form::open(['route' => 'account.api_key.generate']) !!}
apiKey)
- value="{{ $account->apiKey->key }}"
- @endif
- >
+ @if ($account->apiKey) value="{{ $account->apiKey->key }}" @endif>
-{!! Form::close() !!}
+ {!! Form::close() !!}
-@include('parts.account_variables', ['account' => $account])
-
-@endsection
\ No newline at end of file
+ @include('parts.account_variables', ['account' => $account])
+@endsection
diff --git a/flexiapi/resources/views/account/devices/index.blade.php b/flexiapi/resources/views/account/devices/index.blade.php
index 9834e79..645e90a 100644
--- a/flexiapi/resources/views/account/devices/index.blade.php
+++ b/flexiapi/resources/views/account/devices/index.blade.php
@@ -6,11 +6,11 @@
@section('content')
-
+
- | User Agent |
- |
+ User Agent |
+ |
diff --git a/flexiapi/resources/views/admin/account/account_type/create.blade.php b/flexiapi/resources/views/admin/account/account_type/create.blade.php
index 1602c3f..c93daf5 100644
--- a/flexiapi/resources/views/admin/account/account_type/create.blade.php
+++ b/flexiapi/resources/views/admin/account/account_type/create.blade.php
@@ -5,7 +5,7 @@
Accounts
- {{ $account->identifier }}
+ {{ $account->identifier }}
Types
@@ -17,9 +17,9 @@
Add a Type to the Account
@if ($account_types->count() == 0)
-
+
No Account Type to add
-
+
@else
{!! Form::model($account, [
diff --git a/flexiapi/resources/views/admin/account/action/create_edit.blade.php b/flexiapi/resources/views/admin/account/action/create_edit.blade.php
index b5a1342..dcf67a6 100644
--- a/flexiapi/resources/views/admin/account/action/create_edit.blade.php
+++ b/flexiapi/resources/views/admin/account/action/create_edit.blade.php
@@ -5,7 +5,7 @@
Accounts
- {{ $account->identifier }}
+ {{ $account->identifier }}
Actions
diff --git a/flexiapi/resources/views/admin/account/action/delete.blade.php b/flexiapi/resources/views/admin/account/action/delete.blade.php
index 3dbe64e..72fefa0 100644
--- a/flexiapi/resources/views/admin/account/action/delete.blade.php
+++ b/flexiapi/resources/views/admin/account/action/delete.blade.php
@@ -5,7 +5,7 @@
Accounts
- {{ $action->account->identifier }}
+ {{ $action->account->identifier }}
Actions
diff --git a/flexiapi/resources/views/admin/account/contact/create.blade.php b/flexiapi/resources/views/admin/account/contact/create.blade.php
index a53bb79..c1ee14d 100644
--- a/flexiapi/resources/views/admin/account/contact/create.blade.php
+++ b/flexiapi/resources/views/admin/account/contact/create.blade.php
@@ -1,33 +1,17 @@
@extends('layouts.main')
-@section('breadcrumb')
-
- Accounts
-
-
- {{ $account->identifier }}
-
-
- Contacts
-
-@endsection
-
@section('content')
+ Add a Contact to the Account
-Add a Contact to the Account
-
-{!! Form::model($account, [
- 'route' => ['admin.account.contact.store', $account->id],
- 'method' => 'post'
-]) !!}
-