Skip to content

Commit

Permalink
[TableListView] Improve help text of creator and view count (elastic#…
Browse files Browse the repository at this point in the history
…202488)

## Summary

This PR brings back version mentions in help text for non-serverless
that we removed in elastic#193024. In
that PR we decided that it is not worth adding complexity for checking
`isServerless` deep inside table list view components, but I want to
bring version mentions back now because I believe that it can be very
confusing without the version mentions for existing deployments

Two recent features: 1. created_by; 2. view counts are only working
since 8.14 and 8.16 respectively, so for older kibana with old
dashboards it might be confusing that the data for new features is
missing after the upgrade. In help text we can at least mention that the
reason that data is missing is because we only gather the data starting
from a specific version.

### Serverless (version mentions are missing as before) 


![Screenshot 2024-12-06 at 12 39
50](https://github.com/user-attachments/assets/4ad2cd23-3aa7-4400-a5bd-419407f2fad2)
![Screenshot 2024-12-03 at 11 59
09](https://github.com/user-attachments/assets/c56de5d3-1afb-411f-bdbd-419025ef9084)




### Statefull (version are shown again, just like before
elastic#193024)


![Screenshot 2024-12-06 at 13 03
58](https://github.com/user-attachments/assets/24ea67a5-8a32-45b0-9a4f-2890aaf7ded5)
![Screenshot 2024-12-06 at 13 04
04](https://github.com/user-attachments/assets/8f91d32b-457f-4fd7-882a-d2dd9a3476f4)
![Screenshot 2024-12-03 at 14 11
09](https://github.com/user-attachments/assets/47ea1f8a-1a7b-4aa6-af81-206c6f2d087e)




# Release Notes

Improve help text of creator and view count features on dashboard
listing page
  • Loading branch information
Dosant authored and Samiul-TheSoccerFan committed Dec 10, 2024
1 parent 34af8c3 commit 5262649
Show file tree
Hide file tree
Showing 16 changed files with 160 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,15 @@ import {
import { getUserDisplayName } from '@kbn/user-profile-components';

import { Item } from '../types';
import { useServices } from '../services';

export interface ActivityViewProps {
item: Pick<Partial<Item>, 'createdBy' | 'createdAt' | 'updatedBy' | 'updatedAt' | 'managed'>;
entityNamePlural?: string;
}

export const ActivityView = ({ item }: ActivityViewProps) => {
export const ActivityView = ({ item, entityNamePlural }: ActivityViewProps) => {
const isKibanaVersioningEnabled = useServices()?.isKibanaVersioningEnabled ?? false;
const showLastUpdated = Boolean(item.updatedAt && item.updatedAt !== item.createdAt);

const UnknownUserLabel = (
Expand Down Expand Up @@ -62,7 +65,10 @@ export const ActivityView = ({ item }: ActivityViewProps) => {
) : (
<>
{UnknownUserLabel}
<NoCreatorTip />
<NoCreatorTip
includeVersionTip={isKibanaVersioningEnabled}
entityNamePlural={entityNamePlural}
/>
</>
)
}
Expand All @@ -85,7 +91,10 @@ export const ActivityView = ({ item }: ActivityViewProps) => {
) : (
<>
{UnknownUserLabel}
<NoUpdaterTip />
<NoUpdaterTip
includeVersionTip={isKibanaVersioningEnabled}
entityNamePlural={entityNamePlural}
/>
</>
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,24 +73,39 @@ export const ViewsStats = ({ item }: { item: Item }) => {
);
};

const NoViewsTip = () => (
<EuiIconTip
aria-label={i18n.translate('contentManagement.contentEditor.viewsStats.noViewsTipAriaLabel', {
defaultMessage: 'Additional information',
})}
position="top"
color="inherit"
iconProps={{ style: { verticalAlign: 'text-bottom', marginLeft: 2 } }}
css={{ textWrap: 'balance' }}
type="questionInCircle"
content={
<FormattedMessage
id="contentManagement.contentEditor.viewsStats.noViewsTip"
defaultMessage="Views are counted every time someone opens a dashboard"
/>
}
/>
);
const NoViewsTip = () => {
const isKibanaVersioningEnabled = useServices()?.isKibanaVersioningEnabled ?? false;
return (
<EuiIconTip
aria-label={i18n.translate('contentManagement.contentEditor.viewsStats.noViewsTipAriaLabel', {
defaultMessage: 'Additional information',
})}
position="top"
color="inherit"
iconProps={{ style: { verticalAlign: 'text-bottom', marginLeft: 2 } }}
css={{ textWrap: 'balance' }}
type="questionInCircle"
content={
<>
<FormattedMessage
id="contentManagement.contentEditor.viewsStats.noViewsTip"
defaultMessage="Views are counted every time someone opens a dashboard"
/>
{isKibanaVersioningEnabled && (
<>
{' '}
<FormattedMessage
id="contentManagement.contentEditor.viewsStats.noViewsVersionTip"
defaultMessage="(after version {version})"
values={{ version: '8.16' }}
/>
</>
)}
</>
}
/>
);
};

export function getTotalDays(stats: ContentInsightsStats) {
return moment.utc().diff(moment.utc(stats.from), 'days');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ import { ContentInsightsClientPublic } from './client';
*/
export interface ContentInsightsServices {
contentInsightsClient: ContentInsightsClientPublic;
/**
* Whether versioning is enabled for the current kibana instance. (aka is Serverless)
* This is used to determine if we should show the version mentions in the help text.
*/
isKibanaVersioningEnabled: boolean;
}

const ContentInsightsContext = React.createContext<ContentInsightsServices | null>(null);
Expand All @@ -34,7 +39,10 @@ export const ContentInsightsProvider: FC<PropsWithChildren<Partial<ContentInsigh

return (
<ContentInsightsContext.Provider
value={{ contentInsightsClient: services.contentInsightsClient }}
value={{
contentInsightsClient: services.contentInsightsClient,
isKibanaVersioningEnabled: services.isKibanaVersioningEnabled ?? false,
}}
>
{children}
</ContentInsightsContext.Provider>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export const getMockServices = (overrides?: Partial<Services & UserProfilesServi
isFavoritesEnabled: () => false,
bulkGetUserProfiles: async () => [],
getUserProfile: async () => ({ uid: '', enabled: true, data: {}, user: { username: '' } }),
isKibanaVersioningEnabled: false,
...overrides,
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ import { ActivityView, ViewsStats } from '@kbn/content-management-content-insigh
/**
* This component is used as an extension for the ContentEditor to render the ActivityView and ViewsStats inside the flyout without depending on them directly
*/
export const ContentEditorActivityRow: FC<{ item: UserContentCommonSchema }> = ({ item }) => {
export const ContentEditorActivityRow: FC<{
item: UserContentCommonSchema;
entityNamePlural?: string;
}> = ({ item, entityNamePlural }) => {
return (
<EuiFormRow
fullWidth
Expand All @@ -40,7 +43,7 @@ export const ContentEditorActivityRow: FC<{ item: UserContentCommonSchema }> = (
}
>
<>
<ActivityView item={item} />
<ActivityView item={item} entityNamePlural={entityNamePlural} />
<EuiSpacer size={'s'} />
<ViewsStats item={item} />
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ export function Table<T extends UserContentCommonSchema>({
favoritesEnabled,
}: Props<T>) {
const euiTheme = useEuiTheme();
const { getTagList, isTaggingEnabled } = useServices();
const { getTagList, isTaggingEnabled, isKibanaVersioningEnabled } = useServices();

const renderToolsLeft = useCallback(() => {
if (!deleteItems || selectedIds.length === 0) {
Expand Down Expand Up @@ -340,6 +340,8 @@ export function Table<T extends UserContentCommonSchema>({
}}
selectedUsers={tableFilter.createdBy}
showNoUserOption={showNoUserOption}
isKibanaVersioningEnabled={isKibanaVersioningEnabled}
entityNamePlural={entityNamePlural}
>
<TagFilterContextProvider
isPopoverOpen={isPopoverOpen}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ interface Context {
selectedUsers: string[];
allUsers: string[];
showNoUserOption: boolean;
isKibanaVersioningEnabled: boolean;
entityNamePlural: string;
}

const UserFilterContext = React.createContext<Context | null>(null);
Expand All @@ -44,7 +46,13 @@ export const UserFilterPanel: FC<{}> = () => {
if (!componentContext)
throw new Error('UserFilterPanel must be used within a UserFilterContextProvider');

const { onSelectedUsersChange, selectedUsers, showNoUserOption } = componentContext;
const {
onSelectedUsersChange,
selectedUsers,
showNoUserOption,
isKibanaVersioningEnabled,
entityNamePlural,
} = componentContext;

const [isPopoverOpen, setPopoverOpen] = React.useState(false);
const [searchTerm, setSearchTerm] = React.useState('');
Expand Down Expand Up @@ -126,7 +134,12 @@ export const UserFilterPanel: FC<{}> = () => {
id="contentManagement.tableList.listing.userFilter.emptyMessage"
defaultMessage="None of the dashboards have creators"
/>
{<NoCreatorTip />}
{
<NoCreatorTip
includeVersionTip={isKibanaVersioningEnabled}
entityNamePlural={entityNamePlural}
/>
}
</p>
),
nullOptionLabel: i18n.translate(
Expand All @@ -136,7 +149,12 @@ export const UserFilterPanel: FC<{}> = () => {
}
),
nullOptionProps: {
append: <NoCreatorTip />,
append: (
<NoCreatorTip
includeVersionTip={isKibanaVersioningEnabled}
entityNamePlural={entityNamePlural}
/>
),
},
clearButtonLabel: (
<FormattedMessage
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ export const getStoryServices = (params: Params, action: ActionFn = () => {}) =>
getTagIdsFromReferences: () => [],
isTaggingEnabled: () => true,
isFavoritesEnabled: () => false,
isKibanaVersioningEnabled: false,
...params,
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ export interface Services {
/** Handler to return the url to navigate to the kibana tags management */
getTagManagementUrl: () => string;
getTagIdsFromReferences: (references: SavedObjectsReference[]) => string[];
/** Whether versioning is enabled for the current kibana instance. (aka is Serverless)
This is used to determine if we should show the version mentions in the help text.*/
isKibanaVersioningEnabled: boolean;
}

const TableListViewContext = React.createContext<Services | null>(null);
Expand Down Expand Up @@ -185,6 +188,12 @@ export interface TableListViewKibanaDependencies {
* Content insights client to enable content insights features.
*/
contentInsightsClient?: ContentInsightsClientPublic;

/**
* Flag to indicate if Kibana versioning is enabled. (aka not Serverless)
* Used to determine if we should show the version mentions in the help text.
*/
isKibanaVersioningEnabled?: boolean;
}

/**
Expand Down Expand Up @@ -251,7 +260,10 @@ export const TableListViewKibanaProvider: FC<
<RedirectAppLinksKibanaProvider coreStart={core}>
<UserProfilesKibanaProvider core={core}>
<ContentEditorKibanaProvider core={core} savedObjectsTagging={savedObjectsTagging}>
<ContentInsightsProvider contentInsightsClient={services.contentInsightsClient}>
<ContentInsightsProvider
contentInsightsClient={services.contentInsightsClient}
isKibanaVersioningEnabled={services.isKibanaVersioningEnabled}
>
<FavoritesContextProvider
favoritesClient={services.favorites}
notifyError={(title, text) => {
Expand Down Expand Up @@ -282,6 +294,7 @@ export const TableListViewKibanaProvider: FC<
itemHasTags={itemHasTags}
getTagIdsFromReferences={getTagIdsFromReferences}
getTagManagementUrl={() => core.http.basePath.prepend(TAG_MANAGEMENT_APP_URL)}
isKibanaVersioningEnabled={services.isKibanaVersioningEnabled ?? false}
>
{children}
</TableListViewProvider>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,7 @@ function TableListViewTableComp<T extends UserContentCommonSchema>({
DateFormatterComp,
getTagList,
isFavoritesEnabled,
isKibanaVersioningEnabled,
} = useServices();

const openContentEditor = useOpenContentEditor();
Expand Down Expand Up @@ -578,7 +579,7 @@ function TableListViewTableComp<T extends UserContentCommonSchema>({
appendRows: contentInsightsServices && (
// have to "REWRAP" in the provider here because it will be rendered in a different context
<ContentInsightsProvider {...contentInsightsServices}>
<ContentEditorActivityRow item={item} />
<ContentEditorActivityRow item={item} entityNamePlural={entityNamePlural} />
</ContentInsightsProvider>
),
});
Expand All @@ -591,6 +592,7 @@ function TableListViewTableComp<T extends UserContentCommonSchema>({
tableItemsRowActions,
fetchItems,
contentInsightsServices,
entityNamePlural,
]
);

Expand Down Expand Up @@ -646,7 +648,7 @@ function TableListViewTableComp<T extends UserContentCommonSchema>({
) : record.managed ? (
<ManagedAvatarTip entityName={entityName} />
) : (
<NoCreatorTip iconType={'minus'} />
<NoCreatorTip iconType={'minus'} includeVersionTip={isKibanaVersioningEnabled} />
),
sortable:
false /* createdBy column is not sortable because it doesn't make sense to sort by id*/,
Expand Down Expand Up @@ -753,6 +755,7 @@ function TableListViewTableComp<T extends UserContentCommonSchema>({
inspectItem,
entityName,
isFavoritesEnabled,
isKibanaVersioningEnabled,
]);

const itemsById = useMemo(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,67 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/

import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
import { EuiIconTip, IconType } from '@elastic/eui';
import React from 'react';

export const NoCreatorTip = (props: { iconType?: IconType }) => (
const fallbackEntityNamePlural = i18n.translate(
'contentManagement.userProfiles.fallbackEntityNamePlural',
{ defaultMessage: 'objects' }
);

export const NoCreatorTip = (props: {
iconType?: IconType;
includeVersionTip?: boolean;
entityNamePlural?: string;
}) => (
<NoUsersTip
content={
<FormattedMessage
id="contentManagement.userProfiles.noCreatorTip"
defaultMessage="Creators are assigned when objects are created"
/>
props.includeVersionTip ? (
<FormattedMessage
id="contentManagement.userProfiles.noCreatorTipWithVersion"
defaultMessage="Created by is set when {entityNamePlural} are created by users (not by API) starting from version {version}"
values={{
version: '8.14',
entityNamePlural: props.entityNamePlural ?? fallbackEntityNamePlural,
}}
/>
) : (
<FormattedMessage
id="contentManagement.userProfiles.noCreatorTip"
defaultMessage="Created by is set when {entityNamePlural} are created by users (not by API)"
values={{ entityNamePlural: props.entityNamePlural ?? fallbackEntityNamePlural }}
/>
)
}
{...props}
/>
);

export const NoUpdaterTip = (props: { iconType?: string }) => (
export const NoUpdaterTip = (props: {
iconType?: string;
includeVersionTip?: boolean;
entityNamePlural?: string;
}) => (
<NoUsersTip
content={
<FormattedMessage
id="contentManagement.userProfiles.noUpdaterTip"
defaultMessage="Updated by is set when objects are updated"
/>
props.includeVersionTip ? (
<FormattedMessage
id="contentManagement.userProfiles.noUpdaterTipWithVersion"
defaultMessage="Updated by is set when {entityNamePlural} are updated by users (not by API) starting from version {version}"
values={{
version: '8.15',
entityNamePlural: props.entityNamePlural ?? fallbackEntityNamePlural,
}}
/>
) : (
<FormattedMessage
id="contentManagement.userProfiles.noUpdaterTip"
defaultMessage="Updated by is set when {entityNamePlural} are created by users (not by API)"
values={{ entityNamePlural: props.entityNamePlural ?? fallbackEntityNamePlural }}
/>
)
}
{...props}
/>
Expand Down
Loading

0 comments on commit 5262649

Please sign in to comment.