123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- import {useState} from 'react';
- import styled from '@emotion/styled';
- import ActivityItem, {ActivityAuthorType} from 'sentry/components/activity/item';
- import space from 'sentry/styles/space';
- import {User} from 'sentry/types';
- import {NoteType} from 'sentry/types/alerts';
- import {ActivityType} from 'sentry/views/alerts/types';
- import NoteBody from './body';
- import EditorTools from './editorTools';
- import NoteHeader from './header';
- import NoteInput from './input';
- type Props = {
- /**
- * String for author name to be displayed in header.
- *
- * This is not completely derived from `props.user` because we can set a
- * default from parent component
- */
- authorName: string;
- dateCreated: Date | string;
- /**
- * min-height for NoteInput textarea
- */
- minHeight: number;
- /**
- * This is the id of the note object from the server. This is to indicate you
- * are editing an existing item
- */
- modelId: string;
- onDelete: (props: Props) => void;
- onUpdate: (data: NoteType, props: Props) => void;
- /**
- * If used, will fetch list of teams/members that can be mentioned for projects
- */
- projectSlugs: string[];
- /**
- * Pass through to ActivityItem. Shows absolute time instead of a relative
- * string
- */
- showTime: boolean;
- /**
- * The note text itself
- */
- text: string;
- user: User;
- /**
- * This is unusual usage that Alert Details uses to get back the activity
- * that an input was bound to as the onUpdate and onDelete actions forward
- * this component's props.
- */
- activity?: ActivityType;
- /**
- * pass through to ActivityItem. Hides the date/timestamp in header
- */
- hideDate?: boolean;
- onCreate?: (data: NoteType) => void;
- };
- function Note(props: Props) {
- const [editing, setEditing] = useState(false);
- const {
- modelId,
- user,
- dateCreated,
- text,
- authorName,
- hideDate,
- minHeight,
- showTime,
- projectSlugs,
- onDelete,
- onCreate,
- onUpdate,
- } = props;
- const activityItemProps = {
- hideDate,
- showTime,
- id: `activity-item-${modelId}`,
- author: {
- type: 'user' as ActivityAuthorType,
- user,
- },
- date: dateCreated,
- };
- if (!editing) {
- const header = (
- <NoteHeader
- {...{authorName, user}}
- onEdit={() => setEditing(true)}
- onDelete={() => onDelete(props)}
- />
- );
- return (
- <ActivityItemWithEditing {...activityItemProps} header={header}>
- <NoteBody text={text} />
- </ActivityItemWithEditing>
- );
- }
- // When editing, `NoteInput` has its own header, pass render func to control
- // rendering of bubble body
- return (
- <ActivityItemNote {...activityItemProps}>
- {() => (
- <NoteInput
- {...{modelId, minHeight, text, projectSlugs}}
- onEditFinish={() => setEditing(false)}
- onUpdate={note => {
- onUpdate(note, props);
- setEditing(false);
- }}
- onCreate={note => onCreate?.(note)}
- />
- )}
- </ActivityItemNote>
- );
- }
- const ActivityItemNote = styled(ActivityItem)`
- /* this was nested under ".activity-note.activity-bubble" */
- ul {
- list-style: disc;
- }
- h1,
- h2,
- h3,
- h4,
- p,
- ul:not(.nav),
- ol,
- pre,
- hr,
- blockquote {
- margin-bottom: ${space(2)};
- }
- ul:not(.nav),
- ol {
- padding-left: 20px;
- }
- p {
- a {
- word-wrap: break-word;
- }
- }
- blockquote {
- font-size: 15px;
- border-left: 5px solid ${p => p.theme.innerBorder};
- padding-left: ${space(1)};
- margin-left: 0;
- }
- `;
- const ActivityItemWithEditing = styled(ActivityItemNote)`
- &:hover {
- ${EditorTools} {
- display: inline-block;
- }
- }
- `;
- export default Note;
|