feature: add quick card labels popup
This commit is contained in:
parent
2a59cddadb
commit
f1f69440c3
@ -67,7 +67,8 @@ interface QuickCardEditorState {
|
||||
isOpen: boolean;
|
||||
left: number;
|
||||
top: number;
|
||||
task?: Task;
|
||||
taskID: string | null;
|
||||
taskGroupID: string | null;
|
||||
}
|
||||
|
||||
const TitleWrapper = styled.div`
|
||||
@ -200,7 +201,13 @@ interface ProjectParams {
|
||||
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`
|
||||
display: flex;
|
||||
@ -417,13 +424,22 @@ const Project = () => {
|
||||
top: e.top,
|
||||
left: e.left,
|
||||
isOpen: true,
|
||||
task: currentTask,
|
||||
taskID: currentTask.id,
|
||||
taskGroupID: currentTask.taskGroup.id,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
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 (
|
||||
<>
|
||||
<GlobalTopNavbar
|
||||
@ -535,17 +551,28 @@ const Project = () => {
|
||||
);
|
||||
}}
|
||||
/>
|
||||
{quickCardEditor.isOpen && (
|
||||
{quickCardEditor.isOpen && currentQuickTask && (
|
||||
<QuickCardEditor
|
||||
isOpen
|
||||
taskID={quickCardEditor.task ? quickCardEditor.task.id : ''}
|
||||
taskGroupID={quickCardEditor.task ? quickCardEditor.task.taskGroup.id : ''}
|
||||
cardTitle={quickCardEditor.task ? quickCardEditor.task.name : ''}
|
||||
task={currentQuickTask}
|
||||
onCloseEditor={() => setQuickCardEditor(initialQuickCardEditorState)}
|
||||
onEditCard={(_listId: string, cardId: string, cardName: string) => {
|
||||
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) =>
|
||||
deleteTask({
|
||||
variables: { taskID: cardId },
|
||||
@ -564,7 +591,6 @@ const Project = () => {
|
||||
},
|
||||
})
|
||||
}
|
||||
labels={[]}
|
||||
top={quickCardEditor.top}
|
||||
left={quickCardEditor.left}
|
||||
/>
|
||||
|
@ -67,8 +67,8 @@ type Props = {
|
||||
onClick: (e: React.MouseEvent<HTMLDivElement>) => void;
|
||||
dueDate?: DueDate;
|
||||
checklists?: Checklist;
|
||||
watched?: boolean;
|
||||
labels?: Array<ProjectLabel>;
|
||||
watched?: boolean;
|
||||
wrapperProps?: any;
|
||||
members?: Array<TaskUser> | null;
|
||||
onCardMemberClick?: OnCardMemberClick;
|
||||
|
@ -17,16 +17,20 @@ export default {
|
||||
},
|
||||
};
|
||||
|
||||
const labelData: Array<ProjectLabel> = [
|
||||
const labelData: Array<TaskLabel> = [
|
||||
{
|
||||
id: 'development',
|
||||
name: 'Development',
|
||||
createdDate: 'date',
|
||||
labelColor: {
|
||||
id: 'label-color-blue',
|
||||
colorHex: LabelColors.BLUE,
|
||||
name: 'blue',
|
||||
position: 1,
|
||||
assignedDate: new Date().toString(),
|
||||
projectLabel: {
|
||||
id: 'development',
|
||||
name: 'Development',
|
||||
createdDate: 'date',
|
||||
labelColor: {
|
||||
id: 'label-color-blue',
|
||||
colorHex: LabelColors.BLUE,
|
||||
name: 'blue',
|
||||
position: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
];
|
||||
@ -40,15 +44,19 @@ export const Default = () => {
|
||||
<>
|
||||
{isEditorOpen && (
|
||||
<QuickCardEditor
|
||||
isOpen={isEditorOpen}
|
||||
taskGroupID="1"
|
||||
taskID="1"
|
||||
cardTitle="Hello, world"
|
||||
task={{
|
||||
id: 'task',
|
||||
name: 'General',
|
||||
taskGroup: {
|
||||
id: '1',
|
||||
},
|
||||
position: 1,
|
||||
labels: labelData,
|
||||
}}
|
||||
onCloseEditor={() => setEditorOpen(false)}
|
||||
onEditCard={action('edit card')}
|
||||
onOpenPopup={action('open popup')}
|
||||
onOpenLabelsPopup={action('open popup')}
|
||||
onArchiveCard={action('archive card')}
|
||||
labels={labelData}
|
||||
top={top}
|
||||
left={left}
|
||||
/>
|
||||
@ -75,7 +83,7 @@ export const Default = () => {
|
||||
setEditorOpen(true);
|
||||
}}
|
||||
watched
|
||||
labels={labelData}
|
||||
labels={labelData.map(l => l.projectLabel)}
|
||||
checklists={{ complete: 1, total: 4 }}
|
||||
dueDate={{ isPastDue: false, formattedDate: 'Oct 26, 2020' }}
|
||||
/>
|
||||
|
@ -1,5 +1,6 @@
|
||||
import styled, { keyframes } from 'styled-components';
|
||||
import TextareaAutosize from 'react-autosize-textarea';
|
||||
import { mixin } from 'shared/utils/styles';
|
||||
|
||||
export const Wrapper = styled.div<{ open: boolean }>`
|
||||
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`
|
||||
background-color: #fff;
|
||||
background-color: ${props => mixin.lighten('#262c49', 0.05)};
|
||||
border-radius: 3px;
|
||||
box-shadow: 0 1px 0 rgba(9, 30, 66, 0.25);
|
||||
color: #c2c6dc;
|
||||
padding: 6px 8px 2px;
|
||||
cursor: default;
|
||||
display: block;
|
||||
@ -59,6 +61,7 @@ export const EditorTextarea = styled(TextareaAutosize)`
|
||||
padding: 0;
|
||||
font-size: 16px;
|
||||
line-height: 20px;
|
||||
color: #fff;
|
||||
&:focus {
|
||||
border: none;
|
||||
outline: none;
|
||||
@ -67,7 +70,7 @@ export const EditorTextarea = styled(TextareaAutosize)`
|
||||
|
||||
export const SaveButton = styled.button`
|
||||
cursor: pointer;
|
||||
background-color: #5aac44;
|
||||
background: rgb(115, 103, 240);
|
||||
box-shadow: none;
|
||||
border: none;
|
||||
color: #fff;
|
||||
@ -79,10 +82,12 @@ export const SaveButton = styled.button`
|
||||
text-align: center;
|
||||
border-radius: 3px;
|
||||
`;
|
||||
|
||||
export const FadeInAnimation = keyframes`
|
||||
from { opacity: 0; transform: translateX(-20px); }
|
||||
to { opacity: 1; transform: translateX(0); }
|
||||
`;
|
||||
|
||||
export const EditorButtons = styled.div`
|
||||
left: 100%;
|
||||
position: absolute;
|
||||
|
@ -6,8 +6,8 @@ import {
|
||||
Editor,
|
||||
EditorDetails,
|
||||
EditorTextarea,
|
||||
SaveButton,
|
||||
EditorButtons,
|
||||
SaveButton,
|
||||
EditorButton,
|
||||
CloseButton,
|
||||
ListCardLabels,
|
||||
@ -15,33 +15,17 @@ import {
|
||||
} from './Styles';
|
||||
|
||||
type Props = {
|
||||
taskID: string;
|
||||
taskGroupID: string;
|
||||
cardTitle: string;
|
||||
task: Task;
|
||||
onCloseEditor: () => 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;
|
||||
labels?: Array<ProjectLabel>;
|
||||
isOpen: boolean;
|
||||
top: number;
|
||||
left: number;
|
||||
};
|
||||
|
||||
const QuickCardEditor = ({
|
||||
taskGroupID,
|
||||
taskID,
|
||||
cardTitle,
|
||||
onCloseEditor,
|
||||
onOpenPopup,
|
||||
onArchiveCard,
|
||||
onEditCard,
|
||||
labels,
|
||||
isOpen,
|
||||
top,
|
||||
left,
|
||||
}: Props) => {
|
||||
const [currentCardTitle, setCardTitle] = useState(cardTitle);
|
||||
const QuickCardEditor = ({ task, onCloseEditor, onOpenLabelsPopup, onArchiveCard, onEditCard, top, left }: Props) => {
|
||||
const [currentCardTitle, setCardTitle] = useState(task.name);
|
||||
const $editorRef: any = useRef();
|
||||
const $labelsRef: any = useRef();
|
||||
useEffect(() => {
|
||||
@ -57,23 +41,23 @@ const QuickCardEditor = ({
|
||||
const handleKeyDown = (e: any) => {
|
||||
if (e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
onEditCard(taskGroupID, taskID, currentCardTitle);
|
||||
onEditCard(task.taskGroup.id, task.id, currentCardTitle);
|
||||
onCloseEditor();
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Wrapper onClick={handleCloseEditor} open={isOpen}>
|
||||
<Wrapper onClick={handleCloseEditor} open>
|
||||
<CloseButton onClick={handleCloseEditor}>
|
||||
<Cross size={16} color="#000" />
|
||||
</CloseButton>
|
||||
<Container left={left} top={top}>
|
||||
<Editor>
|
||||
<ListCardLabels>
|
||||
{labels &&
|
||||
labels.map(label => (
|
||||
<ListCardLabel color={label.labelColor.colorHex} key={label.id}>
|
||||
{label.name}
|
||||
{task.labels &&
|
||||
task.labels.map(label => (
|
||||
<ListCardLabel color={label.projectLabel.labelColor.colorHex} key={label.id}>
|
||||
{label.projectLabel.name}
|
||||
</ListCardLabel>
|
||||
))}
|
||||
</ListCardLabels>
|
||||
@ -89,14 +73,13 @@ const QuickCardEditor = ({
|
||||
/>
|
||||
</EditorDetails>
|
||||
</Editor>
|
||||
<SaveButton onClick={e => onEditCard(taskGroupID, taskID, currentCardTitle)}>Save</SaveButton>
|
||||
<SaveButton onClick={e => onEditCard(task.taskGroup.id, task.id, currentCardTitle)}>Save</SaveButton>
|
||||
<EditorButtons>
|
||||
<EditorButton
|
||||
ref={$labelsRef}
|
||||
onClick={e => {
|
||||
e.stopPropagation();
|
||||
const pos = $labelsRef.current.getBoundingClientRect();
|
||||
onOpenPopup(1, pos.top + $labelsRef.current.clientHeight + 4, pos.left);
|
||||
onOpenLabelsPopup($labelsRef, task);
|
||||
}}
|
||||
>
|
||||
Edit Labels
|
||||
@ -104,7 +87,7 @@ const QuickCardEditor = ({
|
||||
<EditorButton
|
||||
onClick={e => {
|
||||
e.stopPropagation();
|
||||
onArchiveCard(taskGroupID, taskID);
|
||||
onArchiveCard(task.taskGroup.id, task.id);
|
||||
onCloseEditor();
|
||||
}}
|
||||
>
|
||||
|
Loading…
Reference in New Issue
Block a user