Implement project + remove useless config
This commit is contained in:
parent
3422412bbf
commit
34d1506483
@ -5,7 +5,4 @@ import './bootstrap.js';
|
|||||||
* This file will be included onto the page via the importmap() Twig function,
|
* This file will be included onto the page via the importmap() Twig function,
|
||||||
* which should already be in your base.html.twig.
|
* which should already be in your base.html.twig.
|
||||||
*/
|
*/
|
||||||
import './styles/app.css';
|
import './styles/app.css';
|
||||||
import API_CONFIG from "./config.js";
|
|
||||||
|
|
||||||
window.API_CONFIG = API_CONFIG;
|
|
@ -77,8 +77,8 @@ BIM.loadIfc = async function (buffer, name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const fragments = this.components.get(OBC.FragmentsManager);
|
const fragments = this.components.get(OBC.FragmentsManager);
|
||||||
|
|
||||||
const fragmentIfcLoader = this.components.get(OBC.IfcLoader);
|
const fragmentIfcLoader = this.components.get(OBC.IfcLoader);
|
||||||
|
const classifier = this.components.get(OBC.Classifier);
|
||||||
|
|
||||||
// NOTE: loads web-ifc WASM from https://unpkg.com/web-ifc@0.0.53/
|
// NOTE: loads web-ifc WASM from https://unpkg.com/web-ifc@0.0.53/
|
||||||
await fragmentIfcLoader.setup();
|
await fragmentIfcLoader.setup();
|
||||||
@ -107,14 +107,20 @@ BIM.loadIfc = async function (buffer, name) {
|
|||||||
model.name = name;
|
model.name = name;
|
||||||
this.world.scene.three.add(model);
|
this.world.scene.three.add(model);
|
||||||
|
|
||||||
|
// To actually add the model to the scene...
|
||||||
for (const fragment of model.items) {
|
for (const fragment of model.items) {
|
||||||
this.world.meshes.add(fragment.mesh);
|
this.world.meshes.add(fragment.mesh);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
classifier.byEntity(model);
|
||||||
|
const entities = classifier.list.entities;
|
||||||
|
|
||||||
// Useful?
|
// Useful?
|
||||||
this.fragments = fragments;
|
this.fragments = fragments;
|
||||||
this.model = model;
|
this.model = model;
|
||||||
|
|
||||||
|
console.log(entities);
|
||||||
|
|
||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,6 +153,7 @@ BIM.setupHighligther = async function (model) {
|
|||||||
li.innerHTML = `
|
li.innerHTML = `
|
||||||
<ul>
|
<ul>
|
||||||
<li><strong>Name</strong>: ${testProp['Name'].value}</span>
|
<li><strong>Name</strong>: ${testProp['Name'].value}</span>
|
||||||
|
<li><strong>Type</strong>: ${testProp['ObjectType']?.value}</span>
|
||||||
<li><strong>Tag</strong>: ${testProp['Tag'].value}</li>
|
<li><strong>Tag</strong>: ${testProp['Tag'].value}</li>
|
||||||
</ul>
|
</ul>
|
||||||
`;
|
`;
|
||||||
|
@ -1,4 +1,15 @@
|
|||||||
{
|
{
|
||||||
"controllers": [],
|
"controllers": {
|
||||||
|
"@symfony/ux-turbo": {
|
||||||
|
"turbo-core": {
|
||||||
|
"enabled": true,
|
||||||
|
"fetch": "eager"
|
||||||
|
},
|
||||||
|
"mercure-turbo-stream": {
|
||||||
|
"enabled": false,
|
||||||
|
"fetch": "eager"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"entrypoints": []
|
"entrypoints": []
|
||||||
}
|
}
|
||||||
|
@ -11,8 +11,6 @@ export default class extends Controller {
|
|||||||
'buildingForm'
|
'buildingForm'
|
||||||
];
|
];
|
||||||
|
|
||||||
API_BASE = window.API_CONFIG.dev;
|
|
||||||
|
|
||||||
async submit(event) {
|
async submit(event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
@ -22,10 +20,7 @@ export default class extends Controller {
|
|||||||
'POST'
|
'POST'
|
||||||
);
|
);
|
||||||
|
|
||||||
const res = await this.send(
|
const res = await this.send('/project/create', options);
|
||||||
`${this.API_BASE}/api/buildings`,
|
|
||||||
options
|
|
||||||
);
|
|
||||||
|
|
||||||
if (res.id) {
|
if (res.id) {
|
||||||
this.buildingTarget.setAttribute('data-id', res.id);
|
this.buildingTarget.setAttribute('data-id', res.id);
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
"symfony/serializer": "7.1.*",
|
"symfony/serializer": "7.1.*",
|
||||||
"symfony/stimulus-bundle": "^2.23",
|
"symfony/stimulus-bundle": "^2.23",
|
||||||
"symfony/twig-bundle": "7.1.*",
|
"symfony/twig-bundle": "7.1.*",
|
||||||
|
"symfony/ux-turbo": "^2.23",
|
||||||
"symfony/validator": "7.1.*",
|
"symfony/validator": "7.1.*",
|
||||||
"symfony/yaml": "7.1.*"
|
"symfony/yaml": "7.1.*"
|
||||||
},
|
},
|
||||||
|
104
composer.lock
generated
104
composer.lock
generated
@ -4,7 +4,7 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "4e98bff9162121f1c4fb1d257c7b7411",
|
"content-hash": "87b4a80041b3e1a8c74c5e68788219c9",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "api-platform/doctrine-common",
|
"name": "api-platform/doctrine-common",
|
||||||
@ -7024,6 +7024,104 @@
|
|||||||
],
|
],
|
||||||
"time": "2024-09-25T14:20:29+00:00"
|
"time": "2024-09-25T14:20:29+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "symfony/ux-turbo",
|
||||||
|
"version": "v2.23.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/symfony/ux-turbo.git",
|
||||||
|
"reference": "db96cf04d70a8c820671ce55530e8bf641ada33f"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/symfony/ux-turbo/zipball/db96cf04d70a8c820671ce55530e8bf641ada33f",
|
||||||
|
"reference": "db96cf04d70a8c820671ce55530e8bf641ada33f",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=8.1",
|
||||||
|
"symfony/stimulus-bundle": "^2.9.1"
|
||||||
|
},
|
||||||
|
"conflict": {
|
||||||
|
"symfony/flex": "<1.13"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"dbrekelmans/bdi": "dev-main",
|
||||||
|
"doctrine/doctrine-bundle": "^2.4.3",
|
||||||
|
"doctrine/orm": "^2.8 | 3.0",
|
||||||
|
"phpstan/phpstan": "^1.10",
|
||||||
|
"symfony/asset-mapper": "^6.4|^7.0",
|
||||||
|
"symfony/debug-bundle": "^5.4|^6.0|^7.0",
|
||||||
|
"symfony/expression-language": "^5.4|^6.0|^7.0",
|
||||||
|
"symfony/form": "^5.4|^6.0|^7.0",
|
||||||
|
"symfony/framework-bundle": "^6.4|^7.0",
|
||||||
|
"symfony/mercure-bundle": "^0.3.7",
|
||||||
|
"symfony/messenger": "^5.4|^6.0|^7.0",
|
||||||
|
"symfony/panther": "^2.1",
|
||||||
|
"symfony/phpunit-bridge": "^5.4|^6.0|^7.0",
|
||||||
|
"symfony/process": "^5.4|6.3.*|^7.0",
|
||||||
|
"symfony/property-access": "^5.4|^6.0|^7.0",
|
||||||
|
"symfony/security-core": "^5.4|^6.0|^7.0",
|
||||||
|
"symfony/stopwatch": "^5.4|^6.0|^7.0",
|
||||||
|
"symfony/twig-bundle": "^6.4|^7.0",
|
||||||
|
"symfony/ux-twig-component": "^2.21",
|
||||||
|
"symfony/web-profiler-bundle": "^5.4|^6.0|^7.0"
|
||||||
|
},
|
||||||
|
"type": "symfony-bundle",
|
||||||
|
"extra": {
|
||||||
|
"thanks": {
|
||||||
|
"url": "https://github.com/symfony/ux",
|
||||||
|
"name": "symfony/ux"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Symfony\\UX\\Turbo\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Kévin Dunglas",
|
||||||
|
"email": "kevin@dunglas.fr"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Symfony Community",
|
||||||
|
"homepage": "https://symfony.com/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Hotwire Turbo integration for Symfony",
|
||||||
|
"homepage": "https://symfony.com",
|
||||||
|
"keywords": [
|
||||||
|
"hotwire",
|
||||||
|
"javascript",
|
||||||
|
"mercure",
|
||||||
|
"symfony-ux",
|
||||||
|
"turbo",
|
||||||
|
"turbo-stream"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"source": "https://github.com/symfony/ux-turbo/tree/v2.23.0"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://symfony.com/sponsor",
|
||||||
|
"type": "custom"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/fabpot",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||||
|
"type": "tidelift"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2025-02-06T08:47:30+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/validator",
|
"name": "symfony/validator",
|
||||||
"version": "v7.1.11",
|
"version": "v7.1.11",
|
||||||
@ -9886,7 +9984,7 @@
|
|||||||
],
|
],
|
||||||
"aliases": [],
|
"aliases": [],
|
||||||
"minimum-stability": "stable",
|
"minimum-stability": "stable",
|
||||||
"stability-flags": {},
|
"stability-flags": [],
|
||||||
"prefer-stable": true,
|
"prefer-stable": true,
|
||||||
"prefer-lowest": false,
|
"prefer-lowest": false,
|
||||||
"platform": {
|
"platform": {
|
||||||
@ -9894,6 +9992,6 @@
|
|||||||
"ext-ctype": "*",
|
"ext-ctype": "*",
|
||||||
"ext-iconv": "*"
|
"ext-iconv": "*"
|
||||||
},
|
},
|
||||||
"platform-dev": {},
|
"platform-dev": [],
|
||||||
"plugin-api-version": "2.6.0"
|
"plugin-api-version": "2.6.0"
|
||||||
}
|
}
|
||||||
|
@ -11,4 +11,5 @@ return [
|
|||||||
Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true],
|
Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true],
|
||||||
Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true],
|
Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true],
|
||||||
Symfony\UX\StimulusBundle\StimulusBundle::class => ['all' => true],
|
Symfony\UX\StimulusBundle\StimulusBundle::class => ['all' => true],
|
||||||
|
Symfony\UX\Turbo\TurboBundle::class => ['all' => true],
|
||||||
];
|
];
|
||||||
|
@ -332,14 +332,17 @@ return [
|
|||||||
'@thatopen/components' => [
|
'@thatopen/components' => [
|
||||||
'version' => '2.4.5',
|
'version' => '2.4.5',
|
||||||
],
|
],
|
||||||
'three' => [
|
|
||||||
'version' => '0.160.1',
|
|
||||||
],
|
|
||||||
'@thatopen/components-front' => [
|
'@thatopen/components-front' => [
|
||||||
'version' => '2.4.4',
|
'version' => '2.4.5',
|
||||||
],
|
],
|
||||||
'bootstrap-icons/font/bootstrap-icons.min.css' => [
|
'bootstrap-icons/font/bootstrap-icons.min.css' => [
|
||||||
'version' => '1.11.3',
|
'version' => '1.11.3',
|
||||||
'type' => 'css',
|
'type' => 'css',
|
||||||
],
|
],
|
||||||
|
'three' => [
|
||||||
|
'version' => '0.160.1',
|
||||||
|
],
|
||||||
|
'@hotwired/turbo' => [
|
||||||
|
'version' => '7.3.0',
|
||||||
|
],
|
||||||
];
|
];
|
||||||
|
47
migrations/Version20250402061353.php
Normal file
47
migrations/Version20250402061353.php
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace DoctrineMigrations;
|
||||||
|
|
||||||
|
use Doctrine\DBAL\Schema\Schema;
|
||||||
|
use Doctrine\Migrations\AbstractMigration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Auto-generated Migration: Please modify to your needs!
|
||||||
|
*/
|
||||||
|
final class Version20250402061353 extends AbstractMigration
|
||||||
|
{
|
||||||
|
public function getDescription(): string
|
||||||
|
{
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function up(Schema $schema): void
|
||||||
|
{
|
||||||
|
// this up() migration is auto-generated, please modify it to your needs
|
||||||
|
$this->addSql(<<<'SQL'
|
||||||
|
ALTER TABLE project DROP FOREIGN KEY FK_2FB3D0EEA76ED395
|
||||||
|
SQL);
|
||||||
|
$this->addSql(<<<'SQL'
|
||||||
|
ALTER TABLE project DROP FOREIGN KEY FK_2FB3D0EE4D2A7E12
|
||||||
|
SQL);
|
||||||
|
$this->addSql(<<<'SQL'
|
||||||
|
DROP TABLE project
|
||||||
|
SQL);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(Schema $schema): void
|
||||||
|
{
|
||||||
|
// this down() migration is auto-generated, please modify it to your needs
|
||||||
|
$this->addSql(<<<'SQL'
|
||||||
|
CREATE TABLE project (id INT AUTO_INCREMENT NOT NULL, user_id INT NOT NULL, building_id INT NOT NULL, ifc VARCHAR(255) CHARACTER SET utf8mb4 DEFAULT NULL COLLATE `utf8mb4_unicode_ci`, INDEX IDX_2FB3D0EEA76ED395 (user_id), INDEX IDX_2FB3D0EE4D2A7E12 (building_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB COMMENT = ''
|
||||||
|
SQL);
|
||||||
|
$this->addSql(<<<'SQL'
|
||||||
|
ALTER TABLE project ADD CONSTRAINT FK_2FB3D0EEA76ED395 FOREIGN KEY (user_id) REFERENCES user (id)
|
||||||
|
SQL);
|
||||||
|
$this->addSql(<<<'SQL'
|
||||||
|
ALTER TABLE project ADD CONSTRAINT FK_2FB3D0EE4D2A7E12 FOREIGN KEY (building_id) REFERENCES architettura (id)
|
||||||
|
SQL);
|
||||||
|
}
|
||||||
|
}
|
47
migrations/Version20250402061726.php
Normal file
47
migrations/Version20250402061726.php
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace DoctrineMigrations;
|
||||||
|
|
||||||
|
use Doctrine\DBAL\Schema\Schema;
|
||||||
|
use Doctrine\Migrations\AbstractMigration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Auto-generated Migration: Please modify to your needs!
|
||||||
|
*/
|
||||||
|
final class Version20250402061726 extends AbstractMigration
|
||||||
|
{
|
||||||
|
public function getDescription(): string
|
||||||
|
{
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function up(Schema $schema): void
|
||||||
|
{
|
||||||
|
// this up() migration is auto-generated, please modify it to your needs
|
||||||
|
$this->addSql(<<<'SQL'
|
||||||
|
CREATE TABLE project (id INT AUTO_INCREMENT NOT NULL, user_id INT NOT NULL, building_id INT NOT NULL, ifc VARCHAR(255) DEFAULT NULL, created_at DATETIME NOT NULL COMMENT '(DC2Type:datetime_immutable)', last_modified DATETIME DEFAULT NULL COMMENT '(DC2Type:datetime_immutable)', INDEX IDX_2FB3D0EEA76ED395 (user_id), INDEX IDX_2FB3D0EE4D2A7E12 (building_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB
|
||||||
|
SQL);
|
||||||
|
$this->addSql(<<<'SQL'
|
||||||
|
ALTER TABLE project ADD CONSTRAINT FK_2FB3D0EEA76ED395 FOREIGN KEY (user_id) REFERENCES user (id)
|
||||||
|
SQL);
|
||||||
|
$this->addSql(<<<'SQL'
|
||||||
|
ALTER TABLE project ADD CONSTRAINT FK_2FB3D0EE4D2A7E12 FOREIGN KEY (building_id) REFERENCES architettura (id)
|
||||||
|
SQL);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(Schema $schema): void
|
||||||
|
{
|
||||||
|
// this down() migration is auto-generated, please modify it to your needs
|
||||||
|
$this->addSql(<<<'SQL'
|
||||||
|
ALTER TABLE project DROP FOREIGN KEY FK_2FB3D0EEA76ED395
|
||||||
|
SQL);
|
||||||
|
$this->addSql(<<<'SQL'
|
||||||
|
ALTER TABLE project DROP FOREIGN KEY FK_2FB3D0EE4D2A7E12
|
||||||
|
SQL);
|
||||||
|
$this->addSql(<<<'SQL'
|
||||||
|
DROP TABLE project
|
||||||
|
SQL);
|
||||||
|
}
|
||||||
|
}
|
70
src/Controller/ProjectController.php
Normal file
70
src/Controller/ProjectController.php
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Controller;
|
||||||
|
|
||||||
|
use App\Entity\Building;
|
||||||
|
use App\Entity\Project;
|
||||||
|
use App\Entity\User;
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
|
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Symfony\Component\Routing\Attribute\Route;
|
||||||
|
use Symfony\Component\Security\Http\Attribute\CurrentUser;
|
||||||
|
|
||||||
|
final class ProjectController extends AbstractController
|
||||||
|
{
|
||||||
|
#[Route('/project', name: 'app_project')]
|
||||||
|
public function index(): Response
|
||||||
|
{
|
||||||
|
return $this->render('project/index.html.twig', [
|
||||||
|
'controller_name' => 'ProjectController',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[Route('/projects', name: 'app_projects')]
|
||||||
|
public function projects(#[CurrentUser] User $user, EntityManagerInterface $em): Response
|
||||||
|
{
|
||||||
|
$repo = $em->getRepository(Project::class);
|
||||||
|
$projects = $repo->findBy(['user' => $user]);
|
||||||
|
|
||||||
|
return $this->render('project/index.html.twig', [
|
||||||
|
'controller_name' => 'ProjectController',
|
||||||
|
'projects' => $projects,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[Route('/project/create', name: 'app_project_create', methods: ['POST'])]
|
||||||
|
public function create(
|
||||||
|
EntityManagerInterface $em,
|
||||||
|
Request $request,
|
||||||
|
#[CurrentUser()]
|
||||||
|
User $user
|
||||||
|
): JsonResponse
|
||||||
|
{
|
||||||
|
$data = $request->getPayload();
|
||||||
|
$datetime = new \DateTimeImmutable();
|
||||||
|
|
||||||
|
$building = new Building();
|
||||||
|
$building->setName($data->get('name'));
|
||||||
|
$em->persist($building);
|
||||||
|
$em->flush();
|
||||||
|
|
||||||
|
$project = new Project();
|
||||||
|
$project->setUser($user);
|
||||||
|
$project->setBuilding($building);
|
||||||
|
$project->setCreatedAt($datetime);
|
||||||
|
$project->setLastModified($datetime);
|
||||||
|
$em->persist($project);
|
||||||
|
$em->flush();
|
||||||
|
|
||||||
|
$user->addProject($project);
|
||||||
|
|
||||||
|
// TODO Does the JSON Building object include its ID?
|
||||||
|
return $this->json([
|
||||||
|
'id' => $building->getId(),
|
||||||
|
'name' => $building->getName()]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -7,6 +7,8 @@ use ApiPlatform\Metadata\Get;
|
|||||||
use ApiPlatform\Metadata\Post;
|
use ApiPlatform\Metadata\Post;
|
||||||
use ApiPlatform\Metadata\GetCollection;
|
use ApiPlatform\Metadata\GetCollection;
|
||||||
use App\Repository\BuildingRepository;
|
use App\Repository\BuildingRepository;
|
||||||
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
|
use Doctrine\Common\Collections\Collection;
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
use Symfony\Component\Serializer\Attribute\Groups;
|
use Symfony\Component\Serializer\Attribute\Groups;
|
||||||
|
|
||||||
@ -33,6 +35,17 @@ class Building
|
|||||||
#[Groups(['building:list', 'building:item'])]
|
#[Groups(['building:list', 'building:item'])]
|
||||||
private ?string $name = null;
|
private ?string $name = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Collection<int, Project>
|
||||||
|
*/
|
||||||
|
#[ORM\OneToMany(targetEntity: Project::class, mappedBy: 'building')]
|
||||||
|
private Collection $projects;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->projects = new ArrayCollection();
|
||||||
|
}
|
||||||
|
|
||||||
public function getId(): ?int
|
public function getId(): ?int
|
||||||
{
|
{
|
||||||
return $this->id;
|
return $this->id;
|
||||||
@ -56,4 +69,34 @@ class Building
|
|||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Collection<int, Project>
|
||||||
|
*/
|
||||||
|
public function getProjects(): Collection
|
||||||
|
{
|
||||||
|
return $this->projects;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addProject(Project $project): static
|
||||||
|
{
|
||||||
|
if (!$this->projects->contains($project)) {
|
||||||
|
$this->projects->add($project);
|
||||||
|
$project->setBuilding($this);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function removeProject(Project $project): static
|
||||||
|
{
|
||||||
|
if ($this->projects->removeElement($project)) {
|
||||||
|
// set the owning side to null (unless already changed)
|
||||||
|
if ($project->getBuilding() === $this) {
|
||||||
|
$project->setBuilding(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,26 +2,12 @@
|
|||||||
|
|
||||||
namespace App\Entity;
|
namespace App\Entity;
|
||||||
|
|
||||||
use App\Repository\ProjectRepository;
|
|
||||||
use ApiPlatform\Metadata\ApiResource;
|
use ApiPlatform\Metadata\ApiResource;
|
||||||
use ApiPlatform\Metadata\Get;
|
use App\Repository\ProjectRepository;
|
||||||
use ApiPlatform\Metadata\Post;
|
|
||||||
use ApiPlatform\Metadata\GetCollection;
|
|
||||||
use Symfony\Component\Serializer\Attribute\Groups;
|
|
||||||
use Doctrine\DBAL\Types\Types;
|
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
|
||||||
#[ORM\Entity(repositoryClass: ProjectRepository::class)]
|
#[ORM\Entity(repositoryClass: ProjectRepository::class)]
|
||||||
#[ORM\Table(name: 'progetto')]
|
#[ApiResource]
|
||||||
#[ApiResource(
|
|
||||||
operations: [
|
|
||||||
new Get(normalizationContext: ['groups' => 'project:item']),
|
|
||||||
new GetCollection(normalizationContext: ['groups' => 'project:list']),
|
|
||||||
new Post(security: "is_granted('ROLE_USER')"),
|
|
||||||
],
|
|
||||||
order: ['name' => 'DESC'],
|
|
||||||
paginationEnabled: false,
|
|
||||||
)]
|
|
||||||
class Project
|
class Project
|
||||||
{
|
{
|
||||||
#[ORM\Id]
|
#[ORM\Id]
|
||||||
@ -29,51 +15,48 @@ class Project
|
|||||||
#[ORM\Column]
|
#[ORM\Column]
|
||||||
private ?int $id = null;
|
private ?int $id = null;
|
||||||
|
|
||||||
#[ORM\Column(type: Types::BIGINT, name: 'id_utente')]
|
#[ORM\ManyToOne(inversedBy: 'projects')]
|
||||||
#[ORM\OneToOne(User::class, )]
|
#[ORM\JoinColumn(nullable: false)]
|
||||||
private ?string $userid = null;
|
private ?User $user = null;
|
||||||
|
|
||||||
#[ORM\Column(type: Types::BIGINT, name: 'id_architettura')]
|
#[ORM\ManyToOne(inversedBy: 'projects')]
|
||||||
private ?string $buildingid = null;
|
#[ORM\JoinColumn(nullable: false)]
|
||||||
|
private ?Building $building = null;
|
||||||
|
|
||||||
#[ORM\Column(length: 255, nullable: true)]
|
#[ORM\Column(length: 255, nullable: true)]
|
||||||
/**
|
|
||||||
* @var string $ifc Path to IFC file for this project
|
|
||||||
*/
|
|
||||||
private ?string $ifc = null;
|
private ?string $ifc = null;
|
||||||
|
|
||||||
|
#[ORM\Column]
|
||||||
|
private ?\DateTimeImmutable $createdAt = null;
|
||||||
|
|
||||||
|
#[ORM\Column(nullable: true)]
|
||||||
|
private ?\DateTimeImmutable $lastModified = null;
|
||||||
|
|
||||||
public function getId(): ?int
|
public function getId(): ?int
|
||||||
{
|
{
|
||||||
return $this->id;
|
return $this->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setId(string $id): static
|
public function getUser(): ?User
|
||||||
{
|
{
|
||||||
$this->id = $id;
|
return $this->user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setUser(?User $user): static
|
||||||
|
{
|
||||||
|
$this->user = $user;
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getUserid(): ?string
|
public function getBuilding(): ?Building
|
||||||
{
|
{
|
||||||
return $this->userid;
|
return $this->building;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setUserid(string $userid): static
|
public function setBuilding(?Building $building): static
|
||||||
{
|
{
|
||||||
$this->userid = $userid;
|
$this->building = $building;
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getBuildingid(): ?string
|
|
||||||
{
|
|
||||||
return $this->buildingid;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setBuildingid(string $buildingid): static
|
|
||||||
{
|
|
||||||
$this->buildingid = $buildingid;
|
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@ -89,4 +72,28 @@ class Project
|
|||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getCreatedAt(): ?\DateTimeImmutable
|
||||||
|
{
|
||||||
|
return $this->createdAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setCreatedAt(\DateTimeImmutable $createdAt): static
|
||||||
|
{
|
||||||
|
$this->createdAt = $createdAt;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLastModified(): ?\DateTimeImmutable
|
||||||
|
{
|
||||||
|
return $this->lastModified;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setLastModified(?\DateTimeImmutable $lastModified): static
|
||||||
|
{
|
||||||
|
$this->lastModified = $lastModified;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
namespace App\Entity;
|
namespace App\Entity;
|
||||||
|
|
||||||
use App\Repository\UserRepository;
|
use App\Repository\UserRepository;
|
||||||
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
|
use Doctrine\Common\Collections\Collection;
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
|
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
|
||||||
use Symfony\Component\Security\Core\User\UserInterface;
|
use Symfony\Component\Security\Core\User\UserInterface;
|
||||||
@ -40,6 +42,17 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface
|
|||||||
#[ORM\Column]
|
#[ORM\Column]
|
||||||
private ?string $email = null;
|
private ?string $email = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Collection<int, Project>
|
||||||
|
*/
|
||||||
|
#[ORM\OneToMany(targetEntity: Project::class, mappedBy: 'user')]
|
||||||
|
private Collection $projects;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->projects = new ArrayCollection();
|
||||||
|
}
|
||||||
|
|
||||||
public function getId(): ?int
|
public function getId(): ?int
|
||||||
{
|
{
|
||||||
return $this->id;
|
return $this->id;
|
||||||
@ -149,4 +162,34 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface
|
|||||||
// If you store any temporary, sensitive data on the user, clear it here
|
// If you store any temporary, sensitive data on the user, clear it here
|
||||||
// $this->plainPassword = null;
|
// $this->plainPassword = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Collection<int, Project>
|
||||||
|
*/
|
||||||
|
public function getProjects(): Collection
|
||||||
|
{
|
||||||
|
return $this->projects;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addProject(Project $project): static
|
||||||
|
{
|
||||||
|
if (!$this->projects->contains($project)) {
|
||||||
|
$this->projects->add($project);
|
||||||
|
$project->setUser($this);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function removeProject(Project $project): static
|
||||||
|
{
|
||||||
|
if ($this->projects->removeElement($project)) {
|
||||||
|
// set the owning side to null (unless already changed)
|
||||||
|
if ($project->getUser() === $this) {
|
||||||
|
$project->setUser(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -211,6 +211,15 @@
|
|||||||
"ref": "0df5844274d871b37fc3816c57a768ffc60a43a5"
|
"ref": "0df5844274d871b37fc3816c57a768ffc60a43a5"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"symfony/ux-turbo": {
|
||||||
|
"version": "2.23",
|
||||||
|
"recipe": {
|
||||||
|
"repo": "github.com/symfony/recipes",
|
||||||
|
"branch": "main",
|
||||||
|
"version": "2.19",
|
||||||
|
"ref": "9dd2778a116b6e5e01e5e1582d03d5a9e82630de"
|
||||||
|
}
|
||||||
|
},
|
||||||
"symfony/validator": {
|
"symfony/validator": {
|
||||||
"version": "7.1",
|
"version": "7.1",
|
||||||
"recipe": {
|
"recipe": {
|
||||||
|
41
templates/project/index.html.twig
Normal file
41
templates/project/index.html.twig
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
{% extends 'base.html.twig' %}
|
||||||
|
|
||||||
|
{% block title %}Progetti | WebArchi{% endblock %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
{% include 'partials/navbar.html.twig' %}
|
||||||
|
<div class="container" style="max-width: 50vw">
|
||||||
|
<h1 class="is-size-1 mt-2 has-text-centered">Progetti</h1>
|
||||||
|
|
||||||
|
<table class="table is-striped is-fulldwidth m-6 is-hoverable has-text-centered">
|
||||||
|
<tr><th class="has-text-centered">Architettura</th><th class="has-text-centered">File IFC</th><th class="has-text-centered">Data creazione</th><th class="has-text-centered">Ultima modifica</th><th class="has-text-centered">Azioni</th></tr>
|
||||||
|
{% for project in projects %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ project.building.name }}</td>
|
||||||
|
<td>{{ project.ifc }}</td>
|
||||||
|
<td>{{ project.createdAt.format('Y-m-d') }}</td>
|
||||||
|
<td>{{ project.lastModified.format('Y-m-d H:i:s') }}</td>
|
||||||
|
<td>
|
||||||
|
<div class="buttons">
|
||||||
|
<button class="button is-small is-link" title="Modifica">
|
||||||
|
<span class="icon">
|
||||||
|
<i class="bi bi-pencil-fill"></i>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
<button class="button is-small is-danger" title="Elimina">
|
||||||
|
<span class="icon">
|
||||||
|
<i class="bi bi-trash-fill"></i>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
<button class="button is-small is-primary" title="Condividi">
|
||||||
|
<span class="icon">
|
||||||
|
<i class="bi bi-share-fill"></i>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
@ -19,7 +19,7 @@
|
|||||||
<p class="title is-4">{{ app.user.useridentifier }}</p>
|
<p class="title is-4">{{ app.user.useridentifier }}</p>
|
||||||
<p class="subtitle is-6">
|
<p class="subtitle is-6">
|
||||||
<span class="icon is-small">
|
<span class="icon is-small">
|
||||||
<i class="fa fa-envelope"></i>
|
<i class="bi bi-envelope"></i>
|
||||||
</span>
|
</span>
|
||||||
{{ app.user.email ?? 'no email' }}
|
{{ app.user.email ?? 'no email' }}
|
||||||
</p>
|
</p>
|
||||||
@ -40,7 +40,7 @@
|
|||||||
<div class="message-header">
|
<div class="message-header">
|
||||||
<p>
|
<p>
|
||||||
<span class="icon is-small is-size-5 mr-3">
|
<span class="icon is-small is-size-5 mr-3">
|
||||||
<i class="fa fa-info-circle"></i>
|
<i class="bi bi-info-circle"></i>
|
||||||
</span>
|
</span>
|
||||||
Permessi
|
Permessi
|
||||||
</p>
|
</p>
|
||||||
@ -48,12 +48,8 @@
|
|||||||
<div class="message-body">
|
<div class="message-body">
|
||||||
{% if 'ROLE_ADMIN' in app.user.roles %}
|
{% if 'ROLE_ADMIN' in app.user.roles %}
|
||||||
<p>
|
<p>
|
||||||
Administrators can create and edit users of the ArCOA data entry system,
|
Gli amministratori possono creare e modificare utenti in WebArchi,
|
||||||
including changing passwords and user roles, and disabling accounts.
|
cambiare password e ruoli utente, e disabilitare account.
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
They can perform all actions on all records and vocabularies
|
|
||||||
(create, view, edit, delete).
|
|
||||||
</p>
|
</p>
|
||||||
{% elseif 'ROLE_REVISOR' in app.user.roles %}
|
{% elseif 'ROLE_REVISOR' in app.user.roles %}
|
||||||
<p>Revisors can perform all actions (create, view, edit, delete) on all records and vocabs.</p>
|
<p>Revisors can perform all actions (create, view, edit, delete) on all records and vocabs.</p>
|
||||||
|
16
tests/Controller/ProjectControllerTest.php
Normal file
16
tests/Controller/ProjectControllerTest.php
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Tests\Controller;
|
||||||
|
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
|
||||||
|
|
||||||
|
final class ProjectControllerTest extends WebTestCase
|
||||||
|
{
|
||||||
|
public function testIndex(): void
|
||||||
|
{
|
||||||
|
$client = static::createClient();
|
||||||
|
$client->request('GET', '/project');
|
||||||
|
|
||||||
|
self::assertResponseIsSuccessful();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user