Load the default NotificationDescription implementation lazily

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@spotify.com>
This commit is contained in:
Fredrik Adelöw
2026-04-21 16:44:48 +02:00
parent 03311e33da
commit 4f7e5219de
2 changed files with 65 additions and 46 deletions
@@ -0,0 +1,61 @@
/*
* Copyright 2025 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Text, Button } from '@backstage/ui';
import { useState } from 'react';
import { NotificationDescriptionProps } from './NotificationDescription';
const MAX_LENGTH = 100;
export const DefaultNotificationDescription = (
props: NotificationDescriptionProps,
) => {
const { description } = props;
const [shown, setShown] = useState(false);
const isLong = description.length > MAX_LENGTH;
if (!isLong) {
return <Text variant="body-small">{description}</Text>;
}
if (shown) {
return (
<Text variant="body-small">
{description}{' '}
<Button
variant="tertiary"
onPress={() => {
setShown(false);
}}
>
Show less
</Button>
</Text>
);
}
return (
<Text variant="body-small">
{description.substring(0, MAX_LENGTH)}...{' '}
<Button
variant="tertiary"
onPress={() => {
setShown(true);
}}
>
Show more
</Button>
</Text>
);
};
@@ -13,8 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Text, Button } from '@backstage/ui';
import { useState } from 'react';
import { createSwappableComponent } from '@backstage/frontend-plugin-api';
/**
@@ -26,49 +24,6 @@ export interface NotificationDescriptionProps {
description: string;
}
const MAX_LENGTH = 100;
const DefaultNotificationDescription = (
props: NotificationDescriptionProps,
) => {
const { description } = props;
const [shown, setShown] = useState(false);
const isLong = description.length > MAX_LENGTH;
if (!isLong) {
return <Text variant="body-small">{description}</Text>;
}
if (shown) {
return (
<Text variant="body-small">
{description}{' '}
<Button
variant="tertiary"
onPress={() => {
setShown(false);
}}
>
Show less
</Button>
</Text>
);
}
return (
<Text variant="body-small">
{description.substring(0, MAX_LENGTH)}...{' '}
<Button
variant="tertiary"
onPress={() => {
setShown(true);
}}
>
Show more
</Button>
</Text>
);
};
/**
* Swappable component that renders the description of a notification in the
* notifications table. Apps can override this to customize how descriptions
@@ -79,5 +34,8 @@ const DefaultNotificationDescription = (
export const NotificationDescription =
createSwappableComponent<NotificationDescriptionProps>({
id: 'notifications.notification-description',
loader: () => DefaultNotificationDescription,
loader: () =>
import('./DefaultNotificationDescription').then(
m => m.DefaultNotificationDescription,
),
});