feature: add quick card labels popup

This commit is contained in:
Jordan Knott 2020-05-30 23:51:22 -05:00
parent 2a59cddadb
commit f1f69440c3
5 changed files with 81 additions and 59 deletions

View File

@ -67,7 +67,8 @@ interface QuickCardEditorState {
isOpen: boolean; isOpen: boolean;
left: number; left: number;
top: number; top: number;
task?: Task; taskID: string | null;
taskGroupID: string | null;
} }
const TitleWrapper = styled.div` const TitleWrapper = styled.div`
@ -200,7 +201,13 @@ interface ProjectParams {
projectID: string; projectID: string;
} }
const initialQuickCardEditorState: QuickCardEditorState = { isOpen: false, top: 0, left: 0 }; const initialQuickCardEditorState: QuickCardEditorState = {
taskID: null,
taskGroupID: null,
isOpen: false,
top: 0,
left: 0,
};
const ProjectBar = styled.div` const ProjectBar = styled.div`
display: flex; display: flex;
@ -417,13 +424,22 @@ const Project = () => {
top: e.top, top: e.top,
left: e.left, left: e.left,
isOpen: true, isOpen: true,
task: currentTask, taskID: currentTask.id,
taskGroupID: currentTask.taskGroup.id,
}); });
} }
}; };
labelsRef.current = data.findProject.labels; labelsRef.current = data.findProject.labels;
let currentQuickTask = null;
if (quickCardEditor.taskID && quickCardEditor.taskGroupID) {
const targetGroup = data.findProject.taskGroups.find(t => t.id === quickCardEditor.taskGroupID);
if (targetGroup) {
currentQuickTask = targetGroup.tasks.find(t => t.id === quickCardEditor.taskID);
}
}
return ( return (
<> <>
<GlobalTopNavbar <GlobalTopNavbar
@ -535,17 +551,28 @@ const Project = () => {
); );
}} }}
/> />
{quickCardEditor.isOpen && ( {quickCardEditor.isOpen && currentQuickTask && (
<QuickCardEditor <QuickCardEditor
isOpen task={currentQuickTask}
taskID={quickCardEditor.task ? quickCardEditor.task.id : ''}
taskGroupID={quickCardEditor.task ? quickCardEditor.task.taskGroup.id : ''}
cardTitle={quickCardEditor.task ? quickCardEditor.task.name : ''}
onCloseEditor={() => setQuickCardEditor(initialQuickCardEditorState)} onCloseEditor={() => setQuickCardEditor(initialQuickCardEditorState)}
onEditCard={(_listId: string, cardId: string, cardName: string) => { onEditCard={(_listId: string, cardId: string, cardName: string) => {
updateTaskName({ variables: { taskID: cardId, name: cardName } }); updateTaskName({ variables: { taskID: cardId, name: cardName } });
}} }}
onOpenPopup={() => {}} onOpenLabelsPopup={($targetRef, task) => {
taskLabelsRef.current = task.labels;
showPopup(
$targetRef,
<LabelManagerEditor
onLabelToggle={labelID => {
toggleTaskLabel({ variables: { taskID: task.id, projectLabelID: labelID } });
}}
labelColors={data.labelColors}
labels={labelsRef}
taskLabels={taskLabelsRef}
projectID={projectID}
/>,
);
}}
onArchiveCard={(_listId: string, cardId: string) => onArchiveCard={(_listId: string, cardId: string) =>
deleteTask({ deleteTask({
variables: { taskID: cardId }, variables: { taskID: cardId },
@ -564,7 +591,6 @@ const Project = () => {
}, },
}) })
} }
labels={[]}
top={quickCardEditor.top} top={quickCardEditor.top}
left={quickCardEditor.left} left={quickCardEditor.left}
/> />

View File

@ -67,8 +67,8 @@ type Props = {
onClick: (e: React.MouseEvent<HTMLDivElement>) => void; onClick: (e: React.MouseEvent<HTMLDivElement>) => void;
dueDate?: DueDate; dueDate?: DueDate;
checklists?: Checklist; checklists?: Checklist;
watched?: boolean;
labels?: Array<ProjectLabel>; labels?: Array<ProjectLabel>;
watched?: boolean;
wrapperProps?: any; wrapperProps?: any;
members?: Array<TaskUser> | null; members?: Array<TaskUser> | null;
onCardMemberClick?: OnCardMemberClick; onCardMemberClick?: OnCardMemberClick;

View File

@ -17,16 +17,20 @@ export default {
}, },
}; };
const labelData: Array<ProjectLabel> = [ const labelData: Array<TaskLabel> = [
{ {
id: 'development', id: 'development',
name: 'Development', assignedDate: new Date().toString(),
createdDate: 'date', projectLabel: {
labelColor: { id: 'development',
id: 'label-color-blue', name: 'Development',
colorHex: LabelColors.BLUE, createdDate: 'date',
name: 'blue', labelColor: {
position: 1, id: 'label-color-blue',
colorHex: LabelColors.BLUE,
name: 'blue',
position: 1,
},
}, },
}, },
]; ];
@ -40,15 +44,19 @@ export const Default = () => {
<> <>
{isEditorOpen && ( {isEditorOpen && (
<QuickCardEditor <QuickCardEditor
isOpen={isEditorOpen} task={{
taskGroupID="1" id: 'task',
taskID="1" name: 'General',
cardTitle="Hello, world" taskGroup: {
id: '1',
},
position: 1,
labels: labelData,
}}
onCloseEditor={() => setEditorOpen(false)} onCloseEditor={() => setEditorOpen(false)}
onEditCard={action('edit card')} onEditCard={action('edit card')}
onOpenPopup={action('open popup')} onOpenLabelsPopup={action('open popup')}
onArchiveCard={action('archive card')} onArchiveCard={action('archive card')}
labels={labelData}
top={top} top={top}
left={left} left={left}
/> />
@ -75,7 +83,7 @@ export const Default = () => {
setEditorOpen(true); setEditorOpen(true);
}} }}
watched watched
labels={labelData} labels={labelData.map(l => l.projectLabel)}
checklists={{ complete: 1, total: 4 }} checklists={{ complete: 1, total: 4 }}
dueDate={{ isPastDue: false, formattedDate: 'Oct 26, 2020' }} dueDate={{ isPastDue: false, formattedDate: 'Oct 26, 2020' }}
/> />

View File

@ -1,5 +1,6 @@
import styled, { keyframes } from 'styled-components'; import styled, { keyframes } from 'styled-components';
import TextareaAutosize from 'react-autosize-textarea'; import TextareaAutosize from 'react-autosize-textarea';
import { mixin } from 'shared/utils/styles';
export const Wrapper = styled.div<{ open: boolean }>` export const Wrapper = styled.div<{ open: boolean }>`
background: rgba(0, 0, 0, 0.4); background: rgba(0, 0, 0, 0.4);
@ -21,9 +22,10 @@ export const Container = styled.div<{ top: number; left: number }>`
`; `;
export const Editor = styled.div` export const Editor = styled.div`
background-color: #fff; background-color: ${props => mixin.lighten('#262c49', 0.05)};
border-radius: 3px; border-radius: 3px;
box-shadow: 0 1px 0 rgba(9, 30, 66, 0.25); box-shadow: 0 1px 0 rgba(9, 30, 66, 0.25);
color: #c2c6dc;
padding: 6px 8px 2px; padding: 6px 8px 2px;
cursor: default; cursor: default;
display: block; display: block;
@ -59,6 +61,7 @@ export const EditorTextarea = styled(TextareaAutosize)`
padding: 0; padding: 0;
font-size: 16px; font-size: 16px;
line-height: 20px; line-height: 20px;
color: #fff;
&:focus { &:focus {
border: none; border: none;
outline: none; outline: none;
@ -67,7 +70,7 @@ export const EditorTextarea = styled(TextareaAutosize)`
export const SaveButton = styled.button` export const SaveButton = styled.button`
cursor: pointer; cursor: pointer;
background-color: #5aac44; background: rgb(115, 103, 240);
box-shadow: none; box-shadow: none;
border: none; border: none;
color: #fff; color: #fff;
@ -79,10 +82,12 @@ export const SaveButton = styled.button`
text-align: center; text-align: center;
border-radius: 3px; border-radius: 3px;
`; `;
export const FadeInAnimation = keyframes` export const FadeInAnimation = keyframes`
from { opacity: 0; transform: translateX(-20px); } from { opacity: 0; transform: translateX(-20px); }
to { opacity: 1; transform: translateX(0); } to { opacity: 1; transform: translateX(0); }
`; `;
export const EditorButtons = styled.div` export const EditorButtons = styled.div`
left: 100%; left: 100%;
position: absolute; position: absolute;

View File

@ -6,8 +6,8 @@ import {
Editor, Editor,
EditorDetails, EditorDetails,
EditorTextarea, EditorTextarea,
SaveButton,
EditorButtons, EditorButtons,
SaveButton,
EditorButton, EditorButton,
CloseButton, CloseButton,
ListCardLabels, ListCardLabels,
@ -15,33 +15,17 @@ import {
} from './Styles'; } from './Styles';
type Props = { type Props = {
taskID: string; task: Task;
taskGroupID: string;
cardTitle: string;
onCloseEditor: () => void; onCloseEditor: () => void;
onEditCard: (taskGroupID: string, taskID: string, cardName: string) => void; onEditCard: (taskGroupID: string, taskID: string, cardName: string) => void;
onOpenPopup: (popupType: number, top: number, left: number) => void; onOpenLabelsPopup: ($targetRef: React.RefObject<HTMLElement>, task: Task) => void;
onArchiveCard: (taskGroupID: string, taskID: string) => void; onArchiveCard: (taskGroupID: string, taskID: string) => void;
labels?: Array<ProjectLabel>;
isOpen: boolean;
top: number; top: number;
left: number; left: number;
}; };
const QuickCardEditor = ({ const QuickCardEditor = ({ task, onCloseEditor, onOpenLabelsPopup, onArchiveCard, onEditCard, top, left }: Props) => {
taskGroupID, const [currentCardTitle, setCardTitle] = useState(task.name);
taskID,
cardTitle,
onCloseEditor,
onOpenPopup,
onArchiveCard,
onEditCard,
labels,
isOpen,
top,
left,
}: Props) => {
const [currentCardTitle, setCardTitle] = useState(cardTitle);
const $editorRef: any = useRef(); const $editorRef: any = useRef();
const $labelsRef: any = useRef(); const $labelsRef: any = useRef();
useEffect(() => { useEffect(() => {
@ -57,23 +41,23 @@ const QuickCardEditor = ({
const handleKeyDown = (e: any) => { const handleKeyDown = (e: any) => {
if (e.key === 'Enter') { if (e.key === 'Enter') {
e.preventDefault(); e.preventDefault();
onEditCard(taskGroupID, taskID, currentCardTitle); onEditCard(task.taskGroup.id, task.id, currentCardTitle);
onCloseEditor(); onCloseEditor();
} }
}; };
return ( return (
<Wrapper onClick={handleCloseEditor} open={isOpen}> <Wrapper onClick={handleCloseEditor} open>
<CloseButton onClick={handleCloseEditor}> <CloseButton onClick={handleCloseEditor}>
<Cross size={16} color="#000" /> <Cross size={16} color="#000" />
</CloseButton> </CloseButton>
<Container left={left} top={top}> <Container left={left} top={top}>
<Editor> <Editor>
<ListCardLabels> <ListCardLabels>
{labels && {task.labels &&
labels.map(label => ( task.labels.map(label => (
<ListCardLabel color={label.labelColor.colorHex} key={label.id}> <ListCardLabel color={label.projectLabel.labelColor.colorHex} key={label.id}>
{label.name} {label.projectLabel.name}
</ListCardLabel> </ListCardLabel>
))} ))}
</ListCardLabels> </ListCardLabels>
@ -89,14 +73,13 @@ const QuickCardEditor = ({
/> />
</EditorDetails> </EditorDetails>
</Editor> </Editor>
<SaveButton onClick={e => onEditCard(taskGroupID, taskID, currentCardTitle)}>Save</SaveButton> <SaveButton onClick={e => onEditCard(task.taskGroup.id, task.id, currentCardTitle)}>Save</SaveButton>
<EditorButtons> <EditorButtons>
<EditorButton <EditorButton
ref={$labelsRef} ref={$labelsRef}
onClick={e => { onClick={e => {
e.stopPropagation(); e.stopPropagation();
const pos = $labelsRef.current.getBoundingClientRect(); onOpenLabelsPopup($labelsRef, task);
onOpenPopup(1, pos.top + $labelsRef.current.clientHeight + 4, pos.left);
}} }}
> >
Edit Labels Edit Labels
@ -104,7 +87,7 @@ const QuickCardEditor = ({
<EditorButton <EditorButton
onClick={e => { onClick={e => {
e.stopPropagation(); e.stopPropagation();
onArchiveCard(taskGroupID, taskID); onArchiveCard(task.taskGroup.id, task.id);
onCloseEditor(); onCloseEditor();
}} }}
> >