refactor javascript

This commit is contained in:
Jan Klattenhoff 2024-02-01 11:22:12 +01:00
parent 345e207328
commit 83cc9ab082
13 changed files with 547 additions and 192 deletions

5
.gitignore vendored

@ -13,3 +13,8 @@
/phpunit.xml
.phpunit.result.cache
###< phpunit/phpunit ###
###> symfony/asset-mapper ###
/public/assets/
/assets/vendor/
###< symfony/asset-mapper ###

@ -109,6 +109,9 @@
<path value="$PROJECT_DIR$/vendor/symfony/twig-bridge" />
<path value="$PROJECT_DIR$/vendor/symfony/twig-bundle" />
<path value="$PROJECT_DIR$/vendor/symfony/asset" />
<path value="$PROJECT_DIR$/vendor/symfony/http-client" />
<path value="$PROJECT_DIR$/vendor/symfony/asset-mapper" />
<path value="$PROJECT_DIR$/vendor/symfony/http-client-contracts" />
</include_path>
</component>
<component name="PhpInterpreters">

@ -3,6 +3,7 @@
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" packagePrefix="App\" />
<sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" packagePrefix="App\Tests\" />
<excludeFolder url="file://$MODULE_DIR$/var" />
<excludeFolder url="file://$MODULE_DIR$/vendor/composer" />
@ -102,6 +103,9 @@
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/twig-bundle" />
<excludeFolder url="file://$MODULE_DIR$/vendor/twig/twig" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/asset" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/asset-mapper" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/http-client" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/http-client-contracts" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />

@ -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"

331
composer.lock generated

@ -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",

@ -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`;
}
}

@ -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();
});

22
public/js/modals.js Normal file

@ -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};
}

54
public/js/printerApi.js Normal file

@ -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);
}
});
}

79
public/js/tableActions.js Normal file

@ -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();
}

@ -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": {

@ -10,6 +10,7 @@
{% endblock %}
{% block javascripts %}
{% block importmap %}{{ importmap('app') }}{% endblock %}
{% endblock %}
</head>
<body data-bs-theme="dark">

@ -1,6 +1,10 @@
{% extends 'base.html.twig' %}
{% block javascripts %}
<script src="{{ asset('js/modals.js') }}"></script>
<script src="{{ asset('js/buttonActions.js') }}"></script>
<script src="{{ asset('js/tableActions.js') }}"></script>
<script src="{{ asset('js/printerApi.js') }}"></script>
<script src="{{ asset('js/frontend.js') }}"></script>
{% endblock %}