Selectively show the additional metadata if it isn't in the display string at all

This commit is contained in:
DaneEveritt 2022-06-12 15:30:49 -04:00
parent 88987fb6c7
commit 68a654f9e8
No known key found for this signature in database
GPG key ID: EEA66103B3D71F53
5 changed files with 33 additions and 7 deletions

View file

@ -21,7 +21,8 @@ class ActivityLogTransformer extends BaseClientTransformer
'event' => $model->event, 'event' => $model->event,
'ip' => $model->ip, 'ip' => $model->ip,
'description' => $model->description, 'description' => $model->description,
'properties' => $model->properties, 'properties' => $model->properties ? $model->properties->toArray() : [],
'has_additional_metadata' => $this->hasAdditionalMetadata($model),
'timestamp' => $model->timestamp->toIso8601String(), 'timestamp' => $model->timestamp->toIso8601String(),
]; ];
} }
@ -34,4 +35,32 @@ 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);
} }
/**
* 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
* the browser useragent.
*
* This is used by the front-end to selectively display an "additional metadata"
* button that is pointless if there is nothing the user can't already see from
* the event description.
*/
protected function hasAdditionalMetadata(ActivityLog $model): bool
{
if (is_null($model->properties) || $model->properties->isEmpty()) {
return false;
}
$str = trans('activity.' . str_replace(':', '.', $model->event));
preg_match_all('/:(?<key>[\w-]+)(?:\W?|$)/', $str, $matches);
$exclude = array_merge($matches['key'], ['ip', 'useragent']);
foreach ($model->properties->keys() as $key) {
if (!in_array($key, $exclude, true)) {
return true;
}
}
return false;
}
} }

View file

@ -25,6 +25,7 @@ interface ActivityLog extends Model<'actor'> {
ip: string; ip: string;
description: string | null; description: string | null;
properties: Record<string, string | unknown>; properties: Record<string, string | unknown>;
hasAdditionalMetadata: boolean;
timestamp: Date; timestamp: Date;
relationships: { relationships: {
actor: User | null; actor: User | null;

View file

@ -36,6 +36,7 @@ export default class Transformers {
ip: attributes.ip, ip: attributes.ip,
description: attributes.description, description: attributes.description,
properties: attributes.properties, properties: attributes.properties,
hasAdditionalMetadata: attributes.has_additional_metadata ?? false,
timestamp: new Date(attributes.timestamp), timestamp: new Date(attributes.timestamp),
relationships: { relationships: {
actor: transform(actor as FractalResponseData, this.toUser, null), actor: transform(actor as FractalResponseData, this.toUser, null),

View file

@ -73,7 +73,7 @@ export default ({ activity, children }: Props) => {
</Tooltip> </Tooltip>
</div> </div>
</div> </div>
<ActivityLogMetaButton meta={activity.properties}/> {activity.hasAdditionalMetadata && <ActivityLogMetaButton meta={activity.properties}/>}
</div> </div>
</div> </div>
); );

View file

@ -1,5 +1,4 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import { isEmptyObject } from '@/helpers';
import { ClipboardListIcon } from '@heroicons/react/outline'; import { ClipboardListIcon } from '@heroicons/react/outline';
import { Dialog } from '@/components/elements/dialog'; import { Dialog } from '@/components/elements/dialog';
import { Button } from '@/components/elements/button/index'; import { Button } from '@/components/elements/button/index';
@ -7,10 +6,6 @@ import { Button } from '@/components/elements/button/index';
export default ({ meta }: { meta: Record<string, unknown> }) => { export default ({ meta }: { meta: Record<string, unknown> }) => {
const [ open, setOpen ] = useState(false); const [ open, setOpen ] = useState(false);
if (isEmptyObject(meta)) {
return null;
}
return ( return (
<div className={'self-center mx-4'}> <div className={'self-center mx-4'}>
<Dialog <Dialog