Skip to content
Merged
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ All notable changes to this project will be documented in this file.
* Removed admin/access-config.json fetch
* Aligned with v. 2.5.2.
* Removed themes.
* Added command to migrate config.json files.

### NB! Prior to 3.x the project was split into separate repositories

Expand Down
47 changes: 26 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,26 @@

## Table of Contents

1. [Description](#description)
2. [ADR - Architectural Decision Records](#adr---architectural-decision-records)
3. [Technologies](#technologies)
4. [Versioning](#versioning)
5. [Taskfile](#taskfile)
6. [Development setup](#development-setup)
7. [Production setup](#production-setup)
8. [Coding standards](#coding-standards)
9. [Stateless](#stateless)
10. [OIDC providers](#oidc-providers)
11. [JWT Auth](#jwt-auth)
12. [Test](#test)
13. [API specification and generated code](#api-specification-and-generated-code)
14. [Configuration](#configuration)
15. [Rest API & Relationships](#rest-api--relationships)
16. [Error codes in the Client](#error-codes-in-the-client)
17. [Preview mode in the Client](#preview-mode-in-the-client)
18. [Feeds](#feeds)
19. [Custom Templates](#custom-templates)
20. [Upgrade Guide](#upgrade-guide)
- [Description](#description)
- [ADR - Architectural Decision Records](#adr---architectural-decision-records)
- [Technologies](#technologies)
- [Versioning](#versioning)
- [Taskfile](#taskfile)
- [Development setup](#development-setup)
- [Production setup](#production-setup)
- [Coding standards](#coding-standards)
- [Stateless](#stateless)
- [OIDC providers](#oidc-providers)
- [JWT Auth](#jwt-auth)
- [Test](#test)
- [API specification and generated code](#api-specification-and-generated-code)
- [Configuration](#configuration)
- [Rest API & Relationships](#rest-api--relationships)
- [Error codes in the Client](#error-codes-in-the-client)
- [Preview mode in the Client](#preview-mode-in-the-client)
- [Feeds](#feeds)
- [Custom Templates](#custom-templates)
- [Upgrade Guide](#upgrade-guide)

## Description

Expand Down Expand Up @@ -586,7 +586,9 @@ custom themes.

## Custom Templates

It is possible to include your own templates in your installation.
OS2Display ships with some standard templates. These are located in `assets/shared/templates`.

It is possible to include custom templates in your installation.

### Location

Expand Down Expand Up @@ -620,6 +622,9 @@ The `.jsx` should expose the following functions:

For an example of a custom template see `assets/shared/custom-templates-example/`.

In production, these custom templates need to be built together with the normal templates with the `npm run build`
command.

### Contributing template

If you think the template could be used by other, consider contributing the template to the project as a pull request.
Expand Down
26 changes: 24 additions & 2 deletions UPGRADE.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
# Upgrade Guide

## 2.x -> 3.0.0
## Table of contents

The upgrade from 2.x to 3.0.0 of OS2Display introduces a major change to the project.
- ### [2.x -> 3.0](#2x---30)

## 2.x -> 3.0

The upgrade from 2.x to 3.0 of OS2Display introduces a major change to the project.
The Admin and Client apps and the Templates that previously existed in separate repositories from the API,
have been included in the API repository.
The API repository has been renamed from <https://github.com/os2display/display-api-service> to
Expand All @@ -13,6 +17,17 @@ Because of these changes, it will be necessary to adjust the server setup to mat

### Upgrade steps

#### 0 - Convert external templates to custom templates

Instead of loading javascript for templates from possibly external urls we have made the change to only include
templates that are a part of the code. Standard templates are now located in `assets/shared/templates/`.
Custom templates are located in `assets/shared/custom-templates`.

Because of this change, external templates in 2.x will have to be converted to custom templates.
Custom templates are documented in the [README.md#custom-templates](README.md#custom-templates).

The important thing is that the `id` of the template should remain the same when converted to a custom template.

#### 1 - Upgrade the API to the latest version of 2.x

#### 2 - Configure the following environment variables in `.env.local`
Expand Down Expand Up @@ -40,6 +55,13 @@ CLIENT_DEBUG=false
These values were previously added to Admin and Client: `/public/config.json`.
See [README.md](./README.md) for a description of the configuration options.

You can convert your previous config.json files to .env config with the following commands:

```shell
docker compose exec phpfpm bin/console app:utils:convert-config-json-to-env --type=admin path/to/admin/config.json
docker compose exec phpfpm bin/console app:utils:convert-config-json-to-env --type=client path/to/client/config.json
```

#### 3 - Run doctrine migrate

```shell
Expand Down
8 changes: 0 additions & 8 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -131,14 +131,6 @@
"fixtures-load": [
"bin/console hautelook:fixtures:load --no-interaction"
],
"prepare-code": [
"bin/console doctrine:schema:validate",
"@coding-standards-apply",
"vendor/bin/rector",
"vendor/bin/psalm --no-cache",
"@test-setup",
"@test"
],
"test": [
"vendor/bin/phpunit --stop-on-failure"
],
Expand Down
9 changes: 4 additions & 5 deletions src/Command/UpdateCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,11 @@
)]
class UpdateCommand extends Command
{
private TemplateService $templateService;

public function __construct(TemplateService $templateService, ?string $name = null)
{
public function __construct(
private readonly TemplateService $templateService,
?string $name = null,
) {
parent::__construct($name);
$this->templateService = $templateService;
}

final protected function execute(InputInterface $input, OutputInterface $output): int
Expand Down
102 changes: 102 additions & 0 deletions src/Command/Utils/ConvertConfigJsonToEnvCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
<?php

declare(strict_types=1);

namespace App\Command\Utils;

use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;

#[AsCommand(
name: 'app:utils:convert-config-json-to-env',
description: 'Converts a config json file (admin/client) from 2.x to .env variables used in 3.x',
)]
class ConvertConfigJsonToEnvCommand extends Command
{
protected function configure(): void
{
$this->addArgument('filepath', InputArgument::REQUIRED, 'Path to the file or URL to convert');
$this->addOption('type', 't', InputOption::VALUE_REQUIRED, 'Type of the config (admin or client).', null, ['admin', 'client']);
}

final protected function execute(InputInterface $input, OutputInterface $output): int
{
$io = new SymfonyStyle($input, $output);

$type = $input->getOption('type');

if (!in_array($type, ['admin', 'client'])) {
$io->error('Invalid type');

return Command::INVALID;
}

try {
$content = file_get_contents($input->getArgument('filepath'));

if (false === $content) {
throw new \Exception('Error reading file');
}

$config = json_decode($content, true, 512, JSON_THROW_ON_ERROR);
} catch (\Exception|\JsonException $e) {
$io->error($e->getMessage());

return Command::INVALID;
}

if ('admin' === $type) {
$io->success('Insert the following lines in .env.local');

$rejseplanenApiKey = $config['rejseplanenApiKey'] ?? null;
$showScreenStatus = $config['showScreenStatus'] ?? null;
$touchButtonRegions = $config['touchButtonRegions'] ?? null;
$loginMethods = $config['loginMethods'] ?? null;

if (null !== $loginMethods) {
// Remove enabled field since this is unused in v3.
foreach ($loginMethods as &$method) {
unset($method['enabled']);
}
}

$io->writeln('###> Admin configuration ###');
null !== $rejseplanenApiKey && $io->writeln('ADMIN_REJSEPLANEN_APIKEY="'.$rejseplanenApiKey.'"');
null !== $showScreenStatus && $io->writeln('ADMIN_SHOW_SCREEN_STATUS='.var_export($showScreenStatus, true));
null !== $touchButtonRegions && $io->writeln('ADMIN_TOUCH_BUTTON_REGIONS='.var_export($touchButtonRegions, true));
null !== $loginMethods && $io->writeln("ADMIN_LOGIN_METHODS='".json_encode($loginMethods)."'");
// This is a conversion from an url to boolean value. If the url is not empty, it is interpreted as true.
!empty($config['previewClient']) && $io->writeln('ADMIN_ENHANCED_PREVIEW=true');
$io->writeln('###< Admin configuration ###');
} elseif ('client' === $type) {
$io->success('Insert the following lines in .env.local');

$loginCheckTimeout = $config['loginCheckTimeout'] ?? null;
$refreshTokenTimeout = $config['refreshTokenTimeout'] ?? null;
$releaseTimestampIntervalTimeout = $config['releaseTimestampIntervalTimeout'] ?? null;
$schedulingInterval = $config['schedulingInterval'] ?? null;
$pullStrategyInterval = $config['dataStrategy']['config']['interval'] ?? null;
$debug = $config['debug'] ?? null;

$colorScheme = $config['colorScheme'] ?? null;
$colorSchemeValue = null !== $colorScheme ? "'".json_encode($colorScheme)."'" : null;

$io->writeln('###> Client configuration ###');
null !== $loginCheckTimeout && $io->writeln('CLIENT_LOGIN_CHECK_TIMEOUT='.$loginCheckTimeout);
null !== $refreshTokenTimeout && $io->writeln('CLIENT_REFRESH_TOKEN_TIMEOUT='.$refreshTokenTimeout);
null !== $releaseTimestampIntervalTimeout && $io->writeln('CLIENT_RELEASE_TIMESTAMP_INTERVAL_TIMEOUT='.$releaseTimestampIntervalTimeout);
null !== $schedulingInterval && $io->writeln('CLIENT_SCHEDULING_INTERVAL='.$schedulingInterval);
null !== $pullStrategyInterval && $io->writeln('CLIENT_PULL_STRATEGY_INTERVAL='.$pullStrategyInterval);
null !== $colorSchemeValue && $io->writeln('CLIENT_COLOR_SCHEME='.$colorSchemeValue);
null !== $debug && $io->writeln('CLIENT_DEBUG=true');
$io->writeln('###< Client configuration ###');
}

return Command::SUCCESS;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

declare(strict_types=1);

namespace App\Command;
namespace App\Command\Utils;

use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
Expand All @@ -12,8 +12,8 @@
use Symfony\Component\Uid\Ulid;

#[AsCommand(
name: 'app:ulid:generate',
description: 'Generate a new ULID',
name: 'app:utils:generate-ulid',
description: 'Generate a new ULID.',
)]
class GenerateUlid extends Command
{
Expand Down