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

Colorize one cell of table #107

Open
wants to merge 7 commits into
base: main
Choose a base branch
from

Conversation

dimtrovich
Copy link
Contributor

@dimtrovich dimtrovich commented Nov 11, 2024

this PR allows the developer to define a particular style for a specific table cell without necessarily impacting the entire row (as with the old and even parameters in the table definition).

in fact, by using old or even, all the even or odd rows will have the same appearance and it would be interesting to be able to highlight a specific element in the table. hence this PR.

I've also written tests for the table generator, taking into account several possible scenarios

Before this PR (the elements in the table are not correctly aligned - for example, look line 3 : display_startup_errors)
image

After this PR
image

Step to test

$color = new Color();

      $writer = new Writer();
      $writer->table([
          [
              'Directive' => 'error_reporting',
              'Global' => '32767',
              'Current' => '5111'
          ],
          [
              'Directive' => 'display_startup_errors',
              'Global' => '1',
              'Current' => $color->error('1'),
          ],
          [
              'Directive' => $color->error('opcache.enable'),
              'Global' => 'disabled',
              'Current' => $color->error('disabled'),
          ],
          [
              'Directive' => 'opcache.enable_cli',
              'Global' => 'disabled',
              'Current' => 'disabled',
          ],
      ]);

@dimtrovich dimtrovich changed the title Colorize one column of table Colorize one cell of table Nov 13, 2024
@adhocore
Copy link
Owner

adhocore commented Nov 14, 2024

thank you 👍. however it has to be implemented differently. like using styles. eg:

$writer->table([
  ['a' => 1, 'b' => 2],
  ['a' => 3, 'b' => 8],
  ['a' => 7, 'b' => 32],
], [
  'head' => '', // for heading
  'odd'  => '', // for odd rows
  'even' => '', // for even rows
  '1:1'  => '', // for cell in row 1 col 1 (1 based count)
  '2:*'  => '', // for all cells in row 2 (1 based count)
  '*:2'  => '', // for all cells in col 2 (1 based count)
  'b'    => '', // for all columns named 'b' (same as '*:2' in this example)
]);

priority in increasing order:

  • 'odd' or 'even'
  • '2:*' (row)
  • '*:2' or 'b' (col)
  • '1:1' (cell) = highest priority

actually this was thought out long ago:
https://github.com/adhocore/php-cli?tab=readme-ov-file#tables

@dimtrovich
Copy link
Contributor Author

dimtrovich commented Nov 14, 2024

thank you 👍. however it has to be implemented differently.

It's true that we could also do something like that, but I have a problem with that approach.
Doing it this way presupposes that you know in advance what colour each of the cells might be. In the case of a static construction of the table this would be valid but if the values are dynamic then it would be difficult to do.
For example, imagine that I wanted to display the users in the database with their status (active in green and inactive in red); in this case cell 2:3 could very well be green or red depending on the data in the database.
Using this implementation, all you need to do is make a ternary when filling the cell

For exemple

$table = [];
$users = $db->getUsers();

$color = new Color();
$writer = new Writer();

foreach ($users as $user) {
    $table[] = [
        'Username' => $user->username,    
        'Statut' => $user->active ? $color->ok('Active') : $code->error('Inactive'),    
        'Role' => $color->line($user->role, [
            'fg' => match($user->role) {
                'admin' => Color::GREEN,
                'moderator' => Color::YELLOW,
                default => Color::WHITE
            }
        ]),    
    ]
}

$writer->table($table);

You can see that in such a case, you can't really know in advance what colour the 2:3 cell should be.

The table I showed in the image above is dynamically generated.
https://github.com/blitz-php/framework/blob/devs/src/Security/CheckPhpIni.php#L44-L75

@adhocore
Copy link
Owner

can we still do the way i recommended and for complex edge cases like the one you mentioned of dynamic data, the style can support a callback

eg: since you would already know the column of role (lets say 2), then

writer->table([], [
  '*:2' => fn($val, $row, $table) => 'return different style string based on $val (may also use $row or $table)'
])

for implementation, all you need to check is if the style is a callback or string. if callback call it with (val, row, table) and use resulting string as style ;)

@dimtrovich
Copy link
Contributor Author

@adhocore I implemented this functionality using the $styles parameter.
however I think my initial implementation shouldn't be removed as there could be people trying to pass coloured text into the array (use cases do exist, the proof is I've had it).
So I've kept both approaches, even though only the one using the $styles parameter is presented in the documentation.
The other approach will remain in the background in case someone tries one day to send already customised text to the table.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants