Skip to content

Colorize one cell of table#107

Merged
adhocore merged 7 commits into
adhocore:mainfrom
dimtrovich:colorize-one-column-of-table
Nov 15, 2024
Merged

Colorize one cell of table#107
adhocore merged 7 commits into
adhocore:mainfrom
dimtrovich:colorize-one-column-of-table

Conversation

@dimtrovich

@dimtrovich dimtrovich commented Nov 11, 2024

Copy link
Copy Markdown
Contributor

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

adhocore commented Nov 14, 2024

Copy link
Copy Markdown
Owner

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

dimtrovich commented Nov 14, 2024

Copy link
Copy Markdown
Contributor Author

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
Copy Markdown
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
Copy Markdown
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.

@adhocore adhocore left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks cool, thanks 😎

@adhocore
adhocore merged commit 6092763 into adhocore:main Nov 15, 2024
@dimtrovich
dimtrovich deleted the colorize-one-column-of-table branch November 15, 2024 17:57
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