Skip to content

Commit

Permalink
feat(telemetry): add telemetry events to the settings page (#6198)
Browse files Browse the repository at this point in the history
  • Loading branch information
aditya-radhakrishnan authored Oct 13, 2022
1 parent 09616ee commit a58502c
Show file tree
Hide file tree
Showing 13 changed files with 220 additions and 22 deletions.
98 changes: 97 additions & 1 deletion datahub-web-react/src/app/analytics/event.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,20 @@ export enum EventType {
DownloadAsCsvEvent,
SignUpEvent,
ResetCredentialsEvent,
CreateAccessTokenEvent,
RevokeAccessTokenEvent,
CreateGroupEvent,
CreateInviteLinkEvent,
CreateResetCredentialsLinkEvent,
DeleteEntityEvent,
SelectUserRoleEvent,
BatchSelectUserRoleEvent,
CreatePolicyEvent,
UpdatePolicyEvent,
DeactivatePolicyEvent,
ActivatePolicyEvent,
ShowSimplifiedHomepageEvent,
ShowStandardHomepageEvent,
}

/**
Expand Down Expand Up @@ -247,6 +261,74 @@ export interface DownloadAsCsvEvent extends BaseEvent {
path: string;
}

export interface CreateAccessTokenEvent extends BaseEvent {
type: EventType.CreateAccessTokenEvent;
accessTokenType: string;
duration: string;
}

export interface RevokeAccessTokenEvent extends BaseEvent {
type: EventType.RevokeAccessTokenEvent;
}

export interface CreateGroupEvent extends BaseEvent {
type: EventType.CreateGroupEvent;
}
export interface CreateInviteLinkEvent extends BaseEvent {
type: EventType.CreateInviteLinkEvent;
roleUrn?: string;
}

export interface CreateResetCredentialsLinkEvent extends BaseEvent {
type: EventType.CreateResetCredentialsLinkEvent;
userUrn: string;
}

export interface DeleteEntityEvent extends BaseEvent {
type: EventType.DeleteEntityEvent;
entityUrn: string;
entityType: EntityType;
}

export interface SelectUserRoleEvent extends BaseEvent {
type: EventType.SelectUserRoleEvent;
roleUrn: string;
userUrn: string;
}

export interface BatchSelectUserRoleEvent extends BaseEvent {
type: EventType.BatchSelectUserRoleEvent;
roleUrn: string;
userUrns: string[];
}

export interface CreatePolicyEvent extends BaseEvent {
type: EventType.CreatePolicyEvent;
}

export interface UpdatePolicyEvent extends BaseEvent {
type: EventType.UpdatePolicyEvent;
policyUrn: string;
}

export interface DeactivatePolicyEvent extends BaseEvent {
type: EventType.DeactivatePolicyEvent;
policyUrn: string;
}

export interface ActivatePolicyEvent extends BaseEvent {
type: EventType.ActivatePolicyEvent;
policyUrn: string;
}

export interface ShowSimplifiedHomepageEvent extends BaseEvent {
type: EventType.ShowSimplifiedHomepageEvent;
}

export interface ShowStandardHomepageEvent extends BaseEvent {
type: EventType.ShowStandardHomepageEvent;
}

/**
* Event consisting of a union of specific event types.
*/
Expand All @@ -272,4 +354,18 @@ export type Event =
| DownloadAsCsvEvent
| RecommendationClickEvent
| HomePageRecommendationClickEvent
| BatchEntityActionEvent;
| BatchEntityActionEvent
| CreateAccessTokenEvent
| RevokeAccessTokenEvent
| CreateGroupEvent
| CreateInviteLinkEvent
| CreateResetCredentialsLinkEvent
| DeleteEntityEvent
| SelectUserRoleEvent
| BatchSelectUserRoleEvent
| CreatePolicyEvent
| UpdatePolicyEvent
| DeactivatePolicyEvent
| ActivatePolicyEvent
| ShowSimplifiedHomepageEvent
| ShowStandardHomepageEvent;
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { message, Modal } from 'antd';
import { EntityType } from '../../../../types.generated';
import { useEntityRegistry } from '../../../useEntityRegistry';
import { getDeleteEntityMutation } from '../../../shared/deleteUtils';
import analytics, { EventType } from '../../../analytics';

/**
* Performs the flow for deleting an entity of a given type.
Expand All @@ -25,6 +26,11 @@ function useDeleteEntity(urn: string, type: EntityType, entityData: any, onDelet
},
})
.then(() => {
analytics.event({
type: EventType.DeleteEntityEvent,
entityUrn: urn,
entityType: type,
});
message.loading({
content: 'Deleting...',
duration: 2,
Expand Down
8 changes: 8 additions & 0 deletions datahub-web-react/src/app/identity/group/CreateGroupModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { message, Button, Input, Modal, Typography, Form, Collapse } from 'antd'
import { useCreateGroupMutation } from '../../../graphql/group.generated';
import { useEnterKeyListener } from '../../shared/useEnterKeyListener';
import { groupIdTextValidation } from '../../shared/textUtil';
import analytics, { EventType } from '../../analytics';

type Props = {
onClose: () => void;
Expand All @@ -27,6 +28,13 @@ export default function CreateGroupModal({ onClose, onCreate }: Props) {
},
},
})
.then(({ errors }) => {
if (!errors) {
analytics.event({
type: EventType.CreateGroupEvent,
});
}
})
.catch((e) => {
message.destroy();
message.error({ content: `Failed to create group!: \n ${e.message || ''}`, duration: 3 });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from 'react';
import { message, Popconfirm } from 'antd';
import { useBatchAssignRoleMutation } from '../../../graphql/mutations.generated';
import { DataHubRole } from '../../../types.generated';
import analytics, { EventType } from '../../analytics';

type Props = {
visible: boolean;
Expand Down Expand Up @@ -34,6 +35,11 @@ export default function AssignRoleConfirmation({
})
.then(({ errors }) => {
if (!errors) {
analytics.event({
type: EventType.SelectUserRoleEvent,
roleUrn: roleToAssign.urn,
userUrn,
});
message.success({
content: `Assigned role ${roleToAssign?.name} to user ${username}!`,
duration: 2,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { DataHubRole } from '../../../types.generated';
import { mapRoleIcon } from './UserUtils';
import { useCreateInviteTokenMutation } from '../../../graphql/mutations.generated';
import { ANTD_GRAY } from '../../entity/shared/constants';
import analytics, { EventType } from '../../analytics';

const ModalSection = styled.div`
display: flex;
Expand Down Expand Up @@ -138,6 +139,10 @@ export default function ViewInviteTokenModal({ visible, onClose }: Props) {
})
.then(({ data, errors }) => {
if (!errors) {
analytics.event({
type: EventType.CreateInviteLinkEvent,
roleUrn,
});
setInviteToken(data?.createInviteToken?.inviteToken || '');
message.success('Generated new invite link');
}
Expand Down
47 changes: 31 additions & 16 deletions datahub-web-react/src/app/identity/user/ViewResetTokenModal.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { RedoOutlined } from '@ant-design/icons';
import { Button, Modal, Typography } from 'antd';
import { Button, message, Modal, Typography } from 'antd';
import React, { useState } from 'react';
import styled from 'styled-components';
import { PageRoutes } from '../../../conf/Global';
import { useCreateNativeUserResetTokenMutation } from '../../../graphql/user.generated';
import analytics, { EventType } from '../../analytics';

const ModalSection = styled.div`
display: flex;
Expand Down Expand Up @@ -43,9 +44,36 @@ export default function ViewResetTokenModal({ visible, userUrn, username, onClos
const baseUrl = window.location.origin;
const [hasGeneratedResetToken, setHasGeneratedResetToken] = useState(false);

const [createNativeUserResetToken, { data: createNativeUserResetTokenData }] =
const [createNativeUserResetTokenMutation, { data: createNativeUserResetTokenData }] =
useCreateNativeUserResetTokenMutation({});

const createNativeUserResetToken = () => {
createNativeUserResetTokenMutation({
variables: {
input: {
userUrn,
},
},
})
.then(({ errors }) => {
if (!errors) {
analytics.event({
type: EventType.CreateResetCredentialsLinkEvent,
userUrn,
});
setHasGeneratedResetToken(true);
message.success('Generated new link to reset credentials');
}
})
.catch((e) => {
message.destroy();
message.error({
content: `Failed to create new link to reset credentials : \n ${e.message || ''}`,
duration: 3,
});
});
};

const resetToken = createNativeUserResetTokenData?.createNativeUserResetToken?.resetToken || '';

const inviteLink = `${baseUrl}${PageRoutes.RESET_CREDENTIALS}?reset_token=${resetToken}`;
Expand Down Expand Up @@ -86,20 +114,7 @@ export default function ViewResetTokenModal({ visible, userUrn, username, onClos
<ModalSectionParagraph>
Generate a new reset link! Note, any old links will <b>cease to be active</b>.
</ModalSectionParagraph>
<CreateResetTokenButton
onClick={() => {
createNativeUserResetToken({
variables: {
input: {
userUrn,
},
},
});
setHasGeneratedResetToken(true);
}}
size="small"
type="text"
>
<CreateResetTokenButton onClick={createNativeUserResetToken} size="small" type="text">
<RedoOutlined style={{}} />
</CreateResetTokenButton>
</ModalSection>
Expand Down
30 changes: 28 additions & 2 deletions datahub-web-react/src/app/permissions/policy/ManagePolicies.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
PolicyMatchFilter,
PolicyMatchFilterInput,
PolicyMatchCriterionInput,
EntityType,
} from '../../../types.generated';
import { useAppConfig } from '../../useAppConfig';
import PolicyDetailsModal from './PolicyDetailsModal';
Expand All @@ -33,6 +34,7 @@ import { useEntityRegistry } from '../../useEntityRegistry';
import { ANTD_GRAY } from '../../entity/shared/constants';
import { SearchBar } from '../../search/SearchBar';
import { scrollToTop } from '../../shared/searchUtils';
import analytics, { EventType } from '../../analytics';

const SourceContainer = styled.div``;

Expand Down Expand Up @@ -247,6 +249,11 @@ export const ManagePolicies = () => {
content: `Are you sure you want to remove policy?`,
onOk() {
deletePolicy({ variables: { urn: policy?.urn as string } }); // There must be a focus policy urn.
analytics.event({
type: EventType.DeleteEntityEvent,
entityUrn: policy?.urn,
entityType: EntityType.DatahubPolicy,
});
message.success('Successfully removed policy.');
setTimeout(function () {
policiesRefetch();
Expand Down Expand Up @@ -285,9 +292,16 @@ export const ManagePolicies = () => {
if (focusPolicyUrn) {
// If there's an URN associated with the focused policy, then we are editing an existing policy.
updatePolicy({ variables: { urn: focusPolicyUrn, input: toPolicyInput(savePolicy) } });
analytics.event({
type: EventType.UpdatePolicyEvent,
policyUrn: focusPolicyUrn,
});
} else {
// If there's no URN associated with the focused policy, then we are creating.
createPolicy({ variables: { input: toPolicyInput(savePolicy) } });
analytics.event({
type: EventType.CreatePolicyEvent,
});
}
message.success('Successfully saved policy.');
setTimeout(function () {
Expand Down Expand Up @@ -369,15 +383,27 @@ export const ManagePolicies = () => {
{record?.state === PolicyState.Active ? (
<Button
disabled={!record?.editable}
onClick={() => onToggleActiveDuplicate(record?.policy)}
onClick={() => {
onToggleActiveDuplicate(record?.policy);
analytics.event({
type: EventType.DeactivatePolicyEvent,
policyUrn: record?.policy?.urn,
});
}}
style={{ color: record?.editable ? 'red' : ANTD_GRAY[6], width: 100 }}
>
DEACTIVATE
</Button>
) : (
<Button
disabled={!record?.editable}
onClick={() => onToggleActiveDuplicate(record?.policy)}
onClick={() => {
onToggleActiveDuplicate(record?.policy);
analytics.event({
type: EventType.ActivatePolicyEvent,
policyUrn: record?.policy?.urn,
});
}}
style={{ color: record?.editable ? 'green' : ANTD_GRAY[6], width: 100 }}
>
ACTIVATE
Expand Down
6 changes: 6 additions & 0 deletions datahub-web-react/src/app/permissions/roles/ManageRoles.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { EntityCapabilityType } from '../../entity/Entity';
import { useBatchAssignRoleMutation } from '../../../graphql/mutations.generated';
import { CorpUser, DataHubRole, DataHubPolicy } from '../../../types.generated';
import RoleDetailsModal from './RoleDetailsModal';
import analytics, { EventType } from '../../analytics';

const SourceContainer = styled.div``;

Expand Down Expand Up @@ -99,6 +100,11 @@ export const ManageRoles = () => {
})
.then(({ errors }) => {
if (!errors) {
analytics.event({
type: EventType.BatchSelectUserRoleEvent,
roleUrn: focusRole?.urn,
userUrns: actorUrns,
});
message.success({
content: `Assigned Role to users!`,
duration: 2,
Expand Down
7 changes: 7 additions & 0 deletions datahub-web-react/src/app/settings/AccessTokens.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import CreateTokenModal from './CreateTokenModal';
import { useAppConfigQuery } from '../../graphql/app.generated';
import { getLocaleTimezone } from '../shared/time/timeUtils';
import { scrollToTop } from '../shared/searchUtils';
import analytics, { EventType } from '../analytics';

const SourceContainer = styled.div`
width: 100%;
Expand Down Expand Up @@ -130,7 +131,13 @@ export const AccessTokens = () => {
// Hack to deal with eventual consistency.
const newTokenIds = [...removedTokens, token.id];
setRemovedTokens(newTokenIds);

revokeAccessToken({ variables: { tokenId: token.id } })
.then(({ errors }) => {
if (!errors) {
analytics.event({ type: EventType.RevokeAccessTokenEvent });
}
})
.catch((e) => {
message.destroy();
message.error({ content: `Failed to revoke Token!: \n ${e.message || ''}`, duration: 3 });
Expand Down
Loading

0 comments on commit a58502c

Please sign in to comment.