Abuse the translation engine to handle more of the formatting for us
This commit is contained in:
parent
b052d29a5f
commit
95de4c30fc
4 changed files with 94 additions and 51 deletions
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
namespace Pterodactyl\Transformers\Api\Client;
|
namespace Pterodactyl\Transformers\Api\Client;
|
||||||
|
|
||||||
|
use Illuminate\Support\Str;
|
||||||
use Pterodactyl\Models\User;
|
use Pterodactyl\Models\User;
|
||||||
use Pterodactyl\Models\ActivityLog;
|
use Pterodactyl\Models\ActivityLog;
|
||||||
|
|
||||||
|
@ -22,7 +23,7 @@ class ActivityLogTransformer extends BaseClientTransformer
|
||||||
'is_api' => !is_null($model->api_key_id),
|
'is_api' => !is_null($model->api_key_id),
|
||||||
'ip' => $model->ip,
|
'ip' => $model->ip,
|
||||||
'description' => $model->description,
|
'description' => $model->description,
|
||||||
'properties' => $model->properties ? $model->properties->toArray() : [],
|
'properties' => $this->properties($model),
|
||||||
'has_additional_metadata' => $this->hasAdditionalMetadata($model),
|
'has_additional_metadata' => $this->hasAdditionalMetadata($model),
|
||||||
'timestamp' => $model->timestamp->toIso8601String(),
|
'timestamp' => $model->timestamp->toIso8601String(),
|
||||||
];
|
];
|
||||||
|
@ -37,6 +38,33 @@ class ActivityLogTransformer extends BaseClientTransformer
|
||||||
return $this->item($model->actor, $this->makeTransformer(UserTransformer::class), User::RESOURCE_NAME);
|
return $this->item($model->actor, $this->makeTransformer(UserTransformer::class), User::RESOURCE_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transforms any array values in the properties into a countable field for easier
|
||||||
|
* use within the translation outputs.
|
||||||
|
*/
|
||||||
|
protected function properties(ActivityLog $model): array
|
||||||
|
{
|
||||||
|
if (!$model->properties || $model->properties->isEmpty()) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$properties = $model->properties
|
||||||
|
->mapWithKeys(function ($value, $key) {
|
||||||
|
if (!is_array($value)) {
|
||||||
|
return [$key => $value];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [$key => $value, "{$key}_count" => count($value)];
|
||||||
|
});
|
||||||
|
|
||||||
|
$keys = $properties->keys()->filter(fn ($key) => Str::endsWith($key, '_count'))->values();
|
||||||
|
if ($keys->containsOneItem()) {
|
||||||
|
$properties = $properties->merge(['count' => $properties->get($keys[0])])->except($keys[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $properties->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines if there are any log properties that we've not already exposed
|
* Determines if there are any log properties that we've not already exposed
|
||||||
* in the response language string and that are not just the IP address or
|
* in the response language string and that are not just the IP address or
|
||||||
|
|
|
@ -15,20 +15,20 @@ return [
|
||||||
'checkpoint' => 'Two-factor authentication requested',
|
'checkpoint' => 'Two-factor authentication requested',
|
||||||
'recovery-token' => 'Used two-factor recovery token',
|
'recovery-token' => 'Used two-factor recovery token',
|
||||||
'token' => 'Solved two-factor challenge',
|
'token' => 'Solved two-factor challenge',
|
||||||
'ip-blocked' => 'Blocked request from unlisted IP address for <strong>:identifier</strong>',
|
'ip-blocked' => 'Blocked request from unlisted IP address for :identifier',
|
||||||
],
|
],
|
||||||
'user' => [
|
'user' => [
|
||||||
'account' => [
|
'account' => [
|
||||||
'email-changed' => 'Changed email from <strong>:old</strong> to <strong>:new</strong>',
|
'email-changed' => 'Changed email from :old to :new',
|
||||||
'password-changed' => 'Changed password',
|
'password-changed' => 'Changed password',
|
||||||
],
|
],
|
||||||
'api-key' => [
|
'api-key' => [
|
||||||
'create' => 'Created new API key <strong>:identifier</strong>',
|
'create' => 'Created new API key :identifier',
|
||||||
'delete' => 'Deleted API key <strong>:identifier</strong>',
|
'delete' => 'Deleted API key :identifier',
|
||||||
],
|
],
|
||||||
'ssh-key' => [
|
'ssh-key' => [
|
||||||
'create' => 'Added SSH key <strong>:fingerprint</strong> to account',
|
'create' => 'Added SSH key :fingerprint to account',
|
||||||
'delete' => 'Removed SSH key <strong>:fingerprint</strong> from account',
|
'delete' => 'Removed SSH key :fingerprint from account',
|
||||||
],
|
],
|
||||||
'two-factor' => [
|
'two-factor' => [
|
||||||
'create' => 'Enabled two-factor auth',
|
'create' => 'Enabled two-factor auth',
|
||||||
|
@ -37,64 +37,66 @@ return [
|
||||||
],
|
],
|
||||||
'server' => [
|
'server' => [
|
||||||
'backup' => [
|
'backup' => [
|
||||||
'download' => 'Downloaded the <strong>:name</strong> backup',
|
'download' => 'Downloaded the :name backup',
|
||||||
'delete' => 'Deleted the <strong>:name</strong> backup',
|
'delete' => 'Deleted the :name backup',
|
||||||
'restore' => 'Restored the <strong>:name</strong> backup (deleted files: :truncate)',
|
'restore' => 'Restored the :name backup (deleted files: :truncate)',
|
||||||
'restore-complete' => 'Completed restoration of the <strong>:name</strong> backup',
|
'restore-complete' => 'Completed restoration of the :name backup',
|
||||||
'restore-failed' => 'Failed to complete restoration of the <strong>:name</strong> backup',
|
'restore-failed' => 'Failed to complete restoration of the :name backup',
|
||||||
'start' => 'Started a new backup <strong>:name</strong>',
|
'start' => 'Started a new backup :name',
|
||||||
'complete' => 'Marked the <strong>:name</strong> backup as complete',
|
'complete' => 'Marked the :name backup as complete',
|
||||||
'fail' => 'Marked the <strong>:name</strong> backup as failed',
|
'fail' => 'Marked the :name backup as failed',
|
||||||
'lock' => 'Locked the <strong>:name</strong> backup',
|
'lock' => 'Locked the :name backup',
|
||||||
'unlock' => 'Unlocked the <strong>:name</strong> backup',
|
'unlock' => 'Unlocked the :name backup',
|
||||||
],
|
],
|
||||||
'database' => [
|
'database' => [
|
||||||
'create' => 'Created new database <strong>:name</strong>',
|
'create' => 'Created new database :name',
|
||||||
'rotate-password' => 'Password rotated for database <strong>:name</strong>',
|
'rotate-password' => 'Password rotated for database :name',
|
||||||
'delete' => 'Deleted database <strong>:name</strong>',
|
'delete' => 'Deleted database :name',
|
||||||
],
|
],
|
||||||
'file' => [
|
'file' => [
|
||||||
'compress' => 'Created new file archive of files in <strong>:directory</strong>',
|
'compress_one' => 'Compressed :directory/:file',
|
||||||
'read' => 'Viewed the contents of <strong>:file</strong>',
|
'compress_other' => 'Compressed :count files in :directory',
|
||||||
'copy' => 'Created a copy of <strong>:file</strong>',
|
'read' => 'Viewed the contents of :file',
|
||||||
'create-directory' => 'Created a new directory <strong>:name</strong> in <strong>:directory</strong>',
|
'copy' => 'Created a copy of :file',
|
||||||
'decompress' => 'Decompressed a file archive in <strong>:directory</strong>',
|
'create-directory' => 'Created a new directory :name in :directory',
|
||||||
'delete' => 'Deleted files in <strong>:directory</strong>',
|
'decompress' => 'Decompressed :files in :directory',
|
||||||
'download' => 'Downloaded <strong>:file</strong>',
|
'delete_one' => 'Deleted :directory/:files',
|
||||||
'pull' => 'Downloaded a remote file from :url to <strong>:directory</strong>',
|
'delete_other' => 'Deleted :count files in :directory',
|
||||||
'rename' => 'Renamed files in <strong>:directory</strong>',
|
'download' => 'Downloaded :file',
|
||||||
'write' => 'Wrote new content to <strong>:file</strong>',
|
'pull' => 'Downloaded a remote file from :url to :directory',
|
||||||
|
'rename' => 'Renamed files in :directory',
|
||||||
|
'write' => 'Wrote new content to :file',
|
||||||
'upload' => 'Began a file upload',
|
'upload' => 'Began a file upload',
|
||||||
],
|
],
|
||||||
'allocation' => [
|
'allocation' => [
|
||||||
'create' => 'Added <strong>:allocation</strong> to the server',
|
'create' => 'Added :allocation to the server',
|
||||||
'notes' => 'Updated the notes for <strong>:allocation</strong> from ":old" to ":new"',
|
'notes' => 'Updated the notes for :allocation from ":old" to ":new"',
|
||||||
'primary' => 'Set <strong>:allocation</strong> as the primary server allocation',
|
'primary' => 'Set :allocation as the primary server allocation',
|
||||||
'delete' => 'Deleted the <strong>:allocation</strong> allocation',
|
'delete' => 'Deleted the :allocation allocation',
|
||||||
],
|
],
|
||||||
'schedule' => [
|
'schedule' => [
|
||||||
'store' => 'Created the <strong>:name</strong> schedule',
|
'store' => 'Created the :name schedule',
|
||||||
'update' => 'Updated the <strong>:name</strong> schedule',
|
'update' => 'Updated the :name schedule',
|
||||||
'execute' => 'Manually executed the <strong>:name</strong> schedule',
|
'execute' => 'Manually executed the :name schedule',
|
||||||
'delete' => 'Deleted the <strong>:name</strong> schedule',
|
'delete' => 'Deleted the :name schedule',
|
||||||
],
|
],
|
||||||
'task' => [
|
'task' => [
|
||||||
'create' => 'Created a new ":action" task for the <strong>:name</strong> schedule',
|
'create' => 'Created a new ":action" task for the :name schedule',
|
||||||
'update' => 'Updated the ":action" task for the <strong>:name</strong> schedule',
|
'update' => 'Updated the ":action" task for the :name schedule',
|
||||||
'delete' => 'Deleted a task for the <strong>:name</strong> schedule',
|
'delete' => 'Deleted a task for the :name schedule',
|
||||||
],
|
],
|
||||||
'settings' => [
|
'settings' => [
|
||||||
'rename' => 'Renamed the server from <strong>:old</strong> to <strong>:new</strong>',
|
'rename' => 'Renamed the server from :old to :new',
|
||||||
'reinstall' => 'Triggered a server reinstall',
|
'reinstall' => 'Triggered a server reinstall',
|
||||||
],
|
],
|
||||||
'startup' => [
|
'startup' => [
|
||||||
'edit' => 'Edited the <strong>:variable</strong> startup variable for the server from ":old" to ":new"',
|
'edit' => 'Changed the :variable variable from ":old" to ":new"',
|
||||||
'image' => 'Updated the Docker Image for the server from <strong>:old</strong> to <strong>:new</strong>',
|
'image' => 'Updated the Docker Image for the server from :old to :new',
|
||||||
],
|
],
|
||||||
'subuser' => [
|
'subuser' => [
|
||||||
'create' => 'Added <strong>:email</strong> as a subuser',
|
'create' => 'Added :email as a subuser',
|
||||||
'update' => 'Updated the subuser permissions for <strong>:email</strong>',
|
'update' => 'Updated the subuser permissions for :email',
|
||||||
'delete' => 'Removed <strong>:email</strong> as a subuser',
|
'delete' => 'Removed :email as a subuser',
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|
|
@ -27,6 +27,13 @@ export default ({ activity, children }: Props) => {
|
||||||
return current.toString();
|
return current.toString();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const properties = Object.keys(activity.properties).reduce((obj, key) => ({
|
||||||
|
...obj,
|
||||||
|
[key]: key === 'count' || key.endsWith('_count')
|
||||||
|
? activity.properties[key]
|
||||||
|
: `<strong>${activity.properties[key]}</strong>`,
|
||||||
|
}), {});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={'grid grid-cols-10 py-4 border-b-2 border-gray-800 last:rounded-b last:border-0 group'}>
|
<div className={'grid grid-cols-10 py-4 border-b-2 border-gray-800 last:rounded-b last:border-0 group'}>
|
||||||
<div className={'hidden sm:flex sm:col-span-1 items-center justify-center select-none'}>
|
<div className={'hidden sm:flex sm:col-span-1 items-center justify-center select-none'}>
|
||||||
|
@ -60,10 +67,8 @@ export default ({ activity, children }: Props) => {
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p className={'mt-1 text-sm break-words line-clamp-2 pr-4'}>
|
<p className={style.description}>
|
||||||
<Translate ns={'activity'} values={activity.properties}>
|
<Translate ns={'activity'} values={properties} i18nKey={activity.event.replace(':', '.')}/>
|
||||||
{activity.event.replace(':', '.')}
|
|
||||||
</Translate>
|
|
||||||
</p>
|
</p>
|
||||||
<div className={'mt-1 flex items-center text-sm'}>
|
<div className={'mt-1 flex items-center text-sm'}>
|
||||||
<Link
|
<Link
|
||||||
|
|
|
@ -9,3 +9,11 @@
|
||||||
@apply w-4 h-4;
|
@apply w-4 h-4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.description {
|
||||||
|
@apply mt-1 text-sm break-words line-clamp-2 pr-4;
|
||||||
|
|
||||||
|
& strong {
|
||||||
|
@apply text-gray-50 font-semibold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue