diff --git a/assets/components/StickyHeadTable.tsx b/assets/components/StickyHeadTable.tsx new file mode 100644 index 0000000..05f9761 --- /dev/null +++ b/assets/components/StickyHeadTable.tsx @@ -0,0 +1,83 @@ +import React from "react"; +import {Paper, Table, TableBody, TableCell, TableContainer, TableHead, TablePagination, TableRow} from "@mui/material"; + +interface Column { + id: string; + label: string; + minWidth?: number; + align?: 'right'; + format?: (value: number) => string; +} + +interface Data { + name: string; + code: string; + population: number; + size: number; + density: number; +} + +export default function StickyHeadTable({columns, rows}: { rows: Data[], columns: Column[] }) { + const [page, setPage] = React.useState(0); + const [rowsPerPage, setRowsPerPage] = React.useState(10); + + const handleChangePage = (event: unknown, newPage: number) => { + setPage(newPage); + }; + + const handleChangeRowsPerPage = (event: React.ChangeEvent) => { + setRowsPerPage(+event.target.value); + setPage(0); + }; + + return ( + + + + + + {columns.map((column) => ( + + {column.label} + + ))} + + + + {rows + .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) + .map((row: Data) => { + return ( + + {columns.map((column) => { + const value = row[column.id as keyof typeof row] + return ( + + {column.format && typeof value === 'number' + ? column.format(value) + : value} + + ); + })} + + ); + })} + +
+
+ +
+ ); +} diff --git a/config/packages/security.yaml b/config/packages/security.yaml index 848a06d..d41e1f0 100644 --- a/config/packages/security.yaml +++ b/config/packages/security.yaml @@ -67,7 +67,7 @@ security: # Easy way to control access for large sections of your site # Note: Only the *first* access control that matches will be used access_control: - - { path: ^/api/$, roles: PUBLIC_ACCESS } + - { path: ^/api$, roles: PUBLIC_ACCESS } - { path: ^/api/docs, roles: PUBLIC_ACCESS } - { path: ^/api, roles: IS_AUTHENTICATED_FULLY } diff --git a/config/routes.yaml b/config/routes.yaml index 8abbd39..d81cec5 100644 --- a/config/routes.yaml +++ b/config/routes.yaml @@ -6,7 +6,7 @@ controllers: api_login: path: /api/login -# methods: [ 'POST' ] + methods: [ 'POST' ] oauth_connect_check: path: /login/oauth/check diff --git a/src/Entity/Tld.php b/src/Entity/Tld.php index 06fd257..5a03760 100644 --- a/src/Entity/Tld.php +++ b/src/Entity/Tld.php @@ -21,6 +21,7 @@ use Symfony\Component\Serializer\Attribute\Groups; operations: [ new GetCollection( uriTemplate: '/tld', + paginationItemsPerPage: 200, normalizationContext: ['groups' => ['tld:list']] ), new Get( @@ -56,7 +57,7 @@ class Tld private ?DateTimeImmutable $delegationDate = null; #[ORM\Column(length: 255, nullable: true)] - #[Groups(["tld:item"])] + #[Groups(["tld:list", "tld:item"])] private ?string $registryOperator = null; #[ORM\Column(type: Types::DATE_IMMUTABLE, nullable: true)] @@ -64,7 +65,7 @@ class Tld private ?DateTimeImmutable $removalDate = null; #[ORM\Column(nullable: true)] - #[Groups(["tld:item"])] + #[Groups(["tld:list", "tld:item"])] private ?bool $specification13 = null; #[ORM\Column(length: 10, nullable: true, enumType: TldType::class)] @@ -195,10 +196,8 @@ class Tld return $this->type; } - public function setType(TldType $type): static + public function setType(?TldType $type): void { $this->type = $type; - - return $this; } } diff --git a/src/Service/RDAPService.php b/src/Service/RDAPService.php index 0e224a9..b2d5f85 100644 --- a/src/Service/RDAPService.php +++ b/src/Service/RDAPService.php @@ -27,7 +27,6 @@ use DateTimeImmutable; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\Exception\ORMException; use Exception; -use Symfony\Component\Intl\Countries; use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface; use Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface; use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface; @@ -340,8 +339,16 @@ readonly class RDAPService $tldEntity = $this->tldRepository->findOneBy(['tld' => $tld]); if ($tldEntity === null) $tldEntity = new Tld(); - $tldEntity->setTld($tld)->setType($this->getTldType($tld)); - if ($tldEntity->getRegistryOperator() === NULL) $tldEntity->setType(TldType::ccTLD); + if ($tldEntity->getType() === null) { + $type = $this->getTldType($tld); + if ($type !== null) { + $tldEntity->setType($type); + } elseif ($tldEntity->isContractTerminated() === null) { + $tldEntity->setType(TldType::ccTLD); + } else { + $tldEntity->setType(TldType::gTLD); + } + } $this->em->persist($tldEntity); } @@ -351,12 +358,12 @@ readonly class RDAPService private function getTldType(string $tld): ?TldType { - if (Countries::exists(strtoupper($tld)) || in_array($tld, self::ISO_TLD_EXCEPTION)) return TldType::ccTLD; + if (in_array($tld, self::ISO_TLD_EXCEPTION)) return TldType::ccTLD; if (in_array(strtolower($tld), self::INFRA_TLD)) return TldType::iTLD; if (in_array(strtolower($tld), self::SPONSORED_TLD)) return TldType::sTLD; if (in_array(strtolower($tld), self::TEST_TLD)) return TldType::tTLD; - return TldType::gTLD; + return null; } /** @@ -379,7 +386,8 @@ readonly class RDAPService /** @var Tld $gtTldEntity */ $gtTldEntity = $this->em->getReference(Tld::class, $gTld['gTLD']); - $gtTldEntity->setContractTerminated($gTld['contractTerminated']) + $gtTldEntity + ->setContractTerminated($gTld['contractTerminated']) ->setRegistryOperator($gTld['registryOperator']) ->setSpecification13($gTld['specification13']);