Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Value with unit field #39

Open
wants to merge 5 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ See [keep a changelog](https://keepachangelog.com/en/1.0.0/) for information abo

## [Unreleased]

- [PR-39](https://github.com/itk-dev/aapodwalk_api/pull/39)
Changed distance and duration to integer values.
Added "Value with unit" field
- [PR-38](https://github.com/itk-dev/aapodwalk_api/pull/38)
Added mailer config
- [PR-34](https://github.com/itk-dev/aapodwalk_api/pull/34)
Expand Down
11 changes: 11 additions & 0 deletions Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -137,3 +137,14 @@ tasks:
update-translations:
cmds:
- task composer -- update-translations
-
cmd: |
BOLD='\033[1m'
RESET='\033[0m'
echo && echo -e "${BOLD}Note: You may have to run this command again to make some markup in translations fall into place.${RESET}" && echo
silent: true

update-api-spec:
cmds:
- task composer -- update-api-spec
silent: true
5 changes: 5 additions & 0 deletions assets/styles/admin.css
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,8 @@
white-space: nowrap;
}
}

/* Make the unit take up a little less space than the numeric value. */
.field-value-with-unit.form-group input.form-control {
width: 70%;
}
17 changes: 13 additions & 4 deletions fixtures/route.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,26 @@ App\Entity\Route:
route_pizza:
name: 'Pizzaruten'
description: 'Denne rute er overordentligt fokuseret på pizza'
distance: '3 meter'
distance: 3
imageFile: <uploadFile(files/pizza-1.jpg)>
total_duration: '16'
total_duration: 960 # 16 minutes (16 * 60)
tags: ['@pizza', '@mad']
createdBy: '@user'

route_havnen:
name: 'Havneruten'
description: 'Denne rute er overordentligt fokuseret på havnen'
distance: '103 meter'
distance: 103
imageFile: <uploadFile(files/pizza-1.jpg)>
total_duration: '25'
total_duration: 1500 # 25 minutes (25 * 60)
tags: ['@mad', '@arkitektur']
createdBy: '@another-user'

route_long:
name: 'Den lange rute'
description: 'Denne rute meget lang'
distance: 12345
imageFile: <uploadFile(files/pizza-1.jpg)>
total_duration: 9000 # 2.5 hours (2.5 * 60 * 60)
tags: ['@mad', '@arkitektur']
createdBy: '@another-user'
80 changes: 80 additions & 0 deletions migrations/Version20241218100641.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?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 Version20241218100641 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}

public function up(Schema $schema): void
{
// Convert string values to values in meters (distance) and seconds (total_duration)
$this->addSql(<<<'SQL'
UPDATE
route
SET
distance =
CAST(
-- Convert string to decimal value in three steps:
--
-- 1. Convert comma (assumed used as decimal separator) to dot (.)
-- 2. Remove all characters that are not a digit or a dot
-- 3. Convert to decimal

-- (3)
CAST(
-- (2)
REGEXP_REPLACE(
-- (1)
REPLACE(distance, ',', '.'),
'[^[:digit:].]+',
''
)
AS DECIMAL(16, 8)
)
-- 4. Multiple by scale to convert to meters. If value contains 'km' use 1000 as scale. Otherwise, use 1.
* (SELECT CASE WHEN distance LIKE '%km%' THEN 1000 ELSE 1 END)
AS INT),
total_duration =
CAST(
-- Convert string to decimal value in three steps:
--
-- 1. Convert comma (assumed used as decimal separator) to dot (.)
-- 2. Remove all characters that are not a digit or a dot
-- 3. Convert to decimal

-- (3)
CAST(
-- (2)
REGEXP_REPLACE(
-- (1)
REPLACE(total_duration, ',', '.'),
'[^[:digit:].]+',
''
)
AS DECIMAL(16, 8)
)
-- 4. Multiple by scale to convert to seconds. If value contains 'time' use 3600 as scale. Otherwise, use 60.
* (SELECT CASE WHEN total_duration LIKE '%time%' THEN 60 * 60 ELSE 60 END)
AS INT)
SQL);
$this->addSql('ALTER TABLE route CHANGE distance distance INT NOT NULL, CHANGE total_duration total_duration INT NOT NULL');
}

public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE route CHANGE distance distance VARCHAR(255) NOT NULL, CHANGE total_duration total_duration VARCHAR(255) NOT NULL');
}
}
14 changes: 10 additions & 4 deletions public/api-spec-v1.json
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,7 @@
"type": "string"
},
"proximityToUnlock": {
"description": "Proximity to unlock in meters.",
"type": [
"integer",
"null"
Expand Down Expand Up @@ -542,6 +543,7 @@
"type": "string"
},
"proximityToUnlock": {
"description": "Proximity to unlock in meters.",
"type": [
"integer",
"null"
Expand Down Expand Up @@ -594,7 +596,8 @@
"type": "string"
},
"distance": {
"type": "string"
"description": "Distance in meters.",
"type": "integer"
},
"image": {
"type": [
Expand All @@ -609,7 +612,8 @@
}
},
"totalDuration": {
"type": "string"
"description": "Total duration in seconds.",
"type": "integer"
},
"points": {
"type": "array",
Expand Down Expand Up @@ -670,7 +674,8 @@
"type": "string"
},
"distance": {
"type": "string"
"description": "Distance in meters.",
"type": "integer"
},
"image": {
"type": [
Expand All @@ -685,7 +690,8 @@
}
},
"totalDuration": {
"type": "string"
"description": "Total duration in seconds.",
"type": "integer"
},
"points": {
"type": "array",
Expand Down
14 changes: 10 additions & 4 deletions public/api-spec-v1.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ components:
longitude:
type: string
proximityToUnlock:
description: 'Proximity to unlock in meters.'
type:
- integer
- 'null'
Expand Down Expand Up @@ -278,6 +279,7 @@ components:
longitude:
type: string
proximityToUnlock:
description: 'Proximity to unlock in meters.'
type:
- integer
- 'null'
Expand Down Expand Up @@ -316,7 +318,8 @@ components:
description:
type: string
distance:
type: string
description: 'Distance in meters.'
type: integer
image:
type:
- string
Expand All @@ -326,7 +329,8 @@ components:
items:
$ref: '#/components/schemas/Tag-read'
totalDuration:
type: string
description: 'Total duration in seconds.'
type: integer
points:
type: array
items:
Expand Down Expand Up @@ -367,7 +371,8 @@ components:
description:
type: string
distance:
type: string
description: 'Distance in meters.'
type: integer
image:
type:
- string
Expand All @@ -377,7 +382,8 @@ components:
items:
$ref: '#/components/schemas/Tag.jsonld-read'
totalDuration:
type: string
description: 'Total duration in seconds.'
type: integer
points:
type: array
items:
Expand Down
31 changes: 31 additions & 0 deletions src/Admin/Field/ValueWithUnitField.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace App\Admin\Field;

use App\Form\ValueWithUnitType;
use EasyCorp\Bundle\EasyAdminBundle\Contracts\Field\FieldInterface;
use EasyCorp\Bundle\EasyAdminBundle\Field\FieldTrait;
use Symfony\Contracts\Translation\TranslatableInterface;

final class ValueWithUnitField implements FieldInterface
{
use FieldTrait;

/**
* @param TranslatableInterface|string|false|null $label
*/
public static function new(string $propertyName, $label = null): self
{
return (new self())
->setProperty($propertyName)
->setLabel($label)

// this template is used in 'index' and 'detail' pages
->setTemplatePath('admin/field/value_with_unit.html.twig')

// this is used in 'edit' and 'new' pages to edit the field contents
// you can use your own form types too
->setFormType(ValueWithUnitType::class)
->addCssClass('field-value-with-unit');
}
}
13 changes: 11 additions & 2 deletions src/Controller/Admin/PointOfInterestCrudController.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
namespace App\Controller\Admin;

use App\Admin\Field\LocationField;
use App\Admin\Field\ValueWithUnitField;
use App\Entity\PointOfInterest;
use App\Entity\Role;
use App\Entity\Route;
use App\Field\VichImageField;
use App\Form\ValueWithUnitType;
use App\Service\EasyAdminHelper;
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
use EasyCorp\Bundle\EasyAdminBundle\Field\AssociationField;
Expand Down Expand Up @@ -91,8 +93,15 @@ public function configureFields(string $pageName): iterable
->setRequired(true)
->setVirtual(true)->setColumns(12);

yield NumberField::new('proximityToUnlock', new TranslatableMessage('Proximity to unlock', [], 'admin'))
->setHelp(new TranslatableMessage('The proximity that allows unlocking this point of interest (in m).', [], 'admin'))->setColumns(12);
yield ValueWithUnitField::new('proximityToUnlock', new TranslatableMessage('Proximity to unlock', [], 'admin'))
->setFormTypeOption('units', [
'm' => [
ValueWithUnitType::OPTION_LABEL => new TranslatableMessage('meter', [], 'admin'),
ValueWithUnitType::OPTION_SCALE => 1,
ValueWithUnitType::OPTION_LOCALIZED_UNIT => new TranslatableMessage('unit.m', [], 'admin'),
],
])
->setHelp(new TranslatableMessage('The proximity that allows unlocking this point of interest.', [], 'admin'))->setColumns(12);

yield DateField::new('createdAt', new TranslatableMessage('Created at', [], 'admin'))->hideOnForm();
yield DateField::new('updatedAt', new TranslatableMessage('Updated at', [], 'admin'))->hideOnForm();
Expand Down
37 changes: 33 additions & 4 deletions src/Controller/Admin/RouteCrudController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

namespace App\Controller\Admin;

use App\Admin\Field\ValueWithUnitField;
use App\Entity\Role;
use App\Entity\Route;
use App\Field\VichImageField;
use App\Form\ValueWithUnitType;
use App\Service\AppManager;
use App\Service\EasyAdminHelper;
use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
Expand Down Expand Up @@ -77,10 +79,37 @@ public function configureFields(string $pageName): iterable
yield VichImageField::new('image')->setColumns(6);
}

yield TextField::new('distance', new TranslatableMessage('Distance', [], 'admin'))->setColumns(6)
->setHelp(new TranslatableMessage('The distance should be how far the route is with all points of interests included, e.g. "840m"', [], 'admin'));
yield TextField::new('totalDuration', new TranslatableMessage('Total duration', [], 'admin'))->setColumns(6)
->setHelp(new TranslatableMessage('The total duration of the route, i.e. the total duration of audio tracks in the route plus the time needed for moving along the route.', [], 'admin'));
yield ValueWithUnitField::new('distance', new TranslatableMessage('Distance', [], 'admin'))
->setFormTypeOption('units', [
'km' => [
ValueWithUnitType::OPTION_LABEL => new TranslatableMessage('kilometer', [], 'admin'),
ValueWithUnitType::OPTION_SCALE => 1000,
ValueWithUnitType::OPTION_LOCALIZED_UNIT => new TranslatableMessage('unit.km', [], 'admin'),
],
'm' => [
ValueWithUnitType::OPTION_LABEL => new TranslatableMessage('meter', [], 'admin'),
ValueWithUnitType::OPTION_SCALE => 1,
ValueWithUnitType::OPTION_LOCALIZED_UNIT => new TranslatableMessage('unit.m', [], 'admin'),
],
])
->setColumns(6)
->setHelp(new TranslatableMessage('The total distance of the route with all points of interests included.', [], 'admin'));

yield ValueWithUnitField::new('totalDuration', new TranslatableMessage('Total duration', [], 'admin'))
->setFormTypeOption('units', [
'hour' => [
ValueWithUnitType::OPTION_LABEL => new TranslatableMessage('hours', [], 'admin'),
ValueWithUnitType::OPTION_SCALE => 60 * 60,
ValueWithUnitType::OPTION_LOCALIZED_UNIT => new TranslatableMessage('unit.hour', [], 'admin'),
],
'minute' => [
ValueWithUnitType::OPTION_LABEL => new TranslatableMessage('minutes', [], 'admin'),
ValueWithUnitType::OPTION_SCALE => 60,
ValueWithUnitType::OPTION_LOCALIZED_UNIT => new TranslatableMessage('unit.minute', [], 'admin'),
],
])
->setColumns(6)
->setHelp(new TranslatableMessage('The total duration of the route, i.e. the total duration of audio tracks in the route plus the time needed for moving along the route.', [], 'admin'));

yield CollectionField::new('points', new TranslatableMessage('Points', [], 'admin'))->addCssClass('field-collection')
->setEntryIsComplex()
Expand Down
3 changes: 3 additions & 0 deletions src/Entity/PointOfInterest.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ class PointOfInterest implements BlameableInterface, \JsonSerializable
#[Groups(['read'])]
private ?string $longitude = null;

/**
* Proximity to unlock in meters.
*/
#[ORM\Column(length: 255, nullable: true)]
#[Assert\NotBlank]
#[Groups(['read'])]
Expand Down
Loading
Loading