Add collection and new vocab + mess with repository
This commit is contained in:
parent
f8e470b096
commit
0a41ff4a7b
@ -44,10 +44,12 @@ if (location.pathname.includes('login')) {
|
|||||||
|
|
||||||
if (! location.pathname.includes('login')) {
|
if (! location.pathname.includes('login')) {
|
||||||
const vocabs = document.querySelector('#vocabs');
|
const vocabs = document.querySelector('#vocabs');
|
||||||
|
const records = document.querySelector('#records');
|
||||||
const userMenu = document.querySelector('.dropdown-trigger');
|
const userMenu = document.querySelector('.dropdown-trigger');
|
||||||
const userCaret = document.querySelector('#user-caret');
|
const userCaret = document.querySelector('#user-caret');
|
||||||
|
|
||||||
const forVocabs = document.querySelector('#for-vocabs')
|
const forVocabs = document.querySelector('#for-vocabs')
|
||||||
|
const forRecords = document.querySelector('#for-records')
|
||||||
|
|
||||||
if (forVocabs) {
|
if (forVocabs) {
|
||||||
forVocabs.addEventListener('click', function () {
|
forVocabs.addEventListener('click', function () {
|
||||||
@ -63,6 +65,20 @@ if (! location.pathname.includes('login')) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (forRecords) {
|
||||||
|
forRecords.addEventListener('click', function () {
|
||||||
|
records.classList.toggle('is-hidden');
|
||||||
|
|
||||||
|
if (this.firstElementChild.classList.contains('fa-angle-right')) {
|
||||||
|
this.firstElementChild.classList.remove('fa-angle-right');
|
||||||
|
this.firstElementChild.classList.add('fa-angle-down');
|
||||||
|
} else {
|
||||||
|
this.firstElementChild.classList.remove('fa-angle-down');
|
||||||
|
this.firstElementChild.classList.add('fa-angle-right');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
userMenu.addEventListener('click', function () {
|
userMenu.addEventListener('click', function () {
|
||||||
document.querySelector('.dropdown').classList.toggle('is-active');
|
document.querySelector('.dropdown').classList.toggle('is-active');
|
||||||
if (userCaret.classList.contains('fa-caret-down')) {
|
if (userCaret.classList.contains('fa-caret-down')) {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
@import url('../vendor/bulma/css/bulma.min.css');
|
|
||||||
@import url('../fonts/stylesheet.css');
|
@import url('../fonts/stylesheet.css');
|
||||||
@import url('../fontawesome-free-6.6.0-web/css/all.min.css');
|
@import url('../fontawesome-free-6.6.0-web/css/all.min.css');
|
||||||
|
@import url('../vendor/bulma/css/bulma.min.css');
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
--arcoa-blue: rgba(66,135,199,0.98);
|
--arcoa-blue: rgba(66,135,199,0.98);
|
||||||
@ -15,13 +15,11 @@ body {
|
|||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
#vocabs a {
|
|
||||||
|
#vocabs a,
|
||||||
|
#records a {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
/* For dev only*/
|
|
||||||
.sf-toolbar-clearer {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table.record td,
|
.table.record td,
|
||||||
.table.record th {
|
.table.record th {
|
||||||
@ -29,5 +27,13 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.table.record th {
|
.table.record th {
|
||||||
min-width: 220px;
|
min-width: 240px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table td {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.results tr > th {
|
||||||
|
text-align: center !important;
|
||||||
}
|
}
|
@ -7,10 +7,13 @@
|
|||||||
"php": ">=8.2",
|
"php": ">=8.2",
|
||||||
"ext-ctype": "*",
|
"ext-ctype": "*",
|
||||||
"ext-iconv": "*",
|
"ext-iconv": "*",
|
||||||
|
"api-platform/doctrine-orm": "^4.0",
|
||||||
|
"api-platform/symfony": "^4.0",
|
||||||
"doctrine/dbal": "^3",
|
"doctrine/dbal": "^3",
|
||||||
"doctrine/doctrine-bundle": "^2.13",
|
"doctrine/doctrine-bundle": "^2.13",
|
||||||
"doctrine/doctrine-migrations-bundle": "^3.3",
|
"doctrine/doctrine-migrations-bundle": "^3.3",
|
||||||
"doctrine/orm": "^3.3",
|
"doctrine/orm": "^3.3",
|
||||||
|
"nelmio/cors-bundle": "^2.5",
|
||||||
"phpdocumentor/reflection-docblock": "^5.4",
|
"phpdocumentor/reflection-docblock": "^5.4",
|
||||||
"phpstan/phpdoc-parser": "^1.33",
|
"phpstan/phpdoc-parser": "^1.33",
|
||||||
"symfony/asset": "7.1.*",
|
"symfony/asset": "7.1.*",
|
||||||
|
1480
composer.lock
generated
1480
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@ -13,4 +13,6 @@ return [
|
|||||||
Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true],
|
Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true],
|
||||||
Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true],
|
Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true],
|
||||||
Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true],
|
Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true],
|
||||||
|
Nelmio\CorsBundle\NelmioCorsBundle::class => ['all' => true],
|
||||||
|
ApiPlatform\Symfony\Bundle\ApiPlatformBundle::class => ['all' => true],
|
||||||
];
|
];
|
||||||
|
7
config/packages/api_platform.yaml
Normal file
7
config/packages/api_platform.yaml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
api_platform:
|
||||||
|
title: Hello API Platform
|
||||||
|
version: 1.0.0
|
||||||
|
defaults:
|
||||||
|
stateless: true
|
||||||
|
cache_headers:
|
||||||
|
vary: ['Content-Type', 'Authorization', 'Origin']
|
@ -4,7 +4,9 @@ framework:
|
|||||||
csrf_protection: true
|
csrf_protection: true
|
||||||
|
|
||||||
# Note that the session will be started ONLY if you read or write from it.
|
# Note that the session will be started ONLY if you read or write from it.
|
||||||
session: true
|
session:
|
||||||
|
enabled: true
|
||||||
|
cookie_lifetime: 3600
|
||||||
|
|
||||||
#esi: true
|
#esi: true
|
||||||
#fragments: true
|
#fragments: true
|
||||||
|
10
config/packages/nelmio_cors.yaml
Normal file
10
config/packages/nelmio_cors.yaml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
nelmio_cors:
|
||||||
|
defaults:
|
||||||
|
origin_regex: true
|
||||||
|
allow_origin: ['%env(CORS_ALLOW_ORIGIN)%']
|
||||||
|
allow_methods: ['GET', 'OPTIONS', 'POST', 'PUT', 'PATCH', 'DELETE']
|
||||||
|
allow_headers: ['Content-Type', 'Authorization']
|
||||||
|
expose_headers: ['Link']
|
||||||
|
max_age: 3600
|
||||||
|
paths:
|
||||||
|
'^/': null
|
@ -38,6 +38,9 @@ security:
|
|||||||
- { path: ^/admin, roles: ROLE_ADMIN }
|
- { path: ^/admin, roles: ROLE_ADMIN }
|
||||||
- { path: ^/profile, roles: ROLE_USER }
|
- { path: ^/profile, roles: ROLE_USER }
|
||||||
- { path: ^/bibliography, roles: ROLE_USER }
|
- { path: ^/bibliography, roles: ROLE_USER }
|
||||||
|
- { path: ^/collection, roles: ROLE_USER }
|
||||||
|
- { path: ^/object, roles: ROLE_USER }
|
||||||
|
- { path: ^/site, roles: ROLE_USER }
|
||||||
|
|
||||||
when@test:
|
when@test:
|
||||||
security:
|
security:
|
||||||
|
4
config/routes/api_platform.yaml
Normal file
4
config/routes/api_platform.yaml
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
api_platform:
|
||||||
|
resource: .
|
||||||
|
type: api_platform
|
||||||
|
prefix: /api
|
@ -3,6 +3,7 @@
|
|||||||
namespace App\Controller;
|
namespace App\Controller;
|
||||||
|
|
||||||
use App\Entity\Bibliography;
|
use App\Entity\Bibliography;
|
||||||
|
use App\Form\BibliographyType;
|
||||||
//use App\Security\Voter\VocabVoter;
|
//use App\Security\Voter\VocabVoter;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
@ -23,10 +24,18 @@ class BibliographyController extends AbstractController
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[Route('/bibliography', name: 'app_bibliography_landing')]
|
#[Route('/bibliography', name: 'app_bibliography_landing')]
|
||||||
public function landing(): Response
|
public function landing(EntityManagerInterface $em): Response
|
||||||
{
|
{
|
||||||
|
$repo = $em->getRepository(Bibliography::class);
|
||||||
|
$records = $repo->findBy([], ['modifiedAt' => 'DESC']);
|
||||||
|
$count = count($records);
|
||||||
|
|
||||||
|
$records = array_slice($records, 0, 15);
|
||||||
|
|
||||||
return $this->render('bibliography/landing.html.twig', [
|
return $this->render('bibliography/landing.html.twig', [
|
||||||
'controller_name' => 'BibliographyController',
|
'controller_name' => 'BibliographyController',
|
||||||
|
'records' => $records,
|
||||||
|
'count' => $count,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,11 +47,30 @@ class BibliographyController extends AbstractController
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[Route('/bibliography/add', name: 'app_bibliography_add')]
|
/**
|
||||||
|
* @todo Permissions with voter
|
||||||
|
*/
|
||||||
|
#[Route('/bibliography/add', name: 'app_bibliography_create')]
|
||||||
public function add(): Response
|
public function add(): Response
|
||||||
{
|
{
|
||||||
return $this->render('bibliography/add.html.twig', [
|
$form = $this->createForm(BibliographyType::class);
|
||||||
|
|
||||||
|
return $this->render('bibliography/create.html.twig', [
|
||||||
'controller_name' => 'BibliographyController',
|
'controller_name' => 'BibliographyController',
|
||||||
|
'form' => $form,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* @todo Permissions!
|
||||||
|
*/
|
||||||
|
#[Route('/bibliography/delete/{id<\d+>}', name: 'app_bibliography_del')]
|
||||||
|
public function delete(Bibliography $bibliography, EntityManagerInterface $em): Response
|
||||||
|
{
|
||||||
|
$em->remove($bibliography);
|
||||||
|
$em->flush();
|
||||||
|
|
||||||
|
$this->addFlash('notice', 'Term deleted successfully');
|
||||||
|
|
||||||
|
return $this->redirectToRoute('app_bibliography_landing');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
26
src/Controller/CollectionController.php
Normal file
26
src/Controller/CollectionController.php
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Controller;
|
||||||
|
|
||||||
|
use App\Entity\Collection;
|
||||||
|
use App\Entity\Bibliography;
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Symfony\Component\Routing\Attribute\Route;
|
||||||
|
|
||||||
|
class CollectionController extends AbstractController
|
||||||
|
{
|
||||||
|
#[Route('/collection/{id<\d+>}', name: 'app_collection')]
|
||||||
|
public function index(Collection $collection, EntityManagerInterface $em): Response
|
||||||
|
{
|
||||||
|
$bibliographies = $em->getRepository(Bibliography::class)->findAllCollection($collection->getId());
|
||||||
|
|
||||||
|
$collection->setBibliographies($bibliographies);
|
||||||
|
|
||||||
|
return $this->render('collection/index.html.twig', [
|
||||||
|
'controller_name' => 'CollectionController',
|
||||||
|
'record' => $collection,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
34
src/Controller/VocabObjectTypeController.php
Normal file
34
src/Controller/VocabObjectTypeController.php
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Controller;
|
||||||
|
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Symfony\Component\Routing\Attribute\Route;
|
||||||
|
use App\Entity\VocabObjectType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @todo Pagination
|
||||||
|
*/
|
||||||
|
class VocabObjectTypeController extends AbstractController
|
||||||
|
{
|
||||||
|
#[Route('/vocabs/object_type', name: 'app_vocab_object_type')]
|
||||||
|
public function index(EntityManagerInterface $em): Response
|
||||||
|
{
|
||||||
|
$roles = $this->getUser()->getRoles();
|
||||||
|
|
||||||
|
if (in_array('ROLE_READER', $roles)) {
|
||||||
|
$this->addFlash('warning', 'Only editors, revisors and administrators can view vocabularies');
|
||||||
|
return $this->redirectToRoute('app_home');
|
||||||
|
}
|
||||||
|
|
||||||
|
$terms = $em->getRepository(VocabObjectType::class)
|
||||||
|
->findBy([], ['term' => 'ASC']);
|
||||||
|
|
||||||
|
return $this->render('vocab_object_type/index.html.twig', [
|
||||||
|
'controller_name' => 'VocabObjectTypeController',
|
||||||
|
'terms' => $terms
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
@ -2,14 +2,14 @@
|
|||||||
|
|
||||||
namespace App\Entity;
|
namespace App\Entity;
|
||||||
|
|
||||||
//use App\Repository\UserRepository;
|
use App\Repository\BibliographyRepository;
|
||||||
|
|
||||||
use DateTimeImmutable;
|
use DateTimeImmutable;
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
use Doctrine\DBAL\Types\Types;
|
use Doctrine\DBAL\Types\Types;
|
||||||
use App\RecordStatus;
|
use App\RecordStatus;
|
||||||
|
use Doctrine\Common\Collections\Collection as DoctrineCollection;
|
||||||
|
|
||||||
#[ORM\Entity()]
|
#[ORM\Entity(repositoryClass: BibliographyRepository::class)]
|
||||||
#[ORM\Table(name: 'bibliography')]
|
#[ORM\Table(name: 'bibliography')]
|
||||||
class Bibliography
|
class Bibliography
|
||||||
{
|
{
|
||||||
@ -42,6 +42,20 @@ class Bibliography
|
|||||||
#[ORM\Column(length: 100, name: 'creator')]
|
#[ORM\Column(length: 100, name: 'creator')]
|
||||||
private ?string $creator = null;
|
private ?string $creator = null;
|
||||||
|
|
||||||
|
#[ORM\JoinTable(name: 'rel_riferimento_collezione')]
|
||||||
|
#[ORM\JoinColumn(name: 'Bibliografia_id_bib', referencedColumnName: 'id')]
|
||||||
|
#[ORM\InverseJoinColumn(name: 'Collezione_id_coll', referencedColumnName: 'id')]
|
||||||
|
#[ORM\ManyToMany(targetEntity: Collection::class)]
|
||||||
|
private DoctrineCollection $collections;
|
||||||
|
|
||||||
|
private DoctrineCollection $documents;
|
||||||
|
|
||||||
|
private DoctrineCollection $objects;
|
||||||
|
|
||||||
|
private DoctrineCollection $persons;
|
||||||
|
|
||||||
|
private DoctrineCollection $sites;
|
||||||
|
|
||||||
public function getId(): ?int
|
public function getId(): ?int
|
||||||
{
|
{
|
||||||
return $this->id;
|
return $this->id;
|
||||||
@ -143,4 +157,16 @@ class Bibliography
|
|||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getCollections(): ?DoctrineCollection
|
||||||
|
{
|
||||||
|
return $this->collections;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setCollections(DoctrineCollection $collections): static
|
||||||
|
{
|
||||||
|
$this->collections = $collections;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
295
src/Entity/Collection.php
Normal file
295
src/Entity/Collection.php
Normal file
@ -0,0 +1,295 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Entity;
|
||||||
|
|
||||||
|
//use App\Repository\UserRepository;
|
||||||
|
|
||||||
|
use DateTimeImmutable;
|
||||||
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
use Doctrine\DBAL\Types\Types;
|
||||||
|
use App\RecordStatus;
|
||||||
|
use Doctrine\Common\Collections\Collection as DoctrineCollection;
|
||||||
|
|
||||||
|
#[ORM\Entity()]
|
||||||
|
#[ORM\Table(name: 'collection')]
|
||||||
|
class Collection
|
||||||
|
{
|
||||||
|
#[ORM\Id]
|
||||||
|
#[ORM\GeneratedValue]
|
||||||
|
#[ORM\Column(name: 'id')]
|
||||||
|
private ?int $id = null;
|
||||||
|
|
||||||
|
#[ORM\Column(name: 'stato')]
|
||||||
|
private ?int $status = null;
|
||||||
|
|
||||||
|
#[ORM\Column(name: 'modif')]
|
||||||
|
private ?DateTimeImmutable $modifiedAt = null;
|
||||||
|
|
||||||
|
#[ORM\Column(name: 'tit_coll', type: Types::TEXT)]
|
||||||
|
private ?string $title = null;
|
||||||
|
|
||||||
|
#[ORM\Column(name: 'data_coll', type: Types::TEXT)]
|
||||||
|
private ?string $chronology = null;
|
||||||
|
|
||||||
|
#[ORM\Column(name: 'inizio_coll', type: Types::SMALLINT)]
|
||||||
|
private ?int $startDate = null;
|
||||||
|
|
||||||
|
#[ORM\Column(name: 'fine_coll', type: Types::SMALLINT)]
|
||||||
|
private ?int $endDate = null;
|
||||||
|
|
||||||
|
#[ORM\Column(name: 'desc_coll', type: Types::TEXT)]
|
||||||
|
private ?string $description = null;
|
||||||
|
|
||||||
|
#[ORM\Column(name: 'desc_br_coll', type: Types::TEXT)]
|
||||||
|
private ?string $shortDescription = null;
|
||||||
|
|
||||||
|
#[ORM\Column(name: 'id_est_coll', type: Types::TEXT)]
|
||||||
|
private ?string $externalIdentifier = null;
|
||||||
|
|
||||||
|
#[ORM\Column(name: 'link_coll', type: Types::TEXT)]
|
||||||
|
private ?string $link = null;
|
||||||
|
|
||||||
|
#[ORM\Column(name: 'sogg_coll', type: Types::TEXT)]
|
||||||
|
private ?string $subjectHeadings = null;
|
||||||
|
|
||||||
|
#[ORM\Column(name: 'uri_coll', type: Types::TEXT)]
|
||||||
|
private ?string $uri = null;
|
||||||
|
|
||||||
|
#[ORM\Column(name: 'resp', length: 100)]
|
||||||
|
private ?string $owner = null;
|
||||||
|
|
||||||
|
#[ORM\Column(name: 'note_coll', type: Types::TEXT)]
|
||||||
|
private ?string $notes = null;
|
||||||
|
|
||||||
|
#[ORM\Column(length: 100, name: 'editor')]
|
||||||
|
private ?string $editor = null;
|
||||||
|
|
||||||
|
#[ORM\Column(length: 100, name: 'creator')]
|
||||||
|
private ?string $creator = null;
|
||||||
|
|
||||||
|
// TODO: These are references to vocabs
|
||||||
|
#[ORM\Column(name: 'dir_aut_coll')]
|
||||||
|
private ?int $authorRights = null;
|
||||||
|
|
||||||
|
#[ORM\Column(name: 'dir_acc_coll')]
|
||||||
|
private ?int $accessRights = null;
|
||||||
|
|
||||||
|
#[ORM\Column(name: 'lic_coll')]
|
||||||
|
private ?int $license = null;
|
||||||
|
|
||||||
|
#[ORM\JoinTable(name: 'rel_riferimento_collezione')]
|
||||||
|
#[ORM\JoinColumn(name: 'Collezione_id_coll', referencedColumnName: 'id')]
|
||||||
|
#[ORM\InverseJoinColumn(name: 'Bibliografia_id_bib', referencedColumnName: 'id')]
|
||||||
|
#[ORM\ManyToMany(targetEntity: Bibliography::class)]
|
||||||
|
private DoctrineCollection $bibliographies;
|
||||||
|
|
||||||
|
public function getId(): ?int
|
||||||
|
{
|
||||||
|
return $this->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getStatus(): ?string
|
||||||
|
{
|
||||||
|
$status = RecordStatus::tryFrom($this->status);
|
||||||
|
return $status->toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setStatus(int $status): static
|
||||||
|
{
|
||||||
|
$this->status = $status;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getModifiedAt(): ?DateTimeImmutable
|
||||||
|
{
|
||||||
|
return $this->modifiedAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setModifiedAt(DateTimeImmutable $modifiedAt): static
|
||||||
|
{
|
||||||
|
$this->modifiedAt = $modifiedAt;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getOwner(): ?string
|
||||||
|
{
|
||||||
|
return $this->owner;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setOwner(string $owner): static
|
||||||
|
{
|
||||||
|
$this->owner = $owner;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getEditor(): ?string
|
||||||
|
{
|
||||||
|
return $this->editor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setEditor(string $editor): static
|
||||||
|
{
|
||||||
|
$this->editor = $editor;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCreator(): ?string
|
||||||
|
{
|
||||||
|
return $this->creator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setCreator(string $creator): static
|
||||||
|
{
|
||||||
|
$this->creator = $creator;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTitle(): ?string
|
||||||
|
{
|
||||||
|
return $this->title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setTitle(string $title): static
|
||||||
|
{
|
||||||
|
$this->title = $title;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getChronology(): ?string
|
||||||
|
{
|
||||||
|
return $this->chronology;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setChronology(string $chronology): static
|
||||||
|
{
|
||||||
|
$this->chronology = $chronology;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getStartDate(): ?int
|
||||||
|
{
|
||||||
|
return $this->startDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setStartDate(int $startDate): static
|
||||||
|
{
|
||||||
|
$this->startDate = $startDate;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getEndDate(): ?int
|
||||||
|
{
|
||||||
|
return $this->endDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setEndDate(int $endDate): static
|
||||||
|
{
|
||||||
|
$this->endDate = $endDate;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDescription(): ?string
|
||||||
|
{
|
||||||
|
return $this->description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setDescription(string $description): static
|
||||||
|
{
|
||||||
|
$this->description = $description;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getShortDescription(): ?string
|
||||||
|
{
|
||||||
|
return $this->shortDescription;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setShortDescription(string $shortDescription): static
|
||||||
|
{
|
||||||
|
$this->shortDescription = $shortDescription;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getExternalIdentifier(): ?string
|
||||||
|
{
|
||||||
|
return $this->externalIdentifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setExternalIdentifier(string $externalIdentifier): static
|
||||||
|
{
|
||||||
|
$this->externalIdentifier = $externalIdentifier;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLink(): ?string
|
||||||
|
{
|
||||||
|
return $this->link;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setLink(string $link): static
|
||||||
|
{
|
||||||
|
$this->link = $link;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getSubjectHeadings(): ?string
|
||||||
|
{
|
||||||
|
return $this->link;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setSubjectHeadings(string $subjectHeadings): static
|
||||||
|
{
|
||||||
|
$this->subjectHeadings = $subjectHeadings;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getUri(): ?string
|
||||||
|
{
|
||||||
|
return $this->uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setUri(string $uri): static
|
||||||
|
{
|
||||||
|
$this->uri = $uri;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getNotes(): ?string
|
||||||
|
{
|
||||||
|
return $this->notes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setNotes(string $notes): static
|
||||||
|
{
|
||||||
|
$this->notes = $notes;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getBibliographies(): ?DoctrineCollection
|
||||||
|
{
|
||||||
|
return $this->bibliographies;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setBibliographies(DoctrineCollection $bibliographies): static
|
||||||
|
{
|
||||||
|
$this->bibliographies = $bibliographies;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
}
|
37
src/Entity/VocabObjectType.php
Normal file
37
src/Entity/VocabObjectType.php
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Entity;
|
||||||
|
|
||||||
|
//use App\Repository\UserRepository;
|
||||||
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
|
||||||
|
#[ORM\Entity()]
|
||||||
|
#[ORM\Table(name: 'lis_tipologia_oggetto')]
|
||||||
|
class VocabObjectType implements \App\VocabInterface
|
||||||
|
{
|
||||||
|
#[ORM\Id]
|
||||||
|
#[ORM\GeneratedValue]
|
||||||
|
#[ORM\Column(name: 'id_lis_tip_ogg')]
|
||||||
|
private ?int $id = null;
|
||||||
|
|
||||||
|
#[ORM\Column(length: 80, name: 'lis_tip_ogg')]
|
||||||
|
private ?string $term = null;
|
||||||
|
|
||||||
|
public function getId(): ?int
|
||||||
|
{
|
||||||
|
return $this->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTerm(): ?string
|
||||||
|
{
|
||||||
|
return $this->term;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setTerm(string $term): static
|
||||||
|
{
|
||||||
|
$this->term = $term;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
51
src/Form/BibliographyType.php
Normal file
51
src/Form/BibliographyType.php
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Form;
|
||||||
|
|
||||||
|
use App\Entity\Bibliography;
|
||||||
|
use Symfony\Component\Form\AbstractType;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||||
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
|
|
||||||
|
class BibliographyType extends AbstractType
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @todo Create status choices from enum
|
||||||
|
*/
|
||||||
|
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||||
|
{
|
||||||
|
$builder
|
||||||
|
->add('status', ChoiceType::class, [
|
||||||
|
'choices' => [
|
||||||
|
'-- Select status --' => '',
|
||||||
|
'Draft' => 1,
|
||||||
|
'Complete' => 2,
|
||||||
|
'Unindexed' => 3,
|
||||||
|
'Published' => 4,
|
||||||
|
],
|
||||||
|
'label' => 'Status (*)'
|
||||||
|
])
|
||||||
|
->add(
|
||||||
|
'editor',
|
||||||
|
TextType::class,
|
||||||
|
[
|
||||||
|
'label' => 'Editor(s) (*)'
|
||||||
|
]
|
||||||
|
)
|
||||||
|
->add('citation', TextType::class, ['label' => 'Citation (*)'])
|
||||||
|
->add('reference', TextareaType::class, ['label' => 'Reference (*)'])
|
||||||
|
->add('notes', TextareaType::class, ['label' => 'Editorial notes', 'required' => false])
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function configureOptions(OptionsResolver $resolver): void
|
||||||
|
{
|
||||||
|
$resolver->setDefaults([
|
||||||
|
'data_class' => Bibliography::class,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
@ -5,6 +5,8 @@ namespace App\Repository;
|
|||||||
use App\Entity\Bibliography;
|
use App\Entity\Bibliography;
|
||||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||||
use Doctrine\Persistence\ManagerRegistry;
|
use Doctrine\Persistence\ManagerRegistry;
|
||||||
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
|
use Doctrine\ORM\Query\ResultSetMappingBuilder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @extends ServiceEntityRepository<Bibliography>
|
* @extends ServiceEntityRepository<Bibliography>
|
||||||
@ -15,5 +17,24 @@ class BibliographyRepository extends ServiceEntityRepository
|
|||||||
{
|
{
|
||||||
parent::__construct($registry, Bibliography::class);
|
parent::__construct($registry, Bibliography::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function findAllCollection(int $collectionId): ?ArrayCollection
|
||||||
|
{
|
||||||
|
$rsm = new ResultSetMappingBuilder($this->getEntityManager());
|
||||||
|
$rsm->addRootEntityFromClassMetadata('App\Entity\Bibliography', 'b');
|
||||||
|
|
||||||
|
$query = $this->getEntityManager()->createNativeQuery(
|
||||||
|
"SELECT id, stato, editor, cit_bib, rif_bib FROM bibliography b
|
||||||
|
JOIN rel_riferimento_collezione
|
||||||
|
ON Bibliografia_id_bib = id
|
||||||
|
WHERE Collezione_id_coll = :collId",
|
||||||
|
$rsm
|
||||||
|
);
|
||||||
|
$query->setParameter('collId', $collectionId);
|
||||||
|
|
||||||
|
$bibliographies = new ArrayCollection($query->getResult());
|
||||||
|
|
||||||
|
return $bibliographies;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
20
src/Repository/CollectionRepository.php
Normal file
20
src/Repository/CollectionRepository.php
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Repository;
|
||||||
|
|
||||||
|
use App\Entity\Collection;
|
||||||
|
use App\Repository\BibliographyRepository;
|
||||||
|
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||||
|
use Doctrine\Persistence\ManagerRegistry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @extends ServiceEntityRepository<Collection>
|
||||||
|
*/
|
||||||
|
class CollectionRepository extends ServiceEntityRepository
|
||||||
|
{
|
||||||
|
public function __construct(ManagerRegistry $registry)
|
||||||
|
{
|
||||||
|
parent::__construct($registry, Collection::class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
18
src/Repository/VocabObjectTypeRepository.php
Normal file
18
src/Repository/VocabObjectTypeRepository.php
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Repository;
|
||||||
|
|
||||||
|
use App\Entity\VocabObjectType;
|
||||||
|
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||||
|
use Doctrine\Persistence\ManagerRegistry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @extends ServiceEntityRepository<VocabFuncContext>
|
||||||
|
*/
|
||||||
|
class VocabObjectTypeRepository extends ServiceEntityRepository
|
||||||
|
{
|
||||||
|
public function __construct(ManagerRegistry $registry)
|
||||||
|
{
|
||||||
|
parent::__construct($registry, VocabObjectType::class);
|
||||||
|
}
|
||||||
|
}
|
35
symfony.lock
35
symfony.lock
@ -1,4 +1,18 @@
|
|||||||
{
|
{
|
||||||
|
"api-platform/symfony": {
|
||||||
|
"version": "4.0",
|
||||||
|
"recipe": {
|
||||||
|
"repo": "github.com/symfony/recipes",
|
||||||
|
"branch": "main",
|
||||||
|
"version": "4.0",
|
||||||
|
"ref": "e9952e9f393c2d048f10a78f272cd35e807d972b"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"config/packages/api_platform.yaml",
|
||||||
|
"config/routes/api_platform.yaml",
|
||||||
|
"src/ApiResource/.gitignore"
|
||||||
|
]
|
||||||
|
},
|
||||||
"doctrine/doctrine-bundle": {
|
"doctrine/doctrine-bundle": {
|
||||||
"version": "2.13",
|
"version": "2.13",
|
||||||
"recipe": {
|
"recipe": {
|
||||||
@ -26,6 +40,18 @@
|
|||||||
"migrations/.gitignore"
|
"migrations/.gitignore"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"nelmio/cors-bundle": {
|
||||||
|
"version": "2.5",
|
||||||
|
"recipe": {
|
||||||
|
"repo": "github.com/symfony/recipes",
|
||||||
|
"branch": "main",
|
||||||
|
"version": "1.5",
|
||||||
|
"ref": "6bea22e6c564fba3a1391615cada1437d0bde39c"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"config/packages/nelmio_cors.yaml"
|
||||||
|
]
|
||||||
|
},
|
||||||
"phpunit/phpunit": {
|
"phpunit/phpunit": {
|
||||||
"version": "9.6",
|
"version": "9.6",
|
||||||
"recipe": {
|
"recipe": {
|
||||||
@ -248,6 +274,15 @@
|
|||||||
"templates/base.html.twig"
|
"templates/base.html.twig"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"symfony/uid": {
|
||||||
|
"version": "7.1",
|
||||||
|
"recipe": {
|
||||||
|
"repo": "github.com/symfony/recipes",
|
||||||
|
"branch": "main",
|
||||||
|
"version": "7.0",
|
||||||
|
"ref": "0df5844274d871b37fc3816c57a768ffc60a43a5"
|
||||||
|
}
|
||||||
|
},
|
||||||
"symfony/ux-turbo": {
|
"symfony/ux-turbo": {
|
||||||
"version": "v2.21.0"
|
"version": "v2.21.0"
|
||||||
},
|
},
|
||||||
|
72
templates/bibliography/create.html.twig
Normal file
72
templates/bibliography/create.html.twig
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
{% extends 'data_entry.html.twig' %}
|
||||||
|
|
||||||
|
{% block title %}Bibliography - Add new | ArCOA{% endblock %}
|
||||||
|
|
||||||
|
{% block rightpanel %}
|
||||||
|
<div class="container" style="max-width: 60vw">
|
||||||
|
<h1 class="is-size-1 mt-0 has-text-centered">Bibliography</h1>
|
||||||
|
<h2 class="is-size-3 mt-3 has-text-centered">Add new record</h2>
|
||||||
|
|
||||||
|
<p class="pt-4 pb-4 has-text-link has-text-weight-bold">Fields marked with (*) are mandatory</p>
|
||||||
|
<div class="card p-5 has-background-light">
|
||||||
|
{{ form_start(form) }}
|
||||||
|
<div class="field">
|
||||||
|
<label class="label">
|
||||||
|
{{ form_label(form.status) }}
|
||||||
|
</label>
|
||||||
|
<div class="select">
|
||||||
|
{{ form_widget(form.status) }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<label class="label">
|
||||||
|
{{ form_label(form.editor) }}
|
||||||
|
</label>
|
||||||
|
<div class="control">
|
||||||
|
{{
|
||||||
|
form_widget(
|
||||||
|
form.editor,
|
||||||
|
{'attr': {'class': 'input', 'placeholder': 'Name of the editor (mandatory)'}}
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<label class="label">
|
||||||
|
{{ form_label(form.citation) }}
|
||||||
|
</label>
|
||||||
|
<div class="control">
|
||||||
|
{{ form_widget(form.citation, {'attr': {'class': 'input'}}) }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<label class="label">
|
||||||
|
{{ form_label(form.reference) }}
|
||||||
|
</label>
|
||||||
|
<div class="control">
|
||||||
|
{{ form_widget(form.reference, {'attr': {'class': 'textarea'}}) }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<label class="label">
|
||||||
|
{{ form_label(form.notes) }}
|
||||||
|
</label>
|
||||||
|
<div class="control">
|
||||||
|
{{ form_widget(form.notes, {'attr': {'class': 'textarea'}}) }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="field is-grouped is-grouped-right mt-5">
|
||||||
|
<div class="control">
|
||||||
|
<button type="submit" class="button is-link">
|
||||||
|
Save
|
||||||
|
<span class="icon ml-3">
|
||||||
|
<i class="fa fa-save"></i>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{ form_end(form) }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script type="text/javascript" defer></script>
|
||||||
|
{% endblock %}
|
@ -1,6 +1,6 @@
|
|||||||
{% extends 'data_entry.html.twig' %}
|
{% extends 'data_entry.html.twig' %}
|
||||||
|
|
||||||
{% block title %}Bibliography | ArCOA{% endblock %}
|
{% block title %}Bibliography - {{ record.citation }} | ArCOA{% endblock %}
|
||||||
|
|
||||||
{% block rightpanel %}
|
{% block rightpanel %}
|
||||||
<div class="container" style="max-width: 60vw">
|
<div class="container" style="max-width: 60vw">
|
||||||
@ -16,6 +16,7 @@
|
|||||||
<p><strong>Editor:</strong> {{ record.editor }}</p>
|
<p><strong>Editor:</strong> {{ record.editor }}</p>
|
||||||
</div>
|
</div>
|
||||||
</article>
|
</article>
|
||||||
|
|
||||||
<div class="card p-5">
|
<div class="card p-5">
|
||||||
{% if is_granted('ROLE_ADMIN') or is_granted('ROLE_REVISOR') %}
|
{% if is_granted('ROLE_ADMIN') or is_granted('ROLE_REVISOR') %}
|
||||||
<div class="columns">
|
<div class="columns">
|
||||||
@ -27,12 +28,18 @@
|
|||||||
<i class="fa fa-edit"></i>
|
<i class="fa fa-edit"></i>
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
<button class="button is-danger ml-2">
|
<button class="button is-link">
|
||||||
|
Copy
|
||||||
|
<span class="icon ml-2">
|
||||||
|
<i class="fa fa-copy"></i>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
<a href="{{ path('app_bibliography_del', {'id' : record.id}) }}" class="button is-danger" id="del-record">
|
||||||
Delete
|
Delete
|
||||||
<span class="icon ml-2">
|
<span class="icon ml-2">
|
||||||
<i class="fa fa-trash"></i>
|
<i class="fa fa-trash"></i>
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@ -55,7 +62,56 @@
|
|||||||
<div class="data-tabs is-hidden" id="relations">
|
<div class="data-tabs is-hidden" id="relations">
|
||||||
Some stuff...
|
Some stuff...
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script type="text/javascript" defer></script>
|
|
||||||
|
<div class="modal">
|
||||||
|
<div class="modal-background"></div>
|
||||||
|
<div class="modal-card">
|
||||||
|
<header class="modal-card-head">
|
||||||
|
<span class="icon is-large has-text-warning">
|
||||||
|
<i class="fa fa-warning fa-2x"></i>
|
||||||
|
</span>
|
||||||
|
<p class="modal-card-title has-text-danger pl-2"><strong>Delete record?</strong></p>
|
||||||
|
<button class="delete" aria-label="close"></button>
|
||||||
|
</header>
|
||||||
|
<section class="modal-card-body">
|
||||||
|
<p class="is-size-5">This record will be permanently deleted. Proceed?</p>
|
||||||
|
</section>
|
||||||
|
<footer class="modal-card-foot">
|
||||||
|
<div class="buttons is-right">
|
||||||
|
<button class="button is-link" id="confirm-del">Confirm</button>
|
||||||
|
<button class="button is-light" id="cancel">Cancel</button>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script type="text/javascript" defer>
|
||||||
|
const del = document.querySelector('#del-record');
|
||||||
|
const delPath = del.href;
|
||||||
|
|
||||||
|
del.addEventListener('click', event => {
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
const modal = document.querySelector('.modal');
|
||||||
|
modal.classList.add('is-active');
|
||||||
|
|
||||||
|
modal.querySelector('.delete').addEventListener('click', () => {
|
||||||
|
modal.classList.remove('is-active');
|
||||||
|
});
|
||||||
|
modal.querySelector('.modal-background').addEventListener('click', () => {
|
||||||
|
modal.classList.remove('is-active');
|
||||||
|
});
|
||||||
|
modal.querySelector('#cancel').addEventListener('click', () => {
|
||||||
|
modal.classList.remove('is-active');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Proceed with deletion...
|
||||||
|
modal.querySelector('#confirm-del').addEventListener('click', () => {
|
||||||
|
location.href = delPath;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
@ -7,19 +7,25 @@
|
|||||||
<h1 class="is-size-1 mt-0 has-text-centered">Bibliography</h1>
|
<h1 class="is-size-1 mt-0 has-text-centered">Bibliography</h1>
|
||||||
<h2 class="is-size-3 mt-3 has-text-centered">Choose action</h2>
|
<h2 class="is-size-3 mt-3 has-text-centered">Choose action</h2>
|
||||||
|
|
||||||
|
{% for message in app.flashes('notice') %}
|
||||||
|
<div class=" mt-4 notification is-success">
|
||||||
|
<button class="delete"></button>
|
||||||
|
{{ message }}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
<div class="card p-5 mt-6 pt-6 pb-6">
|
<div class="card p-5 mt-6 pt-6 pb-6">
|
||||||
<div class="columns">
|
<div class="columns">
|
||||||
<div class="column is-half has-text-centered">
|
<div class="column is-half has-text-centered">
|
||||||
<a href="{{ path('app_bibliography_search') }}" class="button is-large">
|
<button class="button is-medium">
|
||||||
Search
|
Search
|
||||||
<span class="icon ml-2">
|
<span class="icon ml-2">
|
||||||
<i class="fa fa-search"></i>
|
<i class="fa fa-search"></i>
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
{% if is_granted('ROLE_ADMIN') or is_granted('ROLE_REVISOR') or is_granted('ROLE_EDITOR') %}
|
{% if is_granted('ROLE_ADMIN') or is_granted('ROLE_REVISOR') or is_granted('ROLE_EDITOR') %}
|
||||||
<div class="column has-text-centered">
|
<div class="column has-text-centered">
|
||||||
<a href="{{ path('app_bibliography_add') }}" class="button is-link is-large">
|
<a href="{{ path('app_bibliography_create') }}" class="button is-link is-medium">
|
||||||
Add new
|
Add new
|
||||||
<span class="icon ml-2">
|
<span class="icon ml-2">
|
||||||
<i class="fa fa-plus"></i>
|
<i class="fa fa-plus"></i>
|
||||||
@ -29,6 +35,54 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<h3 class="has-text-centered is-size-4 mt-6">Records</h3>
|
||||||
|
<p class="pt-4 pb-4"><strong>{{ count }} result(s) found</strong></p>
|
||||||
|
<table class="table is-hoverable is-fullwidth mt-5 has-text-centered results">
|
||||||
|
<tr>
|
||||||
|
<th>ID</th>
|
||||||
|
<th>Citation</th>
|
||||||
|
<th>Status</th>
|
||||||
|
<th>Editor</th>
|
||||||
|
<th>Reference</th>
|
||||||
|
<th>Last modified</th>
|
||||||
|
<th>Actions</th>
|
||||||
|
</tr>
|
||||||
|
{% for record in records %}
|
||||||
|
<tr>
|
||||||
|
<td><a href="{{ path('app_bibliography', {'id' : record.id}) }}">{{ record.id }}</a></td>
|
||||||
|
<td><a href="{{ path('app_bibliography', {'id' : record.id}) }}">{{ record.citation }}</a></td>
|
||||||
|
<td>{{ record.status }}</td>
|
||||||
|
<td>{{ record.owner }}</td>
|
||||||
|
<td style="max-width: 350px;">{{ record.reference }}</td>
|
||||||
|
<td>
|
||||||
|
{{ record.modifiedAt.format('Y-m-d') }}<br>
|
||||||
|
{{ record.editor }} at {{ record.modifiedAt.format('H:i:s') }}
|
||||||
|
</td>
|
||||||
|
<td style="min-width: 120px;">
|
||||||
|
<div class="buttons">
|
||||||
|
<button class="button is-small is-link" title="Edit record">
|
||||||
|
<span class="icon">
|
||||||
|
<i class="fa fa-edit"></i>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
<button class="button is-small is-danger" title="Delete record">
|
||||||
|
<span class="icon">
|
||||||
|
<i class="fa fa-trash"></i>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<script type="text/javascript" defer></script>
|
<script type="text/javascript" defer>
|
||||||
|
const delBtns = document.querySelectorAll('.delete');
|
||||||
|
for (let btn of delBtns) {
|
||||||
|
btn.addEventListener('click', function () {
|
||||||
|
this.parentElement.classList.add('is-hidden');
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
89
templates/collection/index.html.twig
Normal file
89
templates/collection/index.html.twig
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
{% extends 'data_entry.html.twig' %}
|
||||||
|
|
||||||
|
{% block title %}Collection - {{ record.title }} | ArCOA{% endblock %}
|
||||||
|
|
||||||
|
{% block rightpanel %}
|
||||||
|
<div class="container" style="max-width: 60vw">
|
||||||
|
<h1 class="is-size-1 mt-0 has-text-centered">Collection</h1>
|
||||||
|
<h2 class="is-size-3 mt-3 has-text-centered">{{ record.title }}</h2>
|
||||||
|
|
||||||
|
<article class="message is-info mt-3">
|
||||||
|
<div class="message-body">
|
||||||
|
<p>
|
||||||
|
<strong>Last modified:</strong> {{ record.modifiedAt.format('Y-m-d') }}
|
||||||
|
at {{ record.modifiedAt.format('H:i:s') }}
|
||||||
|
</p>
|
||||||
|
<p><strong>Editor:</strong> {{ record.editor }}</p>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
<div class="card p-5">
|
||||||
|
{% if is_granted('ROLE_ADMIN') or is_granted('ROLE_REVISOR') %}
|
||||||
|
<div class="columns">
|
||||||
|
<div class="column is-half"></div>
|
||||||
|
<div class="column has-text-right">
|
||||||
|
<button class="button is-link">
|
||||||
|
Edit
|
||||||
|
<span class="icon ml-2">
|
||||||
|
<i class="fa fa-edit"></i>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
<button class="button is-link">
|
||||||
|
Copy
|
||||||
|
<span class="icon ml-2">
|
||||||
|
<i class="fa fa-copy"></i>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
<button class="button is-danger">
|
||||||
|
Delete
|
||||||
|
<span class="icon ml-2">
|
||||||
|
<i class="fa fa-trash"></i>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
<div class="tabs is-boxed is-fullwidth">
|
||||||
|
<ul>
|
||||||
|
<li class="is-active">Record</li>
|
||||||
|
<li>Relations</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="data-tabs" id="record">
|
||||||
|
<table class="table is-fullwidth pt-4 record">
|
||||||
|
<tr><th>Record ID</th><td>{{ record.id }}</td></tr>
|
||||||
|
<tr><th>Status</th><td>{{ record.getStatus() }}</td></tr>
|
||||||
|
<tr><th>Editor(s)</th><td>{{ record.editor }}</td></tr>
|
||||||
|
<tr><th>Collection name</th><td>{{ record.title }}</td></tr>
|
||||||
|
<tr><th>Chronology</th><td>{{ record.chronology }}</td></tr>
|
||||||
|
<tr><th>Start date</th><td>{{ record.startDate }}</td></tr>
|
||||||
|
<tr><th>End date</th><td>{{ record.endDate }}</td></tr>
|
||||||
|
<tr><th>Description</th><td>{{ record.description }}</td></tr>
|
||||||
|
<tr><th>Short description</th><td>{{ record.shortDescription }}</td></tr>
|
||||||
|
<tr><th>External identifier(s)</th><td>{{ record.externalIdentifier }}</td></tr>
|
||||||
|
<tr><th>External link(s)</th><td>{{ record.link }}</td></tr>
|
||||||
|
<tr><th>Subject headings</th><td>{{ record.subjectHeadings }}</td></tr>
|
||||||
|
<tr><th>ArCOA URI</th><td>{{ record.uri }}</td></tr>
|
||||||
|
<tr><th>Editorial notes</th><td>{{ record.notes }}</td></tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div class="data-tabs is-hidden" id="relations">
|
||||||
|
{% if record.bibliographies %}
|
||||||
|
<p class="p-4 has-text-bold">Bibliographies</p>
|
||||||
|
<table class="table is-fullwidth is-hoverable has-text-centered">
|
||||||
|
<tr><th>ID</th><th>Status</th><th>Citation</th><th>Editor</th><th>Reference</th></tr>
|
||||||
|
{% for biblio in record.bibliographies %}
|
||||||
|
<tr>
|
||||||
|
<td><a href="{{ path('app_bibliography', {'id' : biblio.id}) }}">{{ biblio.id }}</a></td>
|
||||||
|
<td><a href="{{ path('app_bibliography', {'id' : biblio.id}) }}">{{ biblio.citation }}</a></td>
|
||||||
|
<td>{{ biblio.status }}</td>
|
||||||
|
<td>{{ biblio.editor }}</td>
|
||||||
|
<td>{{ biblio.reference }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script type="text/javascript" defer></script>
|
||||||
|
{% endblock %}
|
@ -3,9 +3,12 @@
|
|||||||
{% block body %}
|
{% block body %}
|
||||||
|
|
||||||
<nav class="navbar has-background-light">
|
<nav class="navbar has-background-light">
|
||||||
<div class="navbar-start">
|
<div class="navbar-start ml-4">
|
||||||
<a href="/" class="navbar-item">
|
<a href="/" class="navbar-item">
|
||||||
<strong>ArCOA Data Entry</strong>
|
<span class="icon is-clickable">
|
||||||
|
<i class="fa fa-home"></i>
|
||||||
|
</span>
|
||||||
|
<strong>ArCOA Digital Archive</strong>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
{% if app.user %}
|
{% if app.user %}
|
||||||
@ -56,8 +59,8 @@
|
|||||||
</nav>
|
</nav>
|
||||||
<div class="columns mb-0">
|
<div class="columns mb-0">
|
||||||
<div class="column is-one-fifth arcoa-menu mb-0">
|
<div class="column is-one-fifth arcoa-menu mb-0">
|
||||||
<aside class="menu pl-4">
|
<aside class="menu">
|
||||||
{% if 'ROLE_READER' not in app.user.roles %}
|
{% if 'ROLE_READER' not in app.user.roles %}
|
||||||
<p class="menu-label has-text-white mt-3 pt-5 pl-5 is-size-6">
|
<p class="menu-label has-text-white mt-3 pt-5 pl-5 is-size-6">
|
||||||
Vocabularies
|
Vocabularies
|
||||||
<span class="icon is-clickable pl-4" id="for-vocabs">
|
<span class="icon is-clickable pl-4" id="for-vocabs">
|
||||||
@ -146,7 +149,7 @@
|
|||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a>
|
<a href="{{ path('app_vocab_object_type') }}">
|
||||||
<span class="icon pr-3">
|
<span class="icon pr-3">
|
||||||
<i class="fa fa-plus"></i>
|
<i class="fa fa-plus"></i>
|
||||||
</span>
|
</span>
|
||||||
@ -209,6 +212,18 @@
|
|||||||
<i class="fa fa-angle-right"></i>
|
<i class="fa fa-angle-right"></i>
|
||||||
</span>
|
</span>
|
||||||
</p>
|
</p>
|
||||||
|
<ul class="pl-6 is-hidden has-text-white" id="records">
|
||||||
|
<li>
|
||||||
|
<a href="{{ path('app_bibliography_landing') }}">
|
||||||
|
Bibliography
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="">
|
||||||
|
Collection
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
</aside>
|
</aside>
|
||||||
</div>
|
</div>
|
||||||
<div class="column mt-6 mb-6">
|
<div class="column mt-6 mb-6">
|
||||||
|
@ -87,7 +87,7 @@
|
|||||||
terms.addEventListener('click', async (event) => {
|
terms.addEventListener('click', async (event) => {
|
||||||
const clicked = event.target;
|
const clicked = event.target;
|
||||||
|
|
||||||
if (clicked.classList.contains('is-danger')) {
|
if (clicked.getAttribute('data-id-delete')) {
|
||||||
const termId = clicked.getAttribute('data-id-delete');
|
const termId = clicked.getAttribute('data-id-delete');
|
||||||
|
|
||||||
const data = new FormData;
|
const data = new FormData;
|
||||||
@ -103,7 +103,7 @@
|
|||||||
if (res.status === 200) {
|
if (res.status === 200) {
|
||||||
notice.innerHTML = `
|
notice.innerHTML = `
|
||||||
<button class="delete"></button>
|
<button class="delete"></button>
|
||||||
Term updated successfully
|
Term deleted successfully
|
||||||
`;
|
`;
|
||||||
notice.classList.remove('is-hidden');
|
notice.classList.remove('is-hidden');
|
||||||
notice.querySelector('.delete').addEventListener('click', () => {
|
notice.querySelector('.delete').addEventListener('click', () => {
|
||||||
|
167
templates/vocab_object_type/index.html.twig
Normal file
167
templates/vocab_object_type/index.html.twig
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
{% extends 'data_entry.html.twig' %}
|
||||||
|
|
||||||
|
{% block title %}Vocab - Functional context | ArCOA{% endblock %}
|
||||||
|
|
||||||
|
{% block rightpanel %}
|
||||||
|
<div class="container" style="max-width: 50vw">
|
||||||
|
<h1 class="is-size-1 mt-0 has-text-centered">Vocabulary</h1>
|
||||||
|
<h2 class="is-size-3 mt-4 has-text-centered">Object type</h2>
|
||||||
|
|
||||||
|
<div class="container mt-6">
|
||||||
|
<!-- For AJAX calls... TODO: not working from controller? -->
|
||||||
|
{% if is_granted('ROLE_ADMIN') or is_granted('ROLE_REVISOR') %}
|
||||||
|
<form method="post" action="{{ path('app_vocab_func_context_add') }}">
|
||||||
|
<label class="label">Add new term</label>
|
||||||
|
<div class="field has-addons">
|
||||||
|
<div class="control">
|
||||||
|
<input class="input" name="_term" type="text" placeholder="Add new term">
|
||||||
|
</div>
|
||||||
|
<div class="control">
|
||||||
|
<button type="submit" class="button is-link">
|
||||||
|
Add
|
||||||
|
<span class="icon ml-3">
|
||||||
|
<i class="fa fa-plus"></i>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<div class="notification is-success is-hidden mt-5" id="ajax-success">
|
||||||
|
</div>
|
||||||
|
{% for message in app.flashes('notice') %}
|
||||||
|
<div class="notification is-success mt-5" id="server-success">
|
||||||
|
<button class="delete"></button>
|
||||||
|
{{ message }}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
<h3 class="mt-6 mb-5 is-size-5"><strong>Terms in vocabulary</strong></h3>
|
||||||
|
<table class="table is-fullwidth" id="terms">
|
||||||
|
<tr><th>Term</th>{% if is_granted('ROLE_ADMIN') or is_granted('ROLE_REVISOR') %}<th>Actions</th>{% endif %}</tr>
|
||||||
|
{% for term in terms %}
|
||||||
|
<tr data-row-id="{{ term.id }}">
|
||||||
|
<td>
|
||||||
|
<input class="input" type="text" value="{{ term.term }}" disabled data-term-id="{{ term.id }}" />
|
||||||
|
</td>
|
||||||
|
{% if is_granted('ROLE_ADMIN') or is_granted('ROLE_REVISOR') %}
|
||||||
|
<td>
|
||||||
|
<div class="buttons">
|
||||||
|
<button class="button is-primary is-hidden" data-id-save="{{ term.id }}">
|
||||||
|
Save
|
||||||
|
<span class="icon ml-2">
|
||||||
|
<i class="fa fa-save"></i>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
<button class="button is-link" data-id-edit="{{ term.id }}">
|
||||||
|
Edit
|
||||||
|
<span class="icon ml-2">
|
||||||
|
<i class="fa fa-edit"></i>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
<button class="button is-danger" data-id-delete="{{ term.id }}">
|
||||||
|
Delete
|
||||||
|
<span class="icon ml-2">
|
||||||
|
<i class="fa fa-trash"></i>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
{% endif %}
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script type="text/javascript" defer>
|
||||||
|
const terms = document.querySelector('#terms');
|
||||||
|
const serverNotice = document.querySelector('#server-success');
|
||||||
|
|
||||||
|
if (serverNotice) {
|
||||||
|
serverNotice.querySelector('.delete').addEventListener('click', () => {
|
||||||
|
serverNotice.remove();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
terms.addEventListener('click', async (event) => {
|
||||||
|
const clicked = event.target;
|
||||||
|
|
||||||
|
if (clicked.getAttribute('data-id-delete')) {
|
||||||
|
const termId = clicked.getAttribute('data-id-delete');
|
||||||
|
|
||||||
|
const data = new FormData;
|
||||||
|
data.append("_id", termId);
|
||||||
|
|
||||||
|
const res = await fetch("{{ path('app_vocab_func_context_del') }}", {
|
||||||
|
method: "POST",
|
||||||
|
body: data,
|
||||||
|
});
|
||||||
|
|
||||||
|
const notice = document.querySelector('#ajax-success');
|
||||||
|
|
||||||
|
if (res.status === 200) {
|
||||||
|
notice.innerHTML = `
|
||||||
|
<button class="delete"></button>
|
||||||
|
Term deleted successfully
|
||||||
|
`;
|
||||||
|
notice.classList.remove('is-hidden');
|
||||||
|
notice.querySelector('.delete').addEventListener('click', () => {
|
||||||
|
notice.classList.add('is-hidden');
|
||||||
|
});
|
||||||
|
const row = document.querySelector(`tr[data-row-id="${termId}"]`);
|
||||||
|
row.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clicked.getAttribute('data-id-edit')) {
|
||||||
|
const termId = clicked.getAttribute('data-id-edit');
|
||||||
|
const saveBtn = document.querySelector(`button[data-id-save="${termId}"]`);
|
||||||
|
const input = document.querySelector(`input[data-term-id="${termId}"]`);
|
||||||
|
input.disabled = input.disabled ? false : true;
|
||||||
|
saveBtn.classList.toggle('is-hidden');
|
||||||
|
|
||||||
|
clicked.classList.toggle('is-link');
|
||||||
|
|
||||||
|
if (!clicked.classList.contains('is-link')) {
|
||||||
|
clicked.innerHTML = `
|
||||||
|
Cancel
|
||||||
|
<span class="icon ml-2">
|
||||||
|
<i class="fa fa-times"></i>
|
||||||
|
</span>
|
||||||
|
`;
|
||||||
|
} else {
|
||||||
|
clicked.innerHTML = `
|
||||||
|
Edit
|
||||||
|
<span class="icon ml-2">
|
||||||
|
<i class="fa fa-edit"></i>
|
||||||
|
</span>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = new FormData;
|
||||||
|
data.append("_id", termId);
|
||||||
|
saveBtn.addEventListener('click', async () => {
|
||||||
|
data.append("_new_term", input.value);
|
||||||
|
const res = await fetch("{{ path('app_vocab_func_context_upd') }}", {
|
||||||
|
method: "POST",
|
||||||
|
body: data,
|
||||||
|
});
|
||||||
|
|
||||||
|
const notice = document.querySelector('#ajax-success');
|
||||||
|
|
||||||
|
if (res.status === 200) {
|
||||||
|
notice.innerHTML = `
|
||||||
|
<button class="delete"></button>
|
||||||
|
Term updated successfully
|
||||||
|
`;
|
||||||
|
notice.classList.remove('is-hidden');
|
||||||
|
notice.querySelector('.delete').addEventListener('click', () => {
|
||||||
|
notice.classList.add('is-hidden');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
Loading…
Reference in New Issue
Block a user