diff --git a/CHANGELOG.md b/CHANGELOG.md
index c6ec5c8..c03c76a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/).
+## [2.1]
+
+### Changed
+
+- **Contacts Lists** The Contacts Lists are now handled per Space. During the migration, if there is only one Space present, existing Contacts Lists are automatically attached to it, otherwise the first Super Space available is used. If they are then attached to the wrong Space you'll have to change directly their `space_id` value in the `contacts_lists` database table.
+
## [2.0]
### Added
diff --git a/flexiapi/app/ContactsList.php b/flexiapi/app/ContactsList.php
index a1f3c61..0d7b46c 100644
--- a/flexiapi/app/ContactsList.php
+++ b/flexiapi/app/ContactsList.php
@@ -15,4 +15,9 @@ class ContactsList extends Model
{
return $this->belongsToMany(Account::class, 'contacts_list_contact', 'contacts_list_id', 'contact_id');
}
+
+ public function space()
+ {
+ return $this->belongsTo(Space::class);
+ }
}
diff --git a/flexiapi/app/Http/Controllers/Admin/ContactsListContactController.php b/flexiapi/app/Http/Controllers/Admin/Space/ContactsListContactController.php
similarity index 65%
rename from flexiapi/app/Http/Controllers/Admin/ContactsListContactController.php
rename to flexiapi/app/Http/Controllers/Admin/Space/ContactsListContactController.php
index 5d1fb7a..eaa7d6d 100644
--- a/flexiapi/app/Http/Controllers/Admin/ContactsListContactController.php
+++ b/flexiapi/app/Http/Controllers/Admin/Space/ContactsListContactController.php
@@ -17,18 +17,19 @@
along with this program. If not, see .
*/
-namespace App\Http\Controllers\Admin;
+namespace App\Http\Controllers\Admin\Space;
use App\Account;
use App\ContactsList;
+use App\Space;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
class ContactsListContactController extends Controller
{
- public function add(Request $request, int $contactsListId)
+ public function add(Request $request, Space $space, int $contactsListId)
{
- $accounts = Account::orderBy('updated_at', $request->get('updated_at_order', 'desc'));
+ $accounts = $space->accounts()->orderBy('updated_at', $request->get('updated_at_order', 'desc'));
if ($request->has('search')) {
$accounts = $accounts->where('username', 'like', '%' . $request->get('search') . '%');
@@ -38,9 +39,9 @@ class ContactsListContactController extends Controller
$accounts = $accounts->where('domain', $request->get('domain'));
}
- return view('admin.contacts_list.contacts.add', [
- 'domains' => Account::groupBy('domain')->pluck('domain'),
- 'contacts_list' => ContactsList::findOrFail($contactsListId),
+ return view('admin.space.contacts_list.contacts.add', [
+ 'space' => $space,
+ 'contacts_list' => $space->contactsLists()->findOrFail($contactsListId),
'params' => [
'contacts_list_id' => $contactsListId
],
@@ -52,33 +53,33 @@ class ContactsListContactController extends Controller
]);
}
- public function search(Request $request, int $contactsListId)
+ public function search(Request $request, Space $space, int $contactsListId)
{
- return redirect()->route('admin.contacts_lists.contacts.add', ['contacts_list_id' => $contactsListId] + $request->except('_token'));
+ return redirect()->route('admin.spaces.contacts_lists.contacts.add', ['contacts_list_id' => $contactsListId] + $request->except('_token'));
}
- public function store(Request $request, int $contactsListId)
+ public function store(Request $request, Space $space, int $contactsListId)
{
$request->validate([
'contacts_ids' => 'required|exists:accounts,id'
]);
- $contactsList = ContactsList::findOrFail($contactsListId);
+ $contactsList = $space->contactsLists()->findOrFail($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);
+ return redirect()->route('admin.spaces.contacts_lists.edit', [$space, $contactsList->id]);
}
- public function destroy(Request $request, int $contactsListId)
+ public function destroy(Request $request, Space $space, int $contactsListId)
{
$request->validate([
'contacts_ids' => 'required|exists:accounts,id'
]);
- $contactsList = ContactsList::findOrFail($contactsListId);
+ $contactsList = $space->contactsLists()->findOrFail($contactsListId);
$contactsList->contacts()->detach($request->get('contacts_ids'));
- return redirect()->route('admin.contacts_lists.edit', $contactsList->id);
+ return redirect()->route('admin.spaces.contacts_lists.edit', [$space, $contactsList->id]);
}
}
diff --git a/flexiapi/app/Http/Controllers/Admin/ContactsListController.php b/flexiapi/app/Http/Controllers/Admin/Space/ContactsListController.php
similarity index 57%
rename from flexiapi/app/Http/Controllers/Admin/ContactsListController.php
rename to flexiapi/app/Http/Controllers/Admin/Space/ContactsListController.php
index 4501c02..e834e90 100644
--- a/flexiapi/app/Http/Controllers/Admin/ContactsListController.php
+++ b/flexiapi/app/Http/Controllers/Admin/Space/ContactsListController.php
@@ -17,61 +17,67 @@
along with this program. If not, see .
*/
-namespace App\Http\Controllers\Admin;
+namespace App\Http\Controllers\Admin\Space;
use App\Account;
use App\ContactsList;
+use App\Space;
use App\Http\Controllers\Controller;
use Illuminate\Validation\Rule;
use Illuminate\Http\Request;
class ContactsListController extends Controller
{
- public function index(Request $request)
+ public function index(Request $request, Space $space)
{
$request->validate([
'order_by' => 'in:title,updated_at,contacts_count',
'order_sort' => 'in:asc,desc',
]);
- $contactsLists = ContactsList::orderBy($request->get('order_by', 'updated_at'), $request->get('order_sort', 'desc'));
+ $contactsLists = $space->contactsLists()->orderBy($request->get('order_by', 'updated_at'), $request->get('order_sort', 'desc'));
- return view('admin.contacts_list.index', [
+ return view('admin.space.contacts_list.index', [
+ 'space' => $space,
'contacts_lists' => $contactsLists
->paginate(20)
->appends($request->query()),
]);
}
- public function create(Request $request)
+ public function create(Request $request, Space $space)
{
- return view('admin.contacts_list.create_edit', [
+ return view('admin.space.contacts_list.create_edit', [
+ 'space' => $space,
'contacts_list' => new ContactsList,
]);
}
- public function store(Request $request)
+ public function store(Request $request, Space $space)
{
$request->validate([
'title' => 'required|unique:contacts_lists'
]);
$contactsList = new ContactsList;
+ $contactsList->space_id = $space->id;
$contactsList->title = $request->get('title');
$contactsList->description = $request->get('description');
$contactsList->save();
- return redirect()->route('admin.contacts_lists.edit', $contactsList->id);
+ return redirect()->route('admin.spaces.contacts_lists.edit', [$space, $contactsList->id]);
}
- public function search(Request $request, int $contactsListId)
+ public function search(Request $request, Space $space, int $contactsListId)
{
- return redirect()->route('admin.contacts_lists.edit', ['contacts_list_id' => $contactsListId] + $request->except('_token'));
+ return redirect()->route('admin.spaces.contacts_lists.edit', [
+ 'space' => $space,
+ 'contacts_list_id' => $contactsListId] + $request->except('_token'));
}
- public function edit(Request $request, int $id)
+ public function edit(Request $request, Space $space, int $id)
{
- $contacts = ContactsList::findOrFail($id)->contacts();
+ $contacts = $space->contactsLists()->findOrFail($id)->contacts();
if ($request->has('search')) {
$contacts = $contacts->where('username', 'like', '%' . $request->get('search') . '%');
@@ -83,14 +89,15 @@ class ContactsListController extends Controller
$contacts = $contacts->get();
- return view('admin.contacts_list.create_edit', [
+ return view('admin.space.contacts_list.create_edit', [
+ 'space' => $space,
'domains' => Account::groupBy('domain')->pluck('domain'),
- 'contacts_list' => ContactsList::findOrFail($id),
+ 'contacts_list' => $space->contactsLists()->findOrFail($id),
'contacts' => $contacts
]);
}
- public function update(Request $request, int $id)
+ public function update(Request $request, Space $space, int $id)
{
$request->validate([
'title' => [
@@ -99,26 +106,27 @@ class ContactsListController extends Controller
],
]);
- $contactsList = ContactsList::findOrFail($id);
+ $contactsList = $space->contactsLists()->findOrFail($id);
$contactsList->title = $request->get('title');
$contactsList->description = $request->get('description');
$contactsList->save();
- return redirect()->route('admin.contacts_lists.index');
+ return redirect()->route('admin.spaces.contacts_lists.index', $space);
}
- public function delete(int $id)
+ public function delete(Space $space, int $id)
{
- return view('admin.contacts_list.delete', [
- 'contacts_list' => ContactsList::findOrFail($id),
+ return view('admin.space.contacts_list.delete', [
+ 'space' => $space,
+ 'contacts_list' => $space->contactsLists()->findOrFail($id),
]);
}
- public function destroy(Request $request)
+ public function destroy(Request $request, Space $space)
{
- $contactsList = ContactsList::findOrFail($request->get('contacts_lists_id'));
+ $contactsList = $space->contactsLists()->findOrFail($request->get('contacts_lists_id'));
$contactsList->delete();
- return redirect()->route('admin.contacts_lists.index');
+ return redirect()->route('admin.spaces.contacts_lists.index', $space);
}
}
diff --git a/flexiapi/app/Http/Controllers/Api/Admin/ContactsListController.php b/flexiapi/app/Http/Controllers/Api/Admin/Space/ContactsListController.php
similarity index 74%
rename from flexiapi/app/Http/Controllers/Api/Admin/ContactsListController.php
rename to flexiapi/app/Http/Controllers/Api/Admin/Space/ContactsListController.php
index 5ebef03..bb0be59 100644
--- a/flexiapi/app/Http/Controllers/Api/Admin/ContactsListController.php
+++ b/flexiapi/app/Http/Controllers/Api/Admin/Space/ContactsListController.php
@@ -17,7 +17,7 @@
along with this program. If not, see .
*/
-namespace App\Http\Controllers\Api\Admin;
+namespace App\Http\Controllers\Api\Admin\Space;
use App\Account;
use App\ContactsList;
@@ -28,12 +28,12 @@ class ContactsListController extends Controller
{
public function index(Request $request)
{
- return ContactsList::all();
+ return $request->space->contactsLists;
}
- public function get(int $contactsListId)
+ public function get(Request $request, int $contactsListId)
{
- return ContactsList::findOrFail($contactsListId);
+ return $request->space->contactsLists()->findOrFail($contactsListId);
}
public function store(Request $request)
@@ -44,6 +44,7 @@ class ContactsListController extends Controller
]);
$contactsList = new ContactsList;
+ $contactsList->space_id = $request->space->id;
$contactsList->title = $request->get('title');
$contactsList->description = $request->get('description');
$contactsList->save();
@@ -59,6 +60,7 @@ class ContactsListController extends Controller
]);
$contactsList = ContactsList::findOrFail($contactsListId);
+ $contactsList->space_id = $request->space->id;
$contactsList->title = $request->get('title');
$contactsList->description = $request->get('description');
$contactsList->save();
@@ -66,15 +68,15 @@ class ContactsListController extends Controller
return $contactsList;
}
- public function destroy(int $contactsListId)
+ public function destroy(Request $request, int $contactsListId)
{
- return ContactsList::where('id', $contactsListId)
+ return $request->space->contactsLists()->where('id', $contactsListId)
->delete();
}
- public function contactAdd(int $id, int $contactId)
+ public function contactAdd(Request $request, int $id, int $contactId)
{
- $contactsList = ContactsList::findOrFail($id);
+ $contactsList = $request->space->contactsLists()->findOrFail($id);
$contactsList->contacts()->detach($contactId);
if (Account::findOrFail($contactId)) {
@@ -82,9 +84,9 @@ class ContactsListController extends Controller
}
}
- public function contactRemove(int $id, int $contactId)
+ public function contactRemove(Request $request, int $id, int $contactId)
{
- $contactsList = ContactsList::findOrFail($id);
+ $contactsList = $request->space->contactsLists()->findOrFail($id);
if (!$contactsList->contacts()->pluck('id')->contains($contactId)) {
abort(404);
diff --git a/flexiapi/app/Space.php b/flexiapi/app/Space.php
index 4e77c67..7b57473 100644
--- a/flexiapi/app/Space.php
+++ b/flexiapi/app/Space.php
@@ -102,6 +102,11 @@ class Space extends Model
return $this->hasMany(SpaceCardDavServer::class);
}
+ public function contactsLists()
+ {
+ return $this->hasMany(ContactsList::class);
+ }
+
public function scopeNotFull(Builder $query)
{
return $query->where('max_accounts', 0)
diff --git a/flexiapi/database/migrations/2025_10_09_135432_add_space_id_to_contacts_lists_table.php b/flexiapi/database/migrations/2025_10_09_135432_add_space_id_to_contacts_lists_table.php
new file mode 100644
index 0000000..846ec90
--- /dev/null
+++ b/flexiapi/database/migrations/2025_10_09_135432_add_space_id_to_contacts_lists_table.php
@@ -0,0 +1,47 @@
+first();
+
+ Schema::table('contacts_lists', function (Blueprint $table) use ($space) {
+ if ($space) {
+ $table->bigInteger('space_id')->unsigned()->default($space->id);
+ } else {
+ $table->bigInteger('space_id')->unsigned()->nullable();
+ }
+
+ $table->foreign('space_id')->references('id')
+ ->on('spaces')->onDelete('cascade');
+ });
+
+ Schema::table('contacts_lists', function (Blueprint $table) use ($space) {
+ $table->bigInteger('space_id')->unsigned()->change();
+ });
+
+ Schema::enableForeignKeyConstraints();
+ }
+
+ public function down(): void
+ {
+ Schema::table('contacts_lists', function (Blueprint $table) {
+ $table->dropForeign('contacts_lists_space_id_foreign');
+ $table->dropColumn('space_id');
+ });
+ }
+};
diff --git a/flexiapi/resources/views/admin/account/contact/index.blade.php b/flexiapi/resources/views/admin/account/contact/index.blade.php
index afad8f2..0fde1d3 100644
--- a/flexiapi/resources/views/admin/account/contact/index.blade.php
+++ b/flexiapi/resources/views/admin/account/contact/index.blade.php
@@ -49,7 +49,7 @@
@foreach ($account->contactsLists as $contactsList)
|
- {{ $contactsList->title }}
+ {{ $contactsList->title }}
{{ $contactsList->contacts_count }} {{ __('Contacts') }}
|
diff --git a/flexiapi/resources/views/admin/contacts_list/index.blade.php b/flexiapi/resources/views/admin/contacts_list/index.blade.php
deleted file mode 100644
index 21cbc48..0000000
--- a/flexiapi/resources/views/admin/contacts_list/index.blade.php
+++ /dev/null
@@ -1,45 +0,0 @@
-@extends('layouts.main')
-
-@section('content')
-
-
-
-
-
-
- @include('parts.column_sort', ['key' => 'title', 'title' => __('Name')])
- | {{ __('Description') }} |
- @include('parts.column_sort', ['key' => 'contacts_count', 'title' => __('Contacts')])
- @include('parts.column_sort', ['key' => 'updated_at', 'title' => __('Updated')])
-
-
-
- @if ($contacts_lists->isEmpty())
-
- | {{ __('Empty') }} |
-
- @endif
- @foreach ($contacts_lists as $contacts_list)
-
- |
-
- {{ $contacts_list->title }}
-
- |
- {{ $contacts_list->description }} |
- {{ $contacts_list->contacts_count }} |
- {{ $contacts_list->updated_at}} |
-
- @endforeach
-
-
-
-{{ $contacts_lists->links('pagination::bootstrap-4') }}
-
-@endsection
\ No newline at end of file
diff --git a/flexiapi/resources/views/admin/space/administration.blade.php b/flexiapi/resources/views/admin/space/administration.blade.php
index 40f131f..2c925a0 100644
--- a/flexiapi/resources/views/admin/space/administration.blade.php
+++ b/flexiapi/resources/views/admin/space/administration.blade.php
@@ -6,10 +6,7 @@
@endsection
@section('content')
-
-
+ @include('admin.space.head')
@include('admin.space.tabs')
|