Skip to content

Commit

Permalink
Merge pull request rrze-mmz#186 from rrze-mmz/40-dashboard-shows-all-…
Browse files Browse the repository at this point in the history
…user-series-not-just-current-semester-ones

Fetch only current semester series in dashboard
  • Loading branch information
stefanosgeo authored Nov 26, 2024
2 parents a35fabb + a306fd2 commit 8e4725f
Show file tree
Hide file tree
Showing 8 changed files with 162 additions and 184 deletions.
18 changes: 6 additions & 12 deletions app/Http/Controllers/Backend/DashboardController.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,18 +86,12 @@ public function __invoke(OpencastService $opencastService): Application|Factory|
$livestreams = Livestream::active()->orderBy('clip_id');

return view('backend.dashboard.index', [
'userSeries' => auth()->user()
->getAllSeries()
->with('owner')
->withLastPublicClip()
->CurrentSemester()
->orderBy('title')
->paginate(12),
'userClips' => auth()->user()->clips()
->whereNull('series_id')
->orderByDesc('updated_at')
->limit(12)
->get(),
'userSeriesCounter' => auth()->user()
->getAllSeries()->currentSemester()->count(),
'userClipsCounter' => auth()->user()->clips()
->single()
->currentSemester()
->count(),
'files' => fetchDropZoneFiles(false),
'opencastEvents' => $opencastEvents,
'opencastSettings' => $opencastSettings->data,
Expand Down
248 changes: 104 additions & 144 deletions app/Livewire/IndexPagesDatatable.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ class IndexPagesDatatable extends Component

public function sortBy($field): void
{
$this->sortAsc = ! ($this->sortField === $field) || ! $this->sortAsc;

$this->sortAsc = ($this->sortField !== $field) || ! $this->sortAsc;
$this->sortField = $field;
}

Expand All @@ -44,7 +43,7 @@ public function updatingSearch(): void
public function render()
{
$search = trim(Str::lower($this->search));
$objects = $this->determineClipQuery($search)->paginate(20);
$objects = $this->determineQuery($search)->paginate(20);

return view('livewire.index-pages-datatable', [
'type' => $this->type,
Expand All @@ -54,148 +53,109 @@ public function render()
]);
}

protected function determineClipQuery($search)
protected function determineQuery($search)
{
switch ($this->type) {
case 'series':
return $this->querySeries($search);
case 'clips':
return $this->queryClips($search);
case 'organization':
return $this->queryOrganization($search);
default:
return collect(); // Return empty collection as fallback
}
}

protected function querySeries($search)
{
$query = Series::query()->with(['presenters'])->withLastPublicClip();

if ($this->actionButton === 'dashboard') {
$query = $this->userSeriesQuery(query: $query, currentSemester: true);
} elseif ($this->actionButton === 'assignClip' && ! $this->isAdmin()) {
$query = $this->userSeriesQuery($query);
} else {
$query->isPublic()->whereHas('clips.assets');
}

return $this->applySearchFilter($query, $search)->orderBy('id', 'desc');
}

protected function queryClips($search)
{
$query = Clip::query()->with(['presenters'])->Public();

if ($this->actionButton === 'dashboard') {
return auth()->user()
->clips()
->single()
->with(['presenters'])
->currentSemester();
}
if ($this->singleClips) {
$query->Single();
}

return $this->applySearchFilter($query, $search)->orderBy('updated_at', 'desc');
}

protected function queryOrganization($search)
{
$string = Str::substr($this->organization->orgno, 0, 2);

$query = Series::whereHas('organization', function ($q) use ($string) {
$q->whereRaw('orgno like ?', ["{$string}%"]);
})->with(['presenters'])
->withLastPublicClip()
->isPublic()
->whereHas('clips.assets');

return $this->applySearchFilter($query, $search)->orderBy('id', 'desc');
}

protected function userSeriesQuery($query, $currentSemester = false)
{
if ($this->type === 'series') {
//if it is a lecturer fetch all user series to assign them to a clip
if ($this->actionButton === 'assignClip' && ! auth()->user()->isAdmin()) {
if (auth()->user()->isAdmin()) {
return Series::query()
->with(['presenters'])
->withLastPublicClip()
->where(function ($q) use ($search) {
$search = strtolower($search);
$q->where('id', (int) $search)
->orWhereRaw('lower(title) like ?', ["%{$search}%"])
->orWhereHas('presenters', function ($q) use ($search) {
if (DB::getDriverName() === 'pgsql' || DB::getDriverName() === 'sqlite') {
// PostgresSQL concatenation using "||"
$q->whereRaw('lower(first_name) like ?', ["%{$search}%"])
->orWhereRaw('lower(last_name) like ?', ["%{$search}%"])
->orWhereRaw('lower(first_name || \' \' || last_name) like ?', ["%{$search}%"])
->orWhereRaw('lower(last_name || \' \' || first_name) like ?', ["%{$search}%"]);
} else {
// MySQL or others using CONCAT()
$q->whereRaw('lower(first_name) like ?', ["%{$search}%"])
->orWhereRaw('lower(last_name) like ?', ["%{$search}%"])
->orWhereRaw('lower(CONCAT(first_name, " ", last_name)) like ?', ["%{$search}%"])
->orWhereRaw('lower(CONCAT(last_name, " ", first_name)) like ?', ["%{$search}%"]);
}
});
})
->orderBy('id', 'desc');
} else {
return auth()->user()->accessableSeries()->with(['presenters'])
->withLastPublicClip()
->where(function ($q) use ($search) {
$search = strtolower($search);
$q->where('id', (int) $search)
->orWhereRaw('lower(title) like ?', ["%{$search}%"])
->orWhereHas('presenters', function ($q) use ($search) {
if (DB::getDriverName() === 'pgsql' || DB::getDriverName() === 'sqlite') {
// PostgresSQL concatenation using "||"
$q->whereRaw('lower(first_name) like ?', ["%{$search}%"])
->orWhereRaw('lower(last_name) like ?', ["%{$search}%"])
->orWhereRaw('lower(first_name || \' \' || last_name) like ?', ["%{$search}%"])
->orWhereRaw('lower(last_name || \' \' || first_name) like ?', ["%{$search}%"]);
} else {
// MySQL or others using CONCAT()
$q->whereRaw('lower(first_name) like ?', ["%{$search}%"])
->orWhereRaw('lower(last_name) like ?', ["%{$search}%"])
->orWhereRaw('lower(CONCAT(first_name, " ", last_name)) like ?', ["%{$search}%"])
->orWhereRaw('lower(CONCAT(last_name, " ", first_name)) like ?', ["%{$search}%"]);
}
});
})
->orderBy('id', 'desc');
}
} else {
return Series::query()
->with(['presenters'])
->withLastPublicClip()
->isPublic()
->whereHas('clips.assets')
->where(function ($q) use ($search) {
$search = strtolower($search);
$q->where('id', (int) $search)
->orWhereRaw('lower(title) like ?', ["%{$search}%"])
->orWhereHas('presenters', function ($q) use ($search) {
if (DB::getDriverName() === 'pgsql' || DB::getDriverName() === 'sqlite') {
// PostgresSQL concatenation using "||"
$q->whereRaw('lower(first_name) like ?', ["%{$search}%"])
->orWhereRaw('lower(last_name) like ?', ["%{$search}%"])
->orWhereRaw('lower(first_name || \' \' || last_name) like ?', ["%{$search}%"])
->orWhereRaw('lower(last_name || \' \' || first_name) like ?', ["%{$search}%"]);
} else {
// MySQL or others using CONCAT()
$q->whereRaw('lower(first_name) like ?', ["%{$search}%"])
->orWhereRaw('lower(last_name) like ?', ["%{$search}%"])
->orWhereRaw('lower(CONCAT(first_name, " ", last_name)) like ?', ["%{$search}%"])
->orWhereRaw('lower(CONCAT(last_name, " ", first_name)) like ?', ["%{$search}%"]);
}
});
})
->orderBy('id', 'desc');
}

} elseif ($this->type === 'clips') {
$query = Clip::query();
if ($this->singleClips) {
$query->Single();
}

return $query->with(['presenters'])
->Public()
->where(function ($q) use ($search) {
$search = strtolower($search);
$q->where('id', (int) $search)
->orWhereRaw('lower(title) like ?', ["%{$search}%"])
->orWhereHas('presenters', function ($q) use ($search) {
if (DB::getDriverName() === 'pgsql' || DB::getDriverName() === 'sqlite') {
// PostgresSQL concatenation using "||"
$q->whereRaw('lower(first_name) like ?', ["%{$search}%"])
->orWhereRaw('lower(last_name) like ?', ["%{$search}%"])
->orWhereRaw('lower(first_name || \' \' || last_name) like ?', ["%{$search}%"])
->orWhereRaw('lower(last_name || \' \' || first_name) like ?', ["%{$search}%"]);
} else {
// MySQL or others using CONCAT()
$q->whereRaw('lower(first_name) like ?', ["%{$search}%"])
->orWhereRaw('lower(last_name) like ?', ["%{$search}%"])
->orWhereRaw('lower(CONCAT(first_name, " ", last_name)) like ?', ["%{$search}%"])
->orWhereRaw('lower(CONCAT(last_name, " ", first_name)) like ?', ["%{$search}%"]);
}
});
})
->orderBy('updated_at', 'desc');
} elseif ($this->type === 'organization') {
return Series::whereHas('organization', function ($q) {
$string = Str::substr($this->organization->orgno, 0, 2);
$q->whereRaw('orgno like (?)', ["{$string}%"]);
})->with(['presenters'])
->withLastPublicClip()
->isPublic()
->whereHas('clips.assets')
->where(function ($q) use ($search) {
$search = strtolower($search);
$q->where('id', (int) $search)
->orWhereRaw('lower(title) like ?', ["%{$search}%"])
->orWhereHas('presenters', function ($q) use ($search) {
if (DB::getDriverName() === 'pgsql' || DB::getDriverName() === 'sqlite') {
// PostgresSQL concatenation using "||"
$q->whereRaw('lower(first_name) like ?', ["%{$search}%"])
->orWhereRaw('lower(last_name) like ?', ["%{$search}%"])
->orWhereRaw('lower(first_name || \' \' || last_name) like ?', ["%{$search}%"])
->orWhereRaw('lower(last_name || \' \' || first_name) like ?', ["%{$search}%"]);
} else {
// MySQL or others using CONCAT()
$q->whereRaw('lower(first_name) like ?', ["%{$search}%"])
->orWhereRaw('lower(last_name) like ?', ["%{$search}%"])
->orWhereRaw('lower(CONCAT(first_name, " ", last_name)) like ?', ["%{$search}%"])
->orWhereRaw('lower(CONCAT(last_name, " ", first_name)) like ?', ["%{$search}%"]);
}
});
})
->orderBy('id', 'desc');
if ($currentSemester) {
return auth()->user()->getAllSeries()->with(['presenters'])
->withLastPublicClip()->currentSemester();
}

if ($this->isAdmin()) {
return $query;
}

return auth()->user()->getAllSeries()->with(['presenters'])->withLastPublicClip();
}

protected function applySearchFilter($query, $search)
{
return $query->where(function ($q) use ($search) {
$q->where('id', (int) $search)
->orWhereRaw('lower(title) like ?', ["%{$search}%"])
->orWhereHas('presenters', function ($q) use ($search) {
$this->applyPresenterSearchFilter($q, $search);
});
});
}

protected function applyPresenterSearchFilter($query, $search)
{
if (DB::getDriverName() === 'pgsql' || DB::getDriverName() === 'sqlite') {
$query->whereRaw('lower(first_name) like ?', ["%{$search}%"])
->orWhereRaw('lower(last_name) like ?', ["%{$search}%"])
->orWhereRaw('lower(first_name || \' \' || last_name) like ?', ["%{$search}%"])
->orWhereRaw('lower(last_name || \' \' || first_name) like ?', ["%{$search}%"]);
} else {
$query->whereRaw('lower(first_name) like ?', ["%{$search}%"])
->orWhereRaw('lower(last_name) like ?', ["%{$search}%"])
->orWhereRaw('lower(CONCAT(first_name, " ", last_name)) like ?', ["%{$search}%"])
->orWhereRaw('lower(CONCAT(last_name, " ", first_name)) like ?', ["%{$search}%"]);
}
}

protected function isAdmin()
{
return auth()->user()->isAdmin();
}
}
10 changes: 7 additions & 3 deletions app/Models/Clip.php
Original file line number Diff line number Diff line change
Expand Up @@ -394,9 +394,6 @@ public function scopeSingle($query): mixed
return $query->whereNull('series_id');
}

/**
* Scope a query to only include the semester name of the clip
*/
public function scopeWithSemester($query)
{
return $query->addSelect(
Expand All @@ -408,6 +405,13 @@ public function scopeWithSemester($query)
);
}

public function scopeCurrentSemester($query)
{
return $query->whereHas('semester', function ($q) {
$q->current();
});
}

protected function title(): Attribute
{
return Attribute::make(
Expand Down
20 changes: 15 additions & 5 deletions app/Models/Series.php
Original file line number Diff line number Diff line change
Expand Up @@ -308,11 +308,21 @@ public function scopeHasClipsWithAssets($query): mixed

public function scopeCurrentSemester($query): mixed
{
return $query->whereHas('clips', function ($q) {
$q->whereHas('semester', function ($q) {
$q->current();
});
})->orWhere('owner_id', auth()->user()?->id);
return $query->where(function ($query) {
// Include VideoSeries that have clips within the current semester
$query->whereHas('clips', function ($q) {
$q->whereHas('semester', function ($q) {
$q->current();
});
})
// OR include VideoSeries without clips but created during the current semester
->orWhere(function ($q) {
$currentSemester = Semester::current()->first(); // Get the current semester
if ($currentSemester) {
$q->whereBetween('created_at', [$currentSemester->start_date, $currentSemester->stop_date]);
}
});
});
}

public function scopeHasOpencastSeriesID($query): mixed
Expand Down
2 changes: 1 addition & 1 deletion app/Models/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ public function memberships(): BelongsToMany

public function getAllSeries(): Builder|Series
{
return Series::select('id', 'slug', 'title', 'updated_at', 'owner_id', 'organization_id')
return Series::select('id', 'slug', 'title', 'updated_at', 'owner_id', 'organization_id', 'created_at')
->whereHas('clips', function ($q) {
$q->where('supervisor_id', $this->id);
})
Expand Down
Loading

0 comments on commit 8e4725f

Please sign in to comment.