Add table to admin/UsersContainer.tsx
This commit is contained in:
parent
0ddf806100
commit
95c55e7d28
9 changed files with 223 additions and 22 deletions
|
@ -6,6 +6,7 @@ use Illuminate\Http\JsonResponse;
|
||||||
use Pterodactyl\Models\AdminRole;
|
use Pterodactyl\Models\AdminRole;
|
||||||
use Pterodactyl\Repositories\Eloquent\AdminRolesRepository;
|
use Pterodactyl\Repositories\Eloquent\AdminRolesRepository;
|
||||||
use Pterodactyl\Transformers\Api\Application\AdminRoleTransformer;
|
use Pterodactyl\Transformers\Api\Application\AdminRoleTransformer;
|
||||||
|
use Pterodactyl\Http\Requests\Api\Application\Roles\GetRoleRequest;
|
||||||
use Pterodactyl\Http\Requests\Api\Application\Roles\GetRolesRequest;
|
use Pterodactyl\Http\Requests\Api\Application\Roles\GetRolesRequest;
|
||||||
use Pterodactyl\Http\Requests\Api\Application\Roles\StoreRoleRequest;
|
use Pterodactyl\Http\Requests\Api\Application\Roles\StoreRoleRequest;
|
||||||
use Pterodactyl\Http\Requests\Api\Application\Roles\DeleteRoleRequest;
|
use Pterodactyl\Http\Requests\Api\Application\Roles\DeleteRoleRequest;
|
||||||
|
@ -49,13 +50,13 @@ class RoleController extends ApplicationApiController
|
||||||
/**
|
/**
|
||||||
* Returns a single role.
|
* Returns a single role.
|
||||||
*
|
*
|
||||||
* @param \Pterodactyl\Http\Requests\Api\Application\Roles\GetRolesRequest $request
|
* @param \Pterodactyl\Http\Requests\Api\Application\Roles\GetRoleRequest $request
|
||||||
* @param \Pterodactyl\Models\AdminRole $role
|
* @param \Pterodactyl\Models\AdminRole $role
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||||
*/
|
*/
|
||||||
public function view(GetRolesRequest $request, AdminRole $role): array
|
public function view(GetRoleRequest $request, AdminRole $role): array
|
||||||
{
|
{
|
||||||
return $this->fractal->item($role)
|
return $this->fractal->item($role)
|
||||||
->transformWith($this->getTransformer(AdminRoleTransformer::class))
|
->transformWith($this->getTransformer(AdminRoleTransformer::class))
|
||||||
|
|
|
@ -10,6 +10,8 @@ use Pterodactyl\Services\Users\UserCreationService;
|
||||||
use Pterodactyl\Services\Users\UserDeletionService;
|
use Pterodactyl\Services\Users\UserDeletionService;
|
||||||
use Pterodactyl\Contracts\Repository\UserRepositoryInterface;
|
use Pterodactyl\Contracts\Repository\UserRepositoryInterface;
|
||||||
use Pterodactyl\Transformers\Api\Application\UserTransformer;
|
use Pterodactyl\Transformers\Api\Application\UserTransformer;
|
||||||
|
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
|
||||||
|
use Pterodactyl\Http\Requests\Api\Application\Users\GetUserRequest;
|
||||||
use Pterodactyl\Http\Requests\Api\Application\Users\GetUsersRequest;
|
use Pterodactyl\Http\Requests\Api\Application\Users\GetUsersRequest;
|
||||||
use Pterodactyl\Http\Requests\Api\Application\Users\StoreUserRequest;
|
use Pterodactyl\Http\Requests\Api\Application\Users\StoreUserRequest;
|
||||||
use Pterodactyl\Http\Requests\Api\Application\Users\DeleteUserRequest;
|
use Pterodactyl\Http\Requests\Api\Application\Users\DeleteUserRequest;
|
||||||
|
@ -18,6 +20,11 @@ use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController;
|
||||||
|
|
||||||
class UserController extends ApplicationApiController
|
class UserController extends ApplicationApiController
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @var \Pterodactyl\Contracts\Repository\UserRepositoryInterface
|
||||||
|
*/
|
||||||
|
private $repository;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \Pterodactyl\Services\Users\UserCreationService
|
* @var \Pterodactyl\Services\Users\UserCreationService
|
||||||
*/
|
*/
|
||||||
|
@ -28,11 +35,6 @@ class UserController extends ApplicationApiController
|
||||||
*/
|
*/
|
||||||
private $deletionService;
|
private $deletionService;
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \Pterodactyl\Contracts\Repository\UserRepositoryInterface
|
|
||||||
*/
|
|
||||||
private $repository;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \Pterodactyl\Services\Users\UserUpdateService
|
* @var \Pterodactyl\Services\Users\UserUpdateService
|
||||||
*/
|
*/
|
||||||
|
@ -51,13 +53,12 @@ class UserController extends ApplicationApiController
|
||||||
UserCreationService $creationService,
|
UserCreationService $creationService,
|
||||||
UserDeletionService $deletionService,
|
UserDeletionService $deletionService,
|
||||||
UserUpdateService $updateService
|
UserUpdateService $updateService
|
||||||
)
|
) {
|
||||||
{
|
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
|
|
||||||
|
$this->repository = $repository;
|
||||||
$this->creationService = $creationService;
|
$this->creationService = $creationService;
|
||||||
$this->deletionService = $deletionService;
|
$this->deletionService = $deletionService;
|
||||||
$this->repository = $repository;
|
|
||||||
$this->updateService = $updateService;
|
$this->updateService = $updateService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,10 +74,17 @@ class UserController extends ApplicationApiController
|
||||||
*/
|
*/
|
||||||
public function index(GetUsersRequest $request): array
|
public function index(GetUsersRequest $request): array
|
||||||
{
|
{
|
||||||
|
$perPage = $request->query('per_page', 10);
|
||||||
|
if ($perPage < 1) {
|
||||||
|
$perPage = 10;
|
||||||
|
} else if ($perPage > 100) {
|
||||||
|
throw new BadRequestHttpException('"per_page" query parameter must be below 100.');
|
||||||
|
}
|
||||||
|
|
||||||
$users = QueryBuilder::for(User::query())
|
$users = QueryBuilder::for(User::query())
|
||||||
->allowedFilters(['email', 'uuid', 'username', 'external_id'])
|
->allowedFilters(['email', 'uuid', 'username', 'external_id'])
|
||||||
->allowedSorts(['id', 'uuid'])
|
->allowedSorts(['id', 'uuid'])
|
||||||
->paginate(100);
|
->paginate($perPage);
|
||||||
|
|
||||||
return $this->fractal->collection($users)
|
return $this->fractal->collection($users)
|
||||||
->transformWith($this->getTransformer(UserTransformer::class))
|
->transformWith($this->getTransformer(UserTransformer::class))
|
||||||
|
@ -87,13 +95,13 @@ class UserController extends ApplicationApiController
|
||||||
* Handle a request to view a single user. Includes any relations that
|
* Handle a request to view a single user. Includes any relations that
|
||||||
* were defined in the request.
|
* were defined in the request.
|
||||||
*
|
*
|
||||||
* @param \Pterodactyl\Http\Requests\Api\Application\Users\GetUsersRequest $request
|
* @param \Pterodactyl\Http\Requests\Api\Application\Users\GetUserRequest $request
|
||||||
* @param \Pterodactyl\Models\User $user
|
* @param \Pterodactyl\Models\User $user
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
||||||
*/
|
*/
|
||||||
public function view(GetUsersRequest $request, User $user): array
|
public function view(GetUserRequest $request, User $user): array
|
||||||
{
|
{
|
||||||
return $this->fractal->item($user)
|
return $this->fractal->item($user)
|
||||||
->transformWith($this->getTransformer(UserTransformer::class))
|
->transformWith($this->getTransformer(UserTransformer::class))
|
||||||
|
@ -122,10 +130,9 @@ class UserController extends ApplicationApiController
|
||||||
$this->updateService->setUserLevel(User::USER_LEVEL_ADMIN);
|
$this->updateService->setUserLevel(User::USER_LEVEL_ADMIN);
|
||||||
$user = $this->updateService->handle($user, $request->validated());
|
$user = $this->updateService->handle($user, $request->validated());
|
||||||
|
|
||||||
$response = $this->fractal->item($user)
|
return $this->fractal->item($user)
|
||||||
->transformWith($this->getTransformer(UserTransformer::class));
|
->transformWith($this->getTransformer(UserTransformer::class))
|
||||||
|
->toArray();
|
||||||
return $response->toArray();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
20
app/Http/Requests/Api/Application/Users/GetUserRequest.php
Normal file
20
app/Http/Requests/Api/Application/Users/GetUserRequest.php
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Pterodactyl\Http\Requests\Api\Application\Users;
|
||||||
|
|
||||||
|
use Pterodactyl\Models\User;
|
||||||
|
|
||||||
|
class GetUserRequest extends GetUsersRequest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Determine if the requested role exists on the Panel.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function resourceExists(): bool
|
||||||
|
{
|
||||||
|
$user = $this->route()->parameter('user');
|
||||||
|
|
||||||
|
return $user instanceof User && $user->exists;
|
||||||
|
}
|
||||||
|
}
|
39
resources/scripts/api/admin/users/getUsers.ts
Normal file
39
resources/scripts/api/admin/users/getUsers.ts
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
import http, { getPaginationSet, PaginatedResult } from '@/api/http';
|
||||||
|
import { rawDataToUser } from '@/api/transformers';
|
||||||
|
import { createContext, useContext } from 'react';
|
||||||
|
import useSWR from 'swr';
|
||||||
|
|
||||||
|
export interface User {
|
||||||
|
id: number;
|
||||||
|
externalId: string;
|
||||||
|
uuid: string;
|
||||||
|
username: string;
|
||||||
|
email: string;
|
||||||
|
firstName: string;
|
||||||
|
lastName: string;
|
||||||
|
language: string;
|
||||||
|
rootAdmin: boolean;
|
||||||
|
tfa: boolean;
|
||||||
|
createdAt: Date;
|
||||||
|
updatedAt: Date;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ctx {
|
||||||
|
page: number;
|
||||||
|
setPage: (value: number | ((s: number) => number)) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const Context = createContext<ctx>({ page: 1, setPage: () => 1 });
|
||||||
|
|
||||||
|
export default () => {
|
||||||
|
const { page } = useContext(Context);
|
||||||
|
|
||||||
|
return useSWR<PaginatedResult<User>>([ 'users', page ], async () => {
|
||||||
|
const { data } = await http.get('/api/application/users', { params: { page } });
|
||||||
|
|
||||||
|
return ({
|
||||||
|
items: (data.data || []).map(rawDataToUser),
|
||||||
|
pagination: getPaginationSet(data.meta.pagination),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
|
@ -1,6 +1,7 @@
|
||||||
import { Egg } from '@/api/admin/nests/eggs/getEggs';
|
import { Egg } from '@/api/admin/nests/eggs/getEggs';
|
||||||
import { Nest } from '@/api/admin/nests/getNests';
|
import { Nest } from '@/api/admin/nests/getNests';
|
||||||
import { Role } from '@/api/admin/roles/getRoles';
|
import { Role } from '@/api/admin/roles/getRoles';
|
||||||
|
import { User } from '@/api/admin/users/getUsers';
|
||||||
import { Allocation } from '@/api/server/getServer';
|
import { Allocation } from '@/api/server/getServer';
|
||||||
import { FractalResponseData } from '@/api/http';
|
import { FractalResponseData } from '@/api/http';
|
||||||
import { FileObject } from '@/api/server/files/loadDirectory';
|
import { FileObject } from '@/api/server/files/loadDirectory';
|
||||||
|
@ -117,3 +118,18 @@ export const rawDataToEgg = ({ attributes }: FractalResponseData): Egg => ({
|
||||||
createdAt: new Date(attributes.created_at),
|
createdAt: new Date(attributes.created_at),
|
||||||
updatedAt: new Date(attributes.updated_at),
|
updatedAt: new Date(attributes.updated_at),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const rawDataToUser = ({ attributes }: FractalResponseData): User => ({
|
||||||
|
id: attributes.id,
|
||||||
|
externalId: attributes.external_id,
|
||||||
|
uuid: attributes.uuid,
|
||||||
|
username: attributes.username,
|
||||||
|
email: attributes.email,
|
||||||
|
firstName: attributes.first_name,
|
||||||
|
lastName: attributes.last_name,
|
||||||
|
language: attributes.language,
|
||||||
|
rootAdmin: attributes.root_admin,
|
||||||
|
tfa: attributes['2fa'],
|
||||||
|
createdAt: new Date(attributes.created_at),
|
||||||
|
updatedAt: new Date(attributes.updated_at),
|
||||||
|
});
|
||||||
|
|
|
@ -102,7 +102,7 @@ const NestsContainer = () => {
|
||||||
|
|
||||||
<td css={tw`px-6 text-sm text-neutral-200 text-left whitespace-nowrap`}>{nest.id}</td>
|
<td css={tw`px-6 text-sm text-neutral-200 text-left whitespace-nowrap`}>{nest.id}</td>
|
||||||
<td css={tw`px-6 text-sm text-neutral-200 text-left whitespace-nowrap`}>
|
<td css={tw`px-6 text-sm text-neutral-200 text-left whitespace-nowrap`}>
|
||||||
<NavLink to={`${match.url}/${nest.id}`}>
|
<NavLink to={`${match.url}/${nest.id}`} css={tw`text-primary-400 hover:text-primary-300`}>
|
||||||
{nest.name}
|
{nest.name}
|
||||||
</NavLink>
|
</NavLink>
|
||||||
</td>
|
</td>
|
||||||
|
|
|
@ -103,7 +103,7 @@ export default () => {
|
||||||
|
|
||||||
<td css={tw`px-6 text-sm text-neutral-200 text-left whitespace-nowrap`}>{role.id}</td>
|
<td css={tw`px-6 text-sm text-neutral-200 text-left whitespace-nowrap`}>{role.id}</td>
|
||||||
<td css={tw`px-6 text-sm text-neutral-200 text-left whitespace-nowrap`}>
|
<td css={tw`px-6 text-sm text-neutral-200 text-left whitespace-nowrap`}>
|
||||||
<NavLink to={`${match.url}/${role.id}`}>
|
<NavLink to={`${match.url}/${role.id}`} css={tw`text-primary-400 hover:text-primary-300`}>
|
||||||
{role.name}
|
{role.name}
|
||||||
</NavLink>
|
</NavLink>
|
||||||
</td>
|
</td>
|
||||||
|
|
|
@ -1,12 +1,67 @@
|
||||||
|
import AdminCheckbox from '@/components/admin/AdminCheckbox';
|
||||||
|
import React, { useContext, useEffect, useState } from 'react';
|
||||||
|
import getUsers, { Context as UsersContext } from '@/api/admin/users/getUsers';
|
||||||
|
import AdminTable, { ContentWrapper, Loading, NoItems, Pagination, TableBody, TableHead, TableHeader, TableRow } from '@/components/admin/AdminTable';
|
||||||
import Button from '@/components/elements/Button';
|
import Button from '@/components/elements/Button';
|
||||||
import React from 'react';
|
import FlashMessageRender from '@/components/FlashMessageRender';
|
||||||
|
import useFlash from '@/plugins/useFlash';
|
||||||
|
import { AdminContext } from '@/state/admin';
|
||||||
|
import { NavLink, useRouteMatch } from 'react-router-dom';
|
||||||
import tw from 'twin.macro';
|
import tw from 'twin.macro';
|
||||||
import AdminContentBlock from '@/components/admin/AdminContentBlock';
|
import AdminContentBlock from '@/components/admin/AdminContentBlock';
|
||||||
|
|
||||||
export default () => {
|
const RowCheckbox = ({ id }: { id: number}) => {
|
||||||
|
const isChecked = AdminContext.useStoreState(state => state.nests.selectedNests.indexOf(id) >= 0);
|
||||||
|
const appendSelectedUser = AdminContext.useStoreActions(actions => actions.nests.appendSelectedNest);
|
||||||
|
const removeSelectedUser = AdminContext.useStoreActions(actions => actions.nests.removeSelectedNest);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<AdminCheckbox
|
||||||
|
name={id.toString()}
|
||||||
|
checked={isChecked}
|
||||||
|
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
if (e.currentTarget.checked) {
|
||||||
|
appendSelectedUser(id);
|
||||||
|
} else {
|
||||||
|
removeSelectedUser(id);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const UsersContainer = () => {
|
||||||
|
const match = useRouteMatch();
|
||||||
|
|
||||||
|
const { page, setPage } = useContext(UsersContext);
|
||||||
|
const { clearFlashes, clearAndAddHttpError } = useFlash();
|
||||||
|
const { data: users, error, isValidating } = getUsers();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!error) {
|
||||||
|
clearFlashes('users');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
clearAndAddHttpError({ error, key: 'users' });
|
||||||
|
}, [ error ]);
|
||||||
|
|
||||||
|
const length = users?.items?.length || 0;
|
||||||
|
|
||||||
|
const setSelectedUsers = AdminContext.useStoreActions(actions => actions.nests.setSelectedNests);
|
||||||
|
const selectedUserLength = AdminContext.useStoreState(state => state.nests.selectedNests.length);
|
||||||
|
|
||||||
|
const onSelectAllClick = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
setSelectedUsers(e.currentTarget.checked ? (users?.items?.map(user => user.id) || []) : []);
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setSelectedUsers([]);
|
||||||
|
}, [ page ]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AdminContentBlock>
|
<AdminContentBlock>
|
||||||
<div css={tw`w-full flex flex-row items-center`}>
|
<div css={tw`w-full flex flex-row items-center mb-8`}>
|
||||||
<div css={tw`flex flex-col`}>
|
<div css={tw`flex flex-col`}>
|
||||||
<h2 css={tw`text-2xl text-neutral-50 font-header font-medium`}>Users</h2>
|
<h2 css={tw`text-2xl text-neutral-50 font-header font-medium`}>Users</h2>
|
||||||
<p css={tw`text-base text-neutral-400`}>All registered users on the system.</p>
|
<p css={tw`text-base text-neutral-400`}>All registered users on the system.</p>
|
||||||
|
@ -16,6 +71,66 @@ export default () => {
|
||||||
New User
|
New User
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<FlashMessageRender byKey={'users'} css={tw`mb-4`}/>
|
||||||
|
|
||||||
|
<AdminTable>
|
||||||
|
{ users === undefined || (error && isValidating) ?
|
||||||
|
<Loading/>
|
||||||
|
:
|
||||||
|
length < 1 ?
|
||||||
|
<NoItems/>
|
||||||
|
:
|
||||||
|
<ContentWrapper
|
||||||
|
checked={selectedUserLength === (length === 0 ? -1 : length)}
|
||||||
|
onSelectAllClick={onSelectAllClick}
|
||||||
|
>
|
||||||
|
<Pagination data={users} onPageSelect={setPage}>
|
||||||
|
<div css={tw`overflow-x-auto`}>
|
||||||
|
<table css={tw`w-full table-auto`}>
|
||||||
|
<TableHead>
|
||||||
|
<TableHeader name={'ID'}/>
|
||||||
|
<TableHeader name={'Email'}/>
|
||||||
|
<TableHeader name={'Username'}/>
|
||||||
|
<TableHeader name={'Client Name'}/>
|
||||||
|
</TableHead>
|
||||||
|
|
||||||
|
<TableBody>
|
||||||
|
{
|
||||||
|
users.items.map(user => (
|
||||||
|
<TableRow key={user.id}>
|
||||||
|
<td css={tw`pl-6`}>
|
||||||
|
<RowCheckbox id={user.id}/>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td css={tw`px-6 text-sm text-neutral-200 text-left whitespace-nowrap`}>{user.id}</td>
|
||||||
|
<td css={tw`px-6 text-sm text-neutral-200 text-left whitespace-nowrap`}>
|
||||||
|
<NavLink to={`${match.url}/${user.id}`} css={tw`text-primary-400 hover:text-primary-300`}>
|
||||||
|
{user.email}
|
||||||
|
</NavLink>
|
||||||
|
</td>
|
||||||
|
<td css={tw`px-6 text-sm text-neutral-200 text-left whitespace-nowrap`}>{user.username}</td>
|
||||||
|
<td css={tw`px-6 text-sm text-neutral-200 text-left whitespace-nowrap`}>{user.lastName}, {user.firstName}</td>
|
||||||
|
</TableRow>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
</TableBody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</Pagination>
|
||||||
|
</ContentWrapper>
|
||||||
|
}
|
||||||
|
</AdminTable>
|
||||||
</AdminContentBlock>
|
</AdminContentBlock>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export default () => {
|
||||||
|
const [ page, setPage ] = useState<number>(1);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<UsersContext.Provider value={{ page, setPage }}>
|
||||||
|
<UsersContainer/>
|
||||||
|
</UsersContext.Provider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
|
@ -17,6 +17,7 @@ Route::group(['prefix' => '/users'], function () {
|
||||||
Route::get('/external/{external_id}', 'Users\ExternalUserController@index')->name('api.application.users.external');
|
Route::get('/external/{external_id}', 'Users\ExternalUserController@index')->name('api.application.users.external');
|
||||||
|
|
||||||
Route::post('/', 'Users\UserController@store');
|
Route::post('/', 'Users\UserController@store');
|
||||||
|
|
||||||
Route::patch('/{user}', 'Users\UserController@update');
|
Route::patch('/{user}', 'Users\UserController@update');
|
||||||
|
|
||||||
Route::delete('/{user}', 'Users\UserController@delete');
|
Route::delete('/{user}', 'Users\UserController@delete');
|
||||||
|
@ -36,6 +37,7 @@ Route::group(['prefix' => '/nodes'], function () {
|
||||||
Route::get('/{node}/configuration', 'Nodes\NodeConfigurationController');
|
Route::get('/{node}/configuration', 'Nodes\NodeConfigurationController');
|
||||||
|
|
||||||
Route::post('/', 'Nodes\NodeController@store');
|
Route::post('/', 'Nodes\NodeController@store');
|
||||||
|
|
||||||
Route::patch('/{node}', 'Nodes\NodeController@update');
|
Route::patch('/{node}', 'Nodes\NodeController@update');
|
||||||
|
|
||||||
Route::delete('/{node}', 'Nodes\NodeController@delete');
|
Route::delete('/{node}', 'Nodes\NodeController@delete');
|
||||||
|
@ -60,6 +62,7 @@ Route::group(['prefix' => '/locations'], function () {
|
||||||
Route::get('/{location}', 'Locations\LocationController@view')->name('api.application.locations.view');
|
Route::get('/{location}', 'Locations\LocationController@view')->name('api.application.locations.view');
|
||||||
|
|
||||||
Route::post('/', 'Locations\LocationController@store');
|
Route::post('/', 'Locations\LocationController@store');
|
||||||
|
|
||||||
Route::patch('/{location}', 'Locations\LocationController@update');
|
Route::patch('/{location}', 'Locations\LocationController@update');
|
||||||
|
|
||||||
Route::delete('/{location}', 'Locations\LocationController@delete');
|
Route::delete('/{location}', 'Locations\LocationController@delete');
|
||||||
|
|
Loading…
Reference in a new issue