-
Notifications
You must be signed in to change notification settings - Fork 358
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'develop' into unit-test-stability
- Loading branch information
Showing
1,343 changed files
with
50,609 additions
and
22,739 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
# API Events | ||
|
||
In order to display Events, Cloud Manager polls the [account/events](https://www.linode.com/docs/api/account/#events-list) endpoint at a 16 second interval, or every 2 seconds if there are “in-progress” events. | ||
|
||
In order to display these messages in the application (Notification Center, /events page), we compose messages according to the Event key (`EventAction`). Each key requires an entry and set of custom messages for each status (`EventStatus`), dictated by API specs. Not every Status is required for a given Action. | ||
|
||
## Adding a new Action and Composing Messages | ||
|
||
In order to add a new Action, one must add a new key to the read-only `EventActionKeys` constant array in the api-v4 package. | ||
Once that's done, a related entry must be added to the `eventMessages` Event Map. In order to do so, the entry can either be added to an existing Event Factory or a new one. `eventMessages` is strictly typed, so the decision where to add the new Action will be clear. ex: | ||
|
||
```Typescript | ||
import { EventLink } from '../EventLink'; | ||
|
||
import type { PartialEventMap } from '../types'; | ||
|
||
export const linode: PartialEventMap<'linode'> = { | ||
linode_addip: { | ||
notification: (e) => ( | ||
<> | ||
An IP address has been <strong>added</strong> to Linode{' '} | ||
<EventLink event={e} to="entity" />. | ||
</> | ||
), | ||
}, | ||
}; | ||
``` | ||
|
||
The convention to compose the message is as follows: | ||
- Use the `<EventLink />` component for linking `entity` or `secondary_entity`. This component includes a lookup util to format the link `href` according to the feature. | ||
- The bolding should only be applied to: | ||
- the primary action: (ex: `<strong>created</strong>`) | ||
- its correlated negation for negative actions (ex: `could <strong>not</strong> be <strong>created</strong>.`) | ||
- The `message` should be also handled via the `<EventMessage message={e.message} />` in order to handle potential formatting from the API string (ticks to indicate code blocks). | ||
|
||
## Displaying Events in snackbars | ||
|
||
We can leverage the Event Message factories in order to display events in snackbars/toasts when a given action gets triggered via APIv4. | ||
|
||
```Typescript | ||
const { enqueueSnackbar } = useSnackbar(); | ||
|
||
try { | ||
const successMessage = getEventMessage({ | ||
action: 'image_upload', | ||
entity: { | ||
label: 'Entity', | ||
url: '/image/123', | ||
}, | ||
status: 'notification', | ||
}); | ||
|
||
const showToast = (variant: any) => | ||
enqueueSnackbar(successMessage, { | ||
'success', | ||
}); | ||
}, catch { | ||
const failureMessage = getEventMessage({ | ||
action: 'image_upload', | ||
// in this case we don't add an entity since we know we can't link to it | ||
status: 'failed', | ||
}); | ||
|
||
const showToast = (variant: any) => | ||
enqueueSnackbar(failureMessage, { | ||
'error', | ||
}); | ||
} | ||
``` | ||
|
||
Both `action` and `status` are required. The `entity` and `secondary_entity` can optionally be passed to allow for linking. **Note**: it is possible the Event Message linking will be missing if the action status message expects either value but isn't not provided by the instance call. | ||
|
||
If a corresponding status does not exist (ex: "failed"), it's encouraged to add it to the Action. Event if not triggered by the API, it can be useful to have a reusable Event Message to use through the App. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
# Adobe Analytics | ||
|
||
Cloud Manager uses Adobe Analytics to capture page view and custom event statistics. To view analytics, Cloud Manager developers must follow internal processes to request access to Adobe Analytics dashboards. | ||
|
||
## Writing a Custom Event | ||
|
||
Custom events live (mostly) in `src/utilities/analytics/customEventAnalytics.ts`. Try to write and export custom events in this file if possible, and import them in the component(s) where they are used. | ||
|
||
A custom event will take this shape: | ||
```tsx | ||
// Component.tsx {file(s) where the event is called, for quick reference} | ||
// OtherComponent.tsx | ||
|
||
sendDescriptiveNameEvent () => { | ||
category: '{Descriptive/Page/Flow Name}', | ||
action: '{interaction such as Click, Hover, Focus}:{input type such as button, link, toggle, checkbox, text field} e.g. Click:link', | ||
label: '{string associated with the event; e.g event label} (optional)', | ||
value: '{number associated with the event; e.g. size of a volume} (optional)', | ||
data: '{stringified object of additional key-value pairs; e.g. "{isLinodePoweredOff: true}"} (optional)' | ||
} | ||
``` | ||
|
||
When adding a new custom event, coordinate with UX on the event's `category`, `action`, `label`, and `value` variables to ensure consistency across our data. | ||
|
||
`data` is an additional variable we use to capture information associated with an event that cannot easily or clearly be represented via the other variables; for example, boolean key-value pair(s). To add an additional property to `data`, it should first be added as an optional property and typed in the `CustomAnalyticsData` interface. | ||
|
||
Avoid including pipes (`|`) as delimiters in any of the event properties. They are used in Adobe Analytics to separate fields. | ||
|
||
Avoid creating custom events that collect such as search queries, entity names, or other forms of user input. Custom events can still be fired on these actions with a generic `label` or no label at all. | ||
|
||
Examples | ||
|
||
- `sendMarketplaceSearchEvent` fires when selecting a category from the dropdown (`label` is predefined) and clicking the search field (a generic `label` is used). | ||
- `sendBucketCreateEvent` sends the region of the bucket, but does not send the bucket label. | ||
|
||
## Locally Testing Page Views & Custom Events and/or Troubleshooting | ||
|
||
1. Set the `REACT_APP_ADOBE_ANALYTICS_URL` environment variable in `.env`. | ||
2. Use the browser tools Network tab, filter requests by "adobe", and check that successful network requests have been made to load the launch script and its extensions. | ||
3. In the browser console, type `_satellite.setDebug(true)`. | ||
4. Refresh the page. You should see Adobe debug log output in the console. Each page view change or custom event that fires should be visible in the logs. | ||
5. When viewing dashboards in Adobe Analytics, it may take ~1 hour for analytics data to update. Once this happens, locally fired events will be visible in the dev dashboard. |
Oops, something went wrong.