diff --git a/.gitignore b/.gitignore
index 7ff4b13..4bd5e82 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,3 +13,8 @@
/phpunit.xml
.phpunit.result.cache
###< phpunit/phpunit ###
+
+###> symfony/asset-mapper ###
+/public/assets/
+/assets/vendor/
+###< symfony/asset-mapper ###
diff --git a/.idea/php.xml b/.idea/php.xml
index 8ffcd24..9ce27bb 100644
--- a/.idea/php.xml
+++ b/.idea/php.xml
@@ -109,6 +109,9 @@
+
+
+
diff --git a/.idea/symfony_crud.iml b/.idea/symfony_crud.iml
index 82cda5d..f0de60d 100644
--- a/.idea/symfony_crud.iml
+++ b/.idea/symfony_crud.iml
@@ -3,6 +3,7 @@
+
@@ -102,6 +103,9 @@
+
+
+
diff --git a/composer.json b/composer.json
index 202f989..d0d3a86 100644
--- a/composer.json
+++ b/composer.json
@@ -13,6 +13,7 @@
"phpdocumentor/reflection-docblock": "^5.3",
"phpstan/phpdoc-parser": "^1.25",
"symfony/asset": "7.0.*",
+ "symfony/asset-mapper": "^7.0",
"symfony/console": "7.0.*",
"symfony/dotenv": "7.0.*",
"symfony/flex": "^2",
@@ -57,7 +58,8 @@
"scripts": {
"auto-scripts": {
"cache:clear": "symfony-cmd",
- "assets:install %PUBLIC_DIR%": "symfony-cmd"
+ "assets:install %PUBLIC_DIR%": "symfony-cmd",
+ "importmap:install": "symfony-cmd"
},
"post-install-cmd": [
"@auto-scripts"
diff --git a/composer.lock b/composer.lock
index 80134c7..c537f68 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,8 +4,89 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "948a7d7c4f60d2cead1e331bc1f1c5b4",
+ "content-hash": "717ed6c3538dfaff4c72623709f0f132",
"packages": [
+ {
+ "name": "composer/semver",
+ "version": "3.4.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/composer/semver.git",
+ "reference": "35e8d0af4486141bc745f23a29cc2091eb624a32"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/composer/semver/zipball/35e8d0af4486141bc745f23a29cc2091eb624a32",
+ "reference": "35e8d0af4486141bc745f23a29cc2091eb624a32",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.3.2 || ^7.0 || ^8.0"
+ },
+ "require-dev": {
+ "phpstan/phpstan": "^1.4",
+ "symfony/phpunit-bridge": "^4.2 || ^5"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "3.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Composer\\Semver\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nils Adermann",
+ "email": "naderman@naderman.de",
+ "homepage": "http://www.naderman.de"
+ },
+ {
+ "name": "Jordi Boggiano",
+ "email": "j.boggiano@seld.be",
+ "homepage": "http://seld.be"
+ },
+ {
+ "name": "Rob Bast",
+ "email": "rob.bast@gmail.com",
+ "homepage": "http://robbast.nl"
+ }
+ ],
+ "description": "Semver library that offers utilities, version constraint parsing and validation.",
+ "keywords": [
+ "semantic",
+ "semver",
+ "validation",
+ "versioning"
+ ],
+ "support": {
+ "irc": "ircs://irc.libera.chat:6697/composer",
+ "issues": "https://github.com/composer/semver/issues",
+ "source": "https://github.com/composer/semver/tree/3.4.0"
+ },
+ "funding": [
+ {
+ "url": "https://packagist.com",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/composer",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/composer/composer",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-08-31T09:50:34+00:00"
+ },
{
"name": "doctrine/cache",
"version": "2.2.0",
@@ -1863,6 +1944,84 @@
],
"time": "2023-10-31T17:59:56+00:00"
},
+ {
+ "name": "symfony/asset-mapper",
+ "version": "v7.0.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/asset-mapper.git",
+ "reference": "537b9575df2f0a809abe9dd1117bb4ec578f7a21"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/asset-mapper/zipball/537b9575df2f0a809abe9dd1117bb4ec578f7a21",
+ "reference": "537b9575df2f0a809abe9dd1117bb4ec578f7a21",
+ "shasum": ""
+ },
+ "require": {
+ "composer/semver": "^3.0",
+ "php": ">=8.2",
+ "symfony/filesystem": "^6.4|^7.0",
+ "symfony/http-client": "^6.4|^7.0"
+ },
+ "conflict": {
+ "symfony/framework-bundle": "<6.4"
+ },
+ "require-dev": {
+ "symfony/asset": "^6.4|^7.0",
+ "symfony/browser-kit": "^6.4|^7.0",
+ "symfony/console": "^6.4|^7.0",
+ "symfony/event-dispatcher-contracts": "^3.0",
+ "symfony/finder": "^6.4|^7.0",
+ "symfony/framework-bundle": "^6.4|^7.0",
+ "symfony/http-foundation": "^6.4|^7.0",
+ "symfony/http-kernel": "^6.4|^7.0",
+ "symfony/web-link": "^6.4|^7.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\AssetMapper\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Maps directories of assets & makes them available in a public directory with versioned filenames.",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/asset-mapper/tree/v7.0.3"
+ },
+ "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": "2024-01-23T19:26:06+00:00"
+ },
{
"name": "symfony/cache",
"version": "v7.0.2",
@@ -3173,6 +3332,176 @@
],
"time": "2023-12-29T15:37:40+00:00"
},
+ {
+ "name": "symfony/http-client",
+ "version": "v7.0.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/http-client.git",
+ "reference": "3d2605c07cd14aec294f72f5bf8147702f7a5ada"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/http-client/zipball/3d2605c07cd14aec294f72f5bf8147702f7a5ada",
+ "reference": "3d2605c07cd14aec294f72f5bf8147702f7a5ada",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.2",
+ "psr/log": "^1|^2|^3",
+ "symfony/http-client-contracts": "^3",
+ "symfony/service-contracts": "^2.5|^3"
+ },
+ "conflict": {
+ "php-http/discovery": "<1.15",
+ "symfony/http-foundation": "<6.4"
+ },
+ "provide": {
+ "php-http/async-client-implementation": "*",
+ "php-http/client-implementation": "*",
+ "psr/http-client-implementation": "1.0",
+ "symfony/http-client-implementation": "3.0"
+ },
+ "require-dev": {
+ "amphp/amp": "^2.5",
+ "amphp/http-client": "^4.2.1",
+ "amphp/http-tunnel": "^1.0",
+ "amphp/socket": "^1.1",
+ "guzzlehttp/promises": "^1.4",
+ "nyholm/psr7": "^1.0",
+ "php-http/httplug": "^1.0|^2.0",
+ "psr/http-client": "^1.0",
+ "symfony/dependency-injection": "^6.4|^7.0",
+ "symfony/http-kernel": "^6.4|^7.0",
+ "symfony/messenger": "^6.4|^7.0",
+ "symfony/process": "^6.4|^7.0",
+ "symfony/stopwatch": "^6.4|^7.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\HttpClient\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Provides powerful methods to fetch HTTP resources synchronously or asynchronously",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "http"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/http-client/tree/v7.0.3"
+ },
+ "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": "2024-01-29T15:41:16+00:00"
+ },
+ {
+ "name": "symfony/http-client-contracts",
+ "version": "v3.4.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/http-client-contracts.git",
+ "reference": "1ee70e699b41909c209a0c930f11034b93578654"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/1ee70e699b41909c209a0c930f11034b93578654",
+ "reference": "1ee70e699b41909c209a0c930f11034b93578654",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "3.4-dev"
+ },
+ "thanks": {
+ "name": "symfony/contracts",
+ "url": "https://github.com/symfony/contracts"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Contracts\\HttpClient\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Test/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Generic abstractions related to HTTP clients",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "abstractions",
+ "contracts",
+ "decoupling",
+ "interfaces",
+ "interoperability",
+ "standards"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/http-client-contracts/tree/v3.4.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": "2023-07-30T20:28:31+00:00"
+ },
{
"name": "symfony/http-foundation",
"version": "v7.0.0",
diff --git a/public/js/buttonActions.js b/public/js/buttonActions.js
new file mode 100644
index 0000000..08035eb
--- /dev/null
+++ b/public/js/buttonActions.js
@@ -0,0 +1,27 @@
+function setEditButtonOnClick(editButton, printer) {
+ editButton.onclick = function () {
+ document.getElementById('editInputName').value = printer.name;
+ document.getElementById('editInputPrice').value = printer.price;
+ document.getElementById('editInputBuildVolume').value = printer.build_volume;
+ document.getElementById('editInputMaxSpeed').value = printer.max_speed;
+
+ document.getElementById('editModalConfirm').setAttribute('onclick', `editPrinter(${printer.id})`);
+ }
+}
+
+function setButtonAttributes(buttonType, modal) {
+ const button = document.createElement('button');
+ button.setAttribute('data-bs-target', modal);
+ button.setAttribute('data-bs-toggle', 'modal');
+ button.setAttribute('class', `btn ${buttonType}`);
+ return button;
+}
+
+function setViewButtonOnClick(viewButton, printer) {
+ viewButton.onclick = function () {
+ document.getElementById('viewModalName').textContent = `Name: ${printer.name}`;
+ document.getElementById('viewModalPrice').textContent = `Price: ${printer.price.toFixed(2)}$`;
+ document.getElementById('viewModalBuildVolume').textContent = `Build Volume: ${printer.build_volume}`;
+ document.getElementById('viewModalMaxSpeed').textContent = `Max Speed: ${printer.max_speed}mm/s`;
+ }
+}
\ No newline at end of file
diff --git a/public/js/frontend.js b/public/js/frontend.js
index 5737474..93ab559 100644
--- a/public/js/frontend.js
+++ b/public/js/frontend.js
@@ -1,193 +1,3 @@
-function addTableData(tableRow, data, id, printer) {
- const tableData = document.createElement('td');
- tableData.id = `printer${printer.id}:${id}`;
- tableData.textContent = data;
-
- tableRow.appendChild(tableData);
-}
-
-function removePrinterFromTable(printerId) {
- const tableBody = document.getElementById(`printer${printerId}`);
- tableBody.remove();
-}
-
-function deletePrinter(printerId) {
- fetch(`/printer/${printerId}`, {method: 'DELETE'}).then(response => {
- if (response.ok) {
- removePrinterFromTable(printerId);
- }
- });
-}
-
-
-function addDeleteButton(tableData, printer) {
- const deleteButton = setButtonAttributes('btn-danger');
- deleteButton.textContent = 'Delete';
-
- deleteButton.onclick = function () {
- document.getElementById('deleteModalText').textContent = `Are you sure that you want to delete ${printer.name}?`;
- document.getElementById('deleteModalConfirm').setAttribute('onclick', `deletePrinter(${printer.id})`);
- }
-
- tableData.appendChild(deleteButton);
-}
-
-function setButtonAttributes(buttonType) {
- const button = document.createElement('button');
- button.setAttribute('data-bs-target', '#viewModal');
- button.setAttribute('data-bs-toggle', 'modal');
- button.setAttribute('class', `btn ${buttonType}`);
- return button;
-}
-
-function setViewButtonOnClick(viewButton, printer) {
- viewButton.onclick = function () {
- document.getElementById('viewModalName').textContent = `Name: ${printer.name}`;
- document.getElementById('viewModalPrice').textContent = `Price: ${printer.price.toFixed(2)}$`;
- document.getElementById('viewModalBuildVolume').textContent = `Build Volume: ${printer.build_volume}`;
- document.getElementById('viewModalMaxSpeed').textContent = `Max Speed: ${printer.max_speed}mm/s`;
- }
-}
-
-function addViewButton(tableData, printer) {
- const viewButton = setButtonAttributes('btn-primary');
- viewButton.textContent = 'View';
- viewButton.id = `printer${printer.id}:viewButton`;
-
- setViewButtonOnClick(viewButton, printer);
-
- tableData.appendChild(viewButton);
-}
-
-function setEditButtonOnClick(editButton, printer) {
- editButton.onclick = function () {
- document.getElementById('editInputName').value = printer.name;
- document.getElementById('editInputPrice').value = printer.price;
- document.getElementById('editInputBuildVolume').value = printer.build_volume;
- document.getElementById('editInputMaxSpeed').value = printer.max_speed;
-
- document.getElementById('editModalConfirm').setAttribute('onclick', `editPrinter(${printer.id})`);
- }
-}
-
-function getEditModalValues() {
- const nameInput = document.getElementById('editInputName').value;
- const priceInput = document.getElementById('editInputPrice').value;
- const buildVolumeInput = document.getElementById('editInputBuildVolume').value;
- const maxSpeedInput = document.getElementById('editInputMaxSpeed').value;
- return {nameInput, priceInput, buildVolumeInput, maxSpeedInput};
-}
-
-function editPrinter(printerId) {
- const {nameInput, priceInput, buildVolumeInput, maxSpeedInput} = getEditModalValues();
-
- fetch(`/printer/${printerId}`, {method: 'PUT', body: JSON.stringify({
- name: nameInput,
- price: Number(priceInput),
- build_volume: buildVolumeInput,
- max_speed: Number(maxSpeedInput),
- })}).then(response => {
- if (response.ok) {
- response.json().then(printer => {
- document.getElementById(`printer${printer.id}:name`).textContent = printer.name;
- document.getElementById(`printer${printer.id}:price`).textContent = printer.price;
- document.getElementById(`printer${printer.id}:build_volume`).textContent = printer.build_volume;
-
- document.getElementById(`printer${printer.id}:max_speed`).textContent = printer.max_speed;
-
- const editButton = document.getElementById(`printer${printer.id}:editButton`);
- setEditButtonOnClick(editButton, printer);
-
- const viewButton = document.getElementById(`printer${printer.id}:viewButton`);
- setViewButtonOnClick(viewButton, printer);
- });
- }
- });
-}
-
-function addEditButton(tableData, printer) {
- const editButton = document.createElement('button');
- editButton.setAttribute('data-bs-target', '#editModal');
- editButton.setAttribute('data-bs-toggle', 'modal');
- editButton.setAttribute('class', 'btn btn-primary');
- editButton.id = `printer${printer.id}:editButton`
- editButton.textContent = 'Edit';
-
- setEditButtonOnClick(editButton, printer);
-
- tableData.appendChild(editButton);
-}
-
-function addTableActions(tableRow, printer) {
- const tableData = document.createElement('td');
-
- addViewButton(tableData, printer);
- addEditButton(tableData, printer);
- addDeleteButton(tableData, printer);
-
- tableRow.appendChild(tableData);
-}
-
-function addPrinterToTable(tableBody, printer) {
- const tableRow = document.createElement('tr');
- addTableData(tableRow, printer.name, 'name', printer);
- addTableData(tableRow, `${printer.price.toFixed(2)}$`, 'price', printer);
- addTableData(tableRow, printer.build_volume, 'build_volume', printer);
- addTableData(tableRow, printer.max_speed + 'mm/s', 'max_speed', printer);
-
- addTableActions(tableRow, printer);
-
- tableRow.id = `printer${printer.id}`;
- tableBody.appendChild(tableRow);
-}
-
-function loadTable() {
- fetch('/printer', {method: 'GET'}).then(response => {
- response.json().then(json => {
- const tableBody = document.getElementById('table-body');
- tableBody.innerHTML = null;
- for (printer of json) {
- addPrinterToTable(tableBody, printer);
- }
- });
- });
-}
-
-function clearCreateModalValues() {
- document.getElementById('inputName').value = '';
- document.getElementById('inputPrice').value = '';
- document.getElementById('inputBuildVolume').value = '';
- document.getElementById('inputMaxSpeed').value = '';
-}
-
-function getCreateModalValues() {
- const nameInput = document.getElementById('inputName').value;
- const priceInput = document.getElementById('inputPrice').value;
- const buildVolumeInput = document.getElementById('inputBuildVolume').value;
- const maxSpeedInput = document.getElementById('inputMaxSpeed').value;
- return {nameInput, priceInput, buildVolumeInput, maxSpeedInput};
-}
-
-function createPrinter() {
- const {nameInput, priceInput, buildVolumeInput, maxSpeedInput} = getCreateModalValues();
-
- clearCreateModalValues();
-
- fetch('/printer', {method: 'POST', body: JSON.stringify({
- name: nameInput,
- price: Number(priceInput),
- build_volume: buildVolumeInput,
- max_speed: Number(maxSpeedInput),
- })}).then(response => {
- if (response.ok) {
- const tableBody = document.getElementById('table-body');
- response.json().then(printer => {
- addPrinterToTable(tableBody, printer);
- });
- }
- });
-}
-
document.addEventListener("DOMContentLoaded", function() {
loadTable();
});
\ No newline at end of file
diff --git a/public/js/modals.js b/public/js/modals.js
new file mode 100644
index 0000000..8f34826
--- /dev/null
+++ b/public/js/modals.js
@@ -0,0 +1,22 @@
+function getEditModalValues() {
+ const nameInput = document.getElementById('editInputName').value;
+ const priceInput = document.getElementById('editInputPrice').value;
+ const buildVolumeInput = document.getElementById('editInputBuildVolume').value;
+ const maxSpeedInput = document.getElementById('editInputMaxSpeed').value;
+ return {nameInput, priceInput, buildVolumeInput, maxSpeedInput};
+}
+
+function clearCreateModalValues() {
+ document.getElementById('inputName').value = '';
+ document.getElementById('inputPrice').value = '';
+ document.getElementById('inputBuildVolume').value = '';
+ document.getElementById('inputMaxSpeed').value = '';
+}
+
+function getCreateModalValues() {
+ const nameInput = document.getElementById('inputName').value;
+ const priceInput = document.getElementById('inputPrice').value;
+ const buildVolumeInput = document.getElementById('inputBuildVolume').value;
+ const maxSpeedInput = document.getElementById('inputMaxSpeed').value;
+ return {nameInput, priceInput, buildVolumeInput, maxSpeedInput};
+}
diff --git a/public/js/printerApi.js b/public/js/printerApi.js
new file mode 100644
index 0000000..3621fb3
--- /dev/null
+++ b/public/js/printerApi.js
@@ -0,0 +1,54 @@
+function createPrinter() {
+ const {nameInput, priceInput, buildVolumeInput, maxSpeedInput} = getCreateModalValues();
+
+ clearCreateModalValues();
+
+ fetch('/printer', {method: 'POST', body: JSON.stringify({
+ name: nameInput,
+ price: Number(priceInput),
+ build_volume: buildVolumeInput,
+ max_speed: Number(maxSpeedInput),
+ })}).then(response => {
+ if (response.ok) {
+ const tableBody = document.getElementById('table-body');
+ response.json().then(printer => {
+ addPrinterToTable(tableBody, printer);
+ });
+ }
+ });
+}
+
+function editPrinter(printerId) {
+ const {nameInput, priceInput, buildVolumeInput, maxSpeedInput} = getEditModalValues();
+
+ fetch(`/printer/${printerId}`, {method: 'PUT', body: JSON.stringify({
+ name: nameInput,
+ price: Number(priceInput),
+ build_volume: buildVolumeInput,
+ max_speed: Number(maxSpeedInput),
+ })}).then(response => {
+ if (response.ok) {
+ response.json().then(printer => {
+ document.getElementById(`printer${printer.id}:name`).textContent = printer.name;
+ document.getElementById(`printer${printer.id}:price`).textContent = printer.price;
+ document.getElementById(`printer${printer.id}:build_volume`).textContent = printer.build_volume;
+
+ document.getElementById(`printer${printer.id}:max_speed`).textContent = printer.max_speed;
+
+ const editButton = document.getElementById(`printer${printer.id}:editButton`);
+ setEditButtonOnClick(editButton, printer);
+
+ const viewButton = document.getElementById(`printer${printer.id}:viewButton`);
+ setViewButtonOnClick(viewButton, printer);
+ });
+ }
+ });
+}
+
+function deletePrinter(printerId) {
+ fetch(`/printer/${printerId}`, {method: 'DELETE'}).then(response => {
+ if (response.ok) {
+ removePrinterFromTable(printerId);
+ }
+ });
+}
diff --git a/public/js/tableActions.js b/public/js/tableActions.js
new file mode 100644
index 0000000..9d1ef96
--- /dev/null
+++ b/public/js/tableActions.js
@@ -0,0 +1,79 @@
+function loadTable() {
+ fetch('/printer', {method: 'GET'}).then(response => {
+ response.json().then(json => {
+ const tableBody = document.getElementById('table-body');
+ tableBody.innerHTML = null;
+ for (printer of json) {
+ addPrinterToTable(tableBody, printer);
+ }
+ });
+ });
+}
+
+function addPrinterToTable(tableBody, printer) {
+ const tableRow = document.createElement('tr');
+ addTableData(tableRow, printer.name, 'name', printer);
+ addTableData(tableRow, `${printer.price.toFixed(2)}$`, 'price', printer);
+ addTableData(tableRow, printer.build_volume, 'build_volume', printer);
+ addTableData(tableRow, printer.max_speed + 'mm/s', 'max_speed', printer);
+
+ addTableActions(tableRow, printer);
+
+ tableRow.id = `printer${printer.id}`;
+ tableBody.appendChild(tableRow);
+}
+
+function addTableActions(tableRow, printer) {
+ const tableData = document.createElement('td');
+
+ addViewButton(tableData, printer);
+ addEditButton(tableData, printer);
+ addDeleteButton(tableData, printer);
+
+ tableRow.appendChild(tableData);
+}
+
+function addEditButton(tableData, printer) {
+ const editButton = setButtonAttributes('btn-primary', '#editModal');
+ editButton.id = `printer${printer.id}:editButton`
+ editButton.textContent = 'Edit';
+
+ setEditButtonOnClick(editButton, printer);
+
+ tableData.appendChild(editButton);
+}
+
+function addViewButton(tableData, printer) {
+ const viewButton = setButtonAttributes('btn-primary', '#viewModal');
+ viewButton.textContent = 'View';
+ viewButton.id = `printer${printer.id}:viewButton`;
+
+ setViewButtonOnClick(viewButton, printer);
+
+ tableData.appendChild(viewButton);
+}
+
+function addDeleteButton(tableData, printer) {
+ const deleteButton = setButtonAttributes('btn-danger', '#deleteModal');
+ deleteButton.textContent = 'Delete';
+
+ deleteButton.onclick = function () {
+ document.getElementById('deleteModalText').textContent = `Are you sure that you want to delete ${printer.name}?`;
+ document.getElementById('deleteModalConfirm').setAttribute('onclick', `deletePrinter(${printer.id})`);
+ }
+
+ tableData.appendChild(deleteButton);
+}
+
+function addTableData(tableRow, data, id, printer) {
+ const tableData = document.createElement('td');
+ tableData.id = `printer${printer.id}:${id}`;
+ tableData.textContent = data;
+
+ tableRow.appendChild(tableData);
+}
+
+function removePrinterFromTable(printerId) {
+ const tableBody = document.getElementById(`printer${printerId}`);
+ tableBody.remove();
+}
\ No newline at end of file
diff --git a/symfony.lock b/symfony.lock
index a7fd2ff..d0a2035 100644
--- a/symfony.lock
+++ b/symfony.lock
@@ -40,6 +40,21 @@
"tests/bootstrap.php"
]
},
+ "symfony/asset-mapper": {
+ "version": "7.0",
+ "recipe": {
+ "repo": "github.com/symfony/recipes",
+ "branch": "main",
+ "version": "6.4",
+ "ref": "7824128ef0da56f09a376539d00a17e23e9b5054"
+ },
+ "files": [
+ "assets/app.js",
+ "assets/styles/app.css",
+ "config/packages/asset_mapper.yaml",
+ "importmap.php"
+ ]
+ },
"symfony/console": {
"version": "7.0",
"recipe": {
diff --git a/templates/base.html.twig b/templates/base.html.twig
index a9e9d71..554876f 100644
--- a/templates/base.html.twig
+++ b/templates/base.html.twig
@@ -10,6 +10,7 @@
{% endblock %}
{% block javascripts %}
+{% block importmap %}{{ importmap('app') }}{% endblock %}
{% endblock %}
diff --git a/templates/frontend/index.html.twig b/templates/frontend/index.html.twig
index 051e961..bfacda5 100644
--- a/templates/frontend/index.html.twig
+++ b/templates/frontend/index.html.twig
@@ -1,6 +1,10 @@
{% extends 'base.html.twig' %}
{% block javascripts %}
+
+
+
+
{% endblock %}