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

Configured some columns for staff and client lists. #191

Merged
merged 5 commits into from
Dec 18, 2023
Merged
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
53 changes: 53 additions & 0 deletions app/Http/Controllers/Facility/ClientTqueryController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php

namespace App\Http\Controllers\Facility;

use App\Http\Controllers\ApiController;
use App\Http\Permissions\Permission;
use App\Http\Permissions\PermissionDescribe;
use App\Tquery\Engine\TqService;
use App\Tquery\OpenApi\OpenApiGet;
use App\Tquery\OpenApi\OpenApiPost;
use App\Tquery\Tables\ClientTquery;
use App\Utils\OpenApi\FacilityParameter;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\App;

class ClientTqueryController extends ApiController
{
protected function initPermissions(): void
{
$this->permissionOneOf(Permission::facilityAdmin);
}

private function getTqService(): TqService
{
return App::make(ClientTquery::class, ['facility' => $this->getFacilityOrFail()]);
}

#[OpenApiGet(
path: '/api/v1/facility/{facility}/user/client/tquery',
permissions: new PermissionDescribe(Permission::facilityAdmin),
summary: 'Facility clients tquery',
tag: 'Facility client',
parameters: [new FacilityParameter()],
)]
public function get(): JsonResponse
{
return new JsonResponse($this->getTqService()->getConfigArray());
}

#[OpenApiPost(
path: '/api/v1/facility/{facility}/user/client/tquery',
permissions: new PermissionDescribe(Permission::facilityAdmin),
summary: 'Facility clients tquery',
tag: 'Facility client',
parameters: [new FacilityParameter()],
)]
public function post(
Request $request,
): JsonResponse {
return new JsonResponse($this->getTqService()->query($request));
}
}
2 changes: 1 addition & 1 deletion app/Http/Controllers/Facility/MeetingTqueryController.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class MeetingTqueryController extends ApiController
{
protected function initPermissions(): void
{
$this->permissionOneOf(Permission::globalAdmin);
$this->permissionOneOf(Permission::facilityAdmin);
}

private function getTqService(): TqService
Expand Down
53 changes: 53 additions & 0 deletions app/Http/Controllers/Facility/StaffTqueryController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php

namespace App\Http\Controllers\Facility;

use App\Http\Controllers\ApiController;
use App\Http\Permissions\Permission;
use App\Http\Permissions\PermissionDescribe;
use App\Tquery\Engine\TqService;
use App\Tquery\OpenApi\OpenApiGet;
use App\Tquery\OpenApi\OpenApiPost;
use App\Tquery\Tables\StaffTquery;
use App\Utils\OpenApi\FacilityParameter;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\App;

class StaffTqueryController extends ApiController
{
protected function initPermissions(): void
{
$this->permissionOneOf(Permission::facilityAdmin);
}

private function getTqService(): TqService
{
return App::make(StaffTquery::class, ['facility' => $this->getFacilityOrFail()]);
}

#[OpenApiGet(
path: '/api/v1/facility/{facility}/user/staff/tquery',
permissions: new PermissionDescribe(Permission::facilityAdmin),
summary: 'Facility staff tquery',
tag: 'Facility staff',
parameters: [new FacilityParameter()],
)]
public function get(): JsonResponse
{
return new JsonResponse($this->getTqService()->getConfigArray());
}

#[OpenApiPost(
path: '/api/v1/facility/{facility}/user/staff/tquery',
permissions: new PermissionDescribe(Permission::facilityAdmin),
summary: 'Facility staff tquery',
tag: 'Facility staff',
parameters: [new FacilityParameter()],
)]
public function post(
Request $request,
): JsonResponse {
return new JsonResponse($this->getTqService()->query($request));
}
}
1 change: 0 additions & 1 deletion app/Tquery/Config/TqDataTypeEnum.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
use App\Rules\Valid;
use App\Rules\RegexpIsValidRule;
use App\Tquery\Filter\TqFilterOperator;
use App\Utils\Date\DateHelper;

enum TqDataTypeEnum
{
Expand Down
6 changes: 4 additions & 2 deletions app/Tquery/Config/TqTableAliasEnum.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,23 @@ enum TqTableAliasEnum
{
case created_by;
case last_login_facility;
case members;

public function baseTable(): TqTableEnum
{
return match ($this) {
self::created_by => TqTableEnum::users,
self::last_login_facility => TqTableEnum::facilities,
self::members => TqTableEnum::members,
};
}

public function applyJoin(TqBuilder $builder, TqTableEnum $joinBase, bool $left): void
{
$joinColumn = match ($this) {
self::created_by => $this->name,
self::last_login_facility => $this->name . '_id',
default => $this->name . '_id',
};
$builder->join($joinBase, $this, $joinColumn, $left);
$builder->join($joinBase, $this, $joinColumn, $left, false);
}
}
6 changes: 4 additions & 2 deletions app/Tquery/Engine/TqBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,19 @@ public function join(
TqTableAliasEnum $table,
string $joinColumn,
bool $left,
bool $inv,
): bool {
if (in_array($table, $this->joins, strict: true)) {
return false;
}
[$tableColumn, $baseColumn] = $inv ? [$joinColumn, 'id'] : ['id', $joinColumn];
$this->joins[] = $table;
$tableBase = $table->baseTable();
$this->builder->join(
"{$tableBase->name} as {$table->name}",
"{$table->name}.id",
"{$table->name}.$tableColumn",
'=',
"{$joinBase->name}.$joinColumn",
"{$joinBase->name}.$baseColumn",
$left ? 'left' : 'inner',
);
return true;
Expand Down
25 changes: 25 additions & 0 deletions app/Tquery/Tables/ClientTquery.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

namespace App\Tquery\Tables;

use App\Models\Facility;
use App\Tquery\Config\TqTableAliasEnum;
use App\Tquery\Config\TqTableEnum;
use App\Tquery\Engine\TqBuilder;

readonly class ClientTquery extends AdminUserTquery
{
public function __construct(private Facility $facility)
{
parent::__construct();
}

protected function getBuilder(): TqBuilder
{
$builder = TqBuilder::fromTable(TqTableEnum::users);
$builder->join(TqTableEnum::users, TqTableAliasEnum::members, 'user_id', left: false, inv: true);
$builder->where(fn(string $bind) => "members.facility_id = $bind", false, $this->facility->id, false, false);
$builder->where(fn(null $bind) => 'members.client_id is not null', false, null, false, false);
return $builder;
}
}
25 changes: 25 additions & 0 deletions app/Tquery/Tables/StaffTquery.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

namespace App\Tquery\Tables;

use App\Models\Facility;
use App\Tquery\Config\TqTableAliasEnum;
use App\Tquery\Config\TqTableEnum;
use App\Tquery\Engine\TqBuilder;

readonly class StaffTquery extends AdminUserTquery
{
public function __construct(private Facility $facility)
{
parent::__construct();
}

protected function getBuilder(): TqBuilder
{
$builder = TqBuilder::fromTable(TqTableEnum::users);
$builder->join(TqTableEnum::users, TqTableAliasEnum::members, 'user_id', left: false, inv: true);
$builder->where(fn(string $bind) => "members.facility_id = $bind", false, $this->facility->id, false, false);
$builder->where(fn(null $bind) => 'members.staff_member_id is not null', false, null, false, false);
return $builder;
}
}
6 changes: 4 additions & 2 deletions resources/js/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ const AdminFacilitiesListPage = lazy(() => import("features/root/pages/AdminFaci
const AdminUsersListPage = lazy(() => import("features/root/pages/AdminUsersList.page"));
const CalendarPage = lazy(() => import("features/root/pages/Calendar.page"));
const CalendarTablePage = lazy(() => import("features/root/pages/CalendarTable.page"));
const ClientsTablePage = lazy(() => import("features/root/pages/ClientsTable.page"));
const LoginPage = lazy(() => import("features/authentication/pages/Login.page"));
const RootPage = lazy(() => import("features/root/pages/Root.page"));
const StaffTablePage = lazy(() => import("features/root/pages/StaffTable.page"));

const App: VoidComponent = () => {
const facilitiesQuery = createQuery(System.facilitiesQueryOptions);
Expand Down Expand Up @@ -53,8 +55,8 @@ const App: VoidComponent = () => {
<UnknownNotFound />
<LeafRoute routeKey="facility.admin.calendar" path="/calendar" component={CalendarPage} />
<LeafRoute routeKey="facility.admin.calendar_table" path="/calendar-table" component={CalendarTablePage} />
<LeafRoute routeKey="facility.admin.clients" path="/clients" component={NotYetImplemented} />
<LeafRoute routeKey="facility.admin.staff" path="/staff" component={NotYetImplemented} />
<LeafRoute routeKey="facility.admin.staff" path="/staff" component={StaffTablePage} />
<LeafRoute routeKey="facility.admin.clients" path="/clients" component={ClientsTablePage} />
<LeafRoute routeKey="facility.admin.reports" path="/reports" component={NotYetImplemented} />
</Route>
</Route>
Expand Down
9 changes: 9 additions & 0 deletions resources/js/data-access/memo-api/groups/FacilityClient.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/**
* @see {@link https://test-memo.fdds.pl/api/documentation#/Facility%20client production docs}
* @see {@link http://localhost:9081/api/documentation#/Facility%20client local docs}
*/
export namespace FacilityClient {
export const keys = {
client: () => ["client"] as const,
};
}
9 changes: 9 additions & 0 deletions resources/js/data-access/memo-api/groups/FacilityStaff.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/**
* @see {@link https://test-memo.fdds.pl/api/documentation#/Facility%20staff production docs}
* @see {@link http://localhost:9081/api/documentation#/Facility%20staff local docs}
*/
export namespace FacilityStaff {
export const keys = {
staff: () => ["staff"] as const,
};
}
10 changes: 5 additions & 5 deletions resources/js/features/root/layout/Navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -91,16 +91,16 @@ function getSectionItems(
href: `/${facilityUrl}/admin/calendar`,
routeKey: "facility.admin.calendar",
},
{
icon: CLIENT_ICONS.menu,
href: `/${facilityUrl}/admin/clients`,
routeKey: "facility.admin.clients",
},
{
icon: STAFF_ICONS.menu,
href: `/${facilityUrl}/admin/staff`,
routeKey: "facility.admin.staff",
},
{
icon: CLIENT_ICONS.menu,
href: `/${facilityUrl}/admin/clients`,
routeKey: "facility.admin.clients",
},
{
icon: HiOutlineClipboardDocumentList,
href: `/${facilityUrl}/admin/reports`,
Expand Down
28 changes: 28 additions & 0 deletions resources/js/features/root/pages/ClientsTable.page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import {createTableTranslations} from "components/ui/Table";
import {TQueryTable} from "components/ui/Table/TQueryTable";
import {FacilityClient} from "data-access/memo-api/groups/FacilityClient";
import {VoidComponent} from "solid-js";
import {activeFacilityId} from "state/activeFacilityId.state";

export default (() => {
return (
<>
<TQueryTable
mode="standalone"
staticPrefixQueryKey={FacilityClient.keys.client()}
staticEntityURL={`facility/${activeFacilityId()}/user/client`}
staticTranslations={createTableTranslations("clients")}
staticPersistenceKey="facilityClients"
columns={[
{name: "id", initialVisible: false},
{name: "name", columnDef: {enableHiding: false}},
// {name: "genderDictId"},
{name: "createdAt", columnDef: {sortDescFirst: true}, initialVisible: false},
{name: "createdBy.name", initialVisible: false},
{name: "updatedAt", columnDef: {sortDescFirst: true}, initialVisible: false},
]}
initialSort={[{id: "name", desc: false}]}
/>
</>
);
}) satisfies VoidComponent;
40 changes: 40 additions & 0 deletions resources/js/features/root/pages/StaffTable.page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import {cellFunc, createTableTranslations} from "components/ui/Table";
import {TQueryTable} from "components/ui/Table/TQueryTable";
import {FacilityStaff} from "data-access/memo-api/groups/FacilityStaff";
import {VoidComponent} from "solid-js";
import {activeFacilityId} from "state/activeFacilityId.state";
import {Email} from "components/ui/Email";

export default (() => {
return (
<>
<TQueryTable
mode="standalone"
staticPrefixQueryKey={FacilityStaff.keys.staff()}
staticEntityURL={`facility/${activeFacilityId()}/user/staff`}
staticTranslations={createTableTranslations("staff")}
staticPersistenceKey="facilityStaff"
columns={[
{name: "id", initialVisible: false},
{name: "name", columnDef: {enableHiding: false}},
{name: "email", columnDef: {cell: cellFunc<string>((v) => <Email class="w-full" email={v} />)}},
{name: "hasEmailVerified", initialVisible: false},
{name: "hasPassword"},
{name: "passwordExpireAt", initialVisible: false},
{
name: "hasGlobalAdmin",
columnDef: {
cell: cellFunc<boolean>((adm) => <span class="w-full text-center">{adm ? "💪🏽" : ""}</span>),
size: 130,
},
initialVisible: false,
},
{name: "createdAt", columnDef: {sortDescFirst: true}, initialVisible: false},
{name: "createdBy.name", initialVisible: false},
{name: "updatedAt", columnDef: {sortDescFirst: true}, initialVisible: false},
]}
initialSort={[{id: "name", desc: false}]}
/>
</>
);
}) satisfies VoidComponent;
Loading