Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wip: add sorting in dashboard. #964

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 13 additions & 6 deletions app/Http/Controllers/DashboardController.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,26 @@ public function dashboard(Request $request)
if ($team) {
$team->users = $team->allUsers();
if (! $team->personal_team) {
$projects = Project::with('users', 'owner')->where([['team_id', $team->id], ['is_deleted', false]])->orderBy('updated_at', 'DESC')->get();
$projects = Project::with('users', 'owner')->where([['team_id', $team->id], ['is_deleted', false]])
->when($request->input('sort'), function ($query, $sort) {
$query->sort(["{$sort}" => 'desc']);
}, function ($query) {
$query->sort(['updated_at' => 'desc']);
})->paginate(5)->withQueryString();
} else {
$projects = Project::with('users', 'owner')->where([['owner_id', $user->id], ['is_deleted', false]])
->where('team_id', $team->id)
->orderBy('updated_at', 'DESC')
->get();
$projects = Project::with('users', 'owner')->where([['owner_id', $user->id], ['is_deleted', false], ['team_id', $team->id]])
->when($request->input('sort'), function ($query, $sort) {
$query->sort(["{$sort}" => 'desc']);
}, function ($query) {
$query->sort(['updated_at' => 'desc']);
})->paginate(5)->withQueryString();
}
}

return Inertia::render('Dashboard', [
'filters' => $request->all('action', 'draft_id'),
'team' => $team,
'projects' => $projects->load('tags'),
'projects' => $projects,
'teamRole' => $user->teamRole($team),
]);
}
Expand Down
9 changes: 9 additions & 0 deletions app/Models/Project.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Notification;
use Lacodix\LaravelModelFilter\Traits\IsSortable;
use Laravel\Scout\Searchable;
use Maize\Markable\Markable;
use Maize\Markable\Models\Bookmark;
Expand All @@ -28,6 +29,7 @@ class Project extends Model implements Auditable
use HasDOI;
use HasFactory;
use HasTags;
use IsSortable;
use Markable;
use \OwenIt\Auditing\Auditable;
use Searchable;
Expand Down Expand Up @@ -56,6 +58,13 @@ class Project extends Model implements Auditable
'species',
];

protected array $sortable = [
'is_archived',
'status',
'created_at' => 'desc',
'updated_at',
];

protected static $marks = [
Like::class,
Bookmark::class,
Expand Down
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"http-interop/http-factory-guzzle": "^1.2",
"inertiajs/inertia-laravel": "^0.6.9",
"lab404/laravel-impersonate": "^1.7",
"lacodix/laravel-model-filter": "^1.11",
"larabug/larabug": "^3.0",
"laravel/framework": "^10.0",
"laravel/horizon": "^5.9",
Expand Down
80 changes: 80 additions & 0 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

131 changes: 122 additions & 9 deletions resources/js/Pages/Dashboard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,77 @@
</div>
</div>
</template>
<div v-if="projects.length > 0" class="px-12 py-8 mx-auto max-w-4xl">
<team-projects
:team="team"
:team-role="teamRole"
:mode="'create'"
:projects="projects"
></team-projects>
<div v-if="projects.data.length > 0">
<div
class="relative border-gray-200 pt-4 pb-4 pl-10 border-b mt-3 border-gray-100"
>
<div class="mx-auto flex items-left justify-between">
<Menu as="div" class="relative inline-block text-left">
<div>
<MenuButton
class="group inline-flex justify-center text-sm font-medium text-gray-700 hover:text-gray-900"
>
Sort by:&nbsp;<span
class="capitalize font-black text-gray-900"
>{{ sort.name }}</span
>
<ChevronDownIcon
class="flex-shrink-0 -mr-1 ml-1 h-5 w-5 text-gray-400 group-hover:text-gray-500"
aria-hidden="true"
/>
</MenuButton>
</div>

<transition
enter-active-class="transition ease-out duration-100"
enter-from-class="transform opacity-0 scale-95"
enter-to-class="transform opacity-100 scale-100"
leave-active-class="transition ease-in duration-75"
leave-from-class="transform opacity-100 scale-100"
leave-to-class="transform opacity-0 scale-95"
>
<MenuItems
class="origin-top-left absolute left-0 mt-2 w-40 rounded-md shadow-2xl bg-white ring-1 ring-black ring-opacity-5 focus:outline-none"
>
<div class="py-1">
<MenuItem
v-for="option in sortOptions"
:key="option.name"
v-slot="{ active }"
>
<a
:class="[
option.current
? 'font-medium text-gray-900'
: 'text-gray-500',
active ? 'bg-gray-100' : '',
'block px-4 py-2 text-sm cursor-pointer',
]"
@click="sort = option"
>
{{ option.name }}
</a>
</MenuItem>
</div>
</MenuItems>
</transition>
</Menu>
</div>
</div>
<div class="px-12 py-8 mx-auto max-w-4xl">
<team-projects
:team="team"
:team-role="teamRole"
:mode="'create'"
:projects="projects.data"
></team-projects>
</div>
<div
class="p-10 border-t border-gray-200"
v-if="projects.total > projects.per_page"
>
<Pagination :links="projects.links"></Pagination>
</div>
</div>
<div v-else>
<div class="max-w-lg my-6 py-6 mx-auto">
Expand Down Expand Up @@ -300,9 +364,20 @@ import Create from "@/Shared/CreateButton.vue";
import Onboarding from "@/App/Onboarding.vue";
import { useMagicKeys } from "@vueuse/core";
import { getCurrentInstance } from "vue";
import { watchEffect } from "vue";
import { watchEffect, watch } from "vue";
import { Link } from "@inertiajs/vue3";
import { computed } from "vue";
import { ChevronDownIcon } from "@heroicons/vue/24/solid";
import Pagination from "@/Shared/Pagination.vue";
import {
Menu,
MenuButton,
MenuItem,
MenuItems,
TransitionChild,
TransitionRoot,
} from "@headlessui/vue";
import { router } from "@inertiajs/vue3";

const { meta, u } = useMagicKeys();

Expand All @@ -314,8 +389,32 @@ export default {
Create,
Onboarding,
Link,
ChevronDownIcon,
Pagination,
Menu,
MenuItem,
MenuItems,
MenuButton,
TransitionChild,
TransitionRoot,
},
props: ["user", "team", "projects", "teamRole", "filters"],
data() {
return {
sortOptions: [
{ name: "Creation", value: "created_by", current: true },
{ name: "Last Updated", value: "updated_at", current: false },
{ name: "Status", value: "status", current: false },
{ name: "Archived", value: "is_archived", current: false },
{ name: "Visibility", value: "is_public", current: false },
],
sort: {
name: "Creation",
value: "created_by",
current: true,
},
};
},
setup() {
const app = getCurrentInstance();
const openDatasetCreateDialog = (data) => {
Expand All @@ -331,7 +430,6 @@ export default {
});
}
});

return {
openDatasetCreateDialog,
};
Expand All @@ -354,5 +452,20 @@ export default {
});
}
},
watch: {
sort: {
deep: true,
handler: (sort) => {
router.get(
"dashboard",
{ sort: sort.value },
{
preserveState: true,
replace: true,
}
);
},
},
},
};
</script>