/** * @flow * @file Faces Skill Card component * @author Box */ import * as React from 'react'; import { FormattedMessage } from 'react-intl'; import classNames from 'classnames'; import PlainButton from '../../../../components/plain-button/PlainButton'; import PrimaryButton from '../../../../components/primary-button/PrimaryButton'; import LoadingIndicatorWrapper from '../../../../components/loading-indicator/LoadingIndicatorWrapper'; import InlineError from '../../../../components/inline-error/InlineError'; import Tooltip from '../../../../components/tooltip/Tooltip'; import Button from '../../../../components/button/Button'; import IconEdit from '../../../../icons/general/IconEdit'; import messages from '../../../common/messages'; import { SKILLS_TARGETS } from '../../../common/interactionTargets'; import Face from './Face'; import Timeline from '../timeline'; import type { SkillCardEntry, SkillCard } from '../../../../common/types/skills'; import './Faces.scss'; type Props = { card: SkillCard, getViewer?: Function, hasError: boolean, isEditable: boolean, onSkillChange: Function, }; type State = { faces: Array, hasError: boolean, isEditing: boolean, isLoading: boolean, removes: Array, selected?: SkillCardEntry, }; class Faces extends React.PureComponent { props: Props; state: State; /** * [constructor] * * @public * @return {Faces} */ constructor(props: Props) { super(props); this.state = { faces: props.card.entries, removes: [], isEditing: props.hasError, hasError: props.hasError, isLoading: false, }; } /** * Helper to reset the state * * @private * @param {Object} props - component props * @return {void} */ resetState(props: Props): void { this.setState({ faces: props.card.entries, removes: [], isEditing: false, selected: undefined, hasError: false, isLoading: false, }); } /** * Toggles the edit mode * * @private * @return {void} */ toggleIsEditing = (): void => { this.setState(prevState => ({ isEditing: !prevState.isEditing, })); }; /** * Toggles face selection * * @private * @return {void} */ onSelect = (face: SkillCardEntry): void => { const { selected } = this.state; this.setState({ selected: selected === face ? undefined : face, }); }; /** * Deletes a face * * @private * @return {void} */ onDelete = (face: SkillCardEntry): void => { const { removes } = this.state; removes.push(face); this.setState({ removes: removes.slice(0) }); }; /** * Saves the new card data * * @private * @return {void} */ onSave = (): void => { const { onSkillChange }: Props = this.props; const { removes }: State = this.state; this.toggleIsEditing(); if (removes.length > 0) { this.setState({ isLoading: true }); onSkillChange(removes); } }; /** * Cancels editing * * @private * @return {void} */ onCancel = (): void => { this.resetState(this.props); }; /** * Renders the faces * * @private * @return {void} */ render() { const { card, isEditable, getViewer }: Props = this.props; const { selected, faces, removes, isEditing, hasError, isLoading }: State = this.state; const { duration }: SkillCard = card; const hasFaces = faces.length > 0; const entries = faces.filter((face: SkillCardEntry) => !removes.includes(face)); const editClassName = classNames('be-face-edit', { 'be-faces-is-editing': isEditing, }); return ( {hasFaces && isEditable && !isLoading && ( }> )} {hasError && ( }> )} {hasFaces ? ( entries.map((face: SkillCardEntry, index: number) => ( /* eslint-disable react/no-array-index-key */ /* eslint-enable react/no-array-index-key */ )) ) : ( )} {!!selected && !isEditing && Array.isArray(selected.appears) && selected.appears.length > 0 && ( )} {isEditing && (
)}
); } } export default Faces;