feature: add ability to delete & update project labels

This commit is contained in:
Jordan Knott
2020-05-27 20:12:50 -05:00
parent cbcd8c5f82
commit 539259effd
32 changed files with 1139 additions and 143 deletions

View File

@ -1,4 +1,4 @@
import React, { useState } from 'react';
import React, { useState, useEffect, useRef } from 'react';
import LabelColors from 'shared/constants/labelColors';
import { Checkmark } from 'shared/icons';
import { SaveButton, DeleteButton, LabelBox, EditLabelForm, FieldLabel, FieldName } from './Styles';
@ -7,16 +7,25 @@ type Props = {
labelColors: Array<LabelColor>;
label: Label | null;
onLabelEdit: (labelId: string | null, labelName: string, labelColor: LabelColor) => void;
onLabelDelete?: (labelId: string) => void;
};
const LabelManager = ({ labelColors, label, onLabelEdit }: Props) => {
console.log(label);
const LabelManager = ({ labelColors, label, onLabelEdit, onLabelDelete }: Props) => {
const $fieldName = useRef<HTMLInputElement>(null);
const [currentLabel, setCurrentLabel] = useState(label ? label.name : '');
const [currentColor, setCurrentColor] = useState<LabelColor | null>(label ? label.labelColor : null);
useEffect(() => {
if ($fieldName.current) {
$fieldName.current.focus();
}
}, []);
return (
<EditLabelForm>
<FieldLabel>Name</FieldLabel>
<FieldName
ref={$fieldName}
id="labelName"
type="text"
name="name"
@ -29,6 +38,7 @@ const LabelManager = ({ labelColors, label, onLabelEdit }: Props) => {
<div>
{labelColors.map((labelColor: LabelColor) => (
<LabelBox
key={labelColor.id}
color={labelColor.colorHex}
onClick={() => {
setCurrentColor(labelColor);
@ -40,6 +50,8 @@ const LabelManager = ({ labelColors, label, onLabelEdit }: Props) => {
</div>
<div>
<SaveButton
value="Save"
type="submit"
onClick={e => {
e.preventDefault();
console.log(currentColor);
@ -47,10 +59,17 @@ const LabelManager = ({ labelColors, label, onLabelEdit }: Props) => {
onLabelEdit(label ? label.labelId : null, currentLabel, currentColor);
}
}}
type="submit"
value="Save"
/>
<DeleteButton type="submit" value="Delete" />
{label && onLabelDelete && (
<DeleteButton
value="Delete"
type="submit"
onClick={e => {
e.preventDefault();
onLabelDelete(label.labelId);
}}
/>
)}
</div>
</EditLabelForm>
);

View File

@ -1,4 +1,4 @@
import React, { useState } from 'react';
import React, { useState, useEffect, useRef } from 'react';
import { Pencil, Checkmark } from 'shared/icons';
import {
@ -20,12 +20,19 @@ type Props = {
onLabelCreate: () => void;
};
const LabelManager: React.FC<Props> = ({ labels, onLabelToggle, onLabelEdit, onLabelCreate }) => {
const $fieldName = useRef<HTMLInputElement>(null);
const [currentLabel, setCurrentLabel] = useState('');
const [currentSearch, setCurrentSearch] = useState('');
useEffect(() => {
if ($fieldName.current) {
$fieldName.current.focus();
}
}, []);
return (
<>
<LabelSearch
type="text"
ref={$fieldName}
placeholder="search labels..."
onChange={e => {
setCurrentSearch(e.currentTarget.value);

View File

@ -248,36 +248,47 @@ export const LabelBox = styled.span<{ color: string }>`
`;
export const SaveButton = styled.input`
cursor: pointer;
background-color: #5aac44;
background: rgb(115, 103, 240);
box-shadow: none;
border: none;
color: #fff;
padding-left: 24px;
padding-right: 24px;
ursor: pointer;
cursor: pointer;
display: inline-block;
font-weight: 400;
line-height: 20px;
margin: 8px 4px 0 0;
margin-right: 4px;
padding: 6px 12px;
text-align: center;
border-radius: 3px;
`;
export const DeleteButton = styled.input`
background-color: #cf513d;
box-shadow: none;
border: none;
color: #fff;
cursor: pointer;
type="submit"font-weight: 400;
line-height: 20px;
margin: 8px 4px 0 0;
padding: 6px 12px;
text-align: center;
border-radius: 3px;
float: right;
outline: none;
border: none;
line-height: 20px;
padding: 6px 12px;
background-color: transparent;
text-align: center;
color: #c2c6dc;
font-weight: 400;
line-height: 20px;
cursor: pointer;
margin: 0 0 0 8px;
border-radius: 3px;
border-width: 1px;
border-style: solid;
border-color: transparent;
border-image: initial;
border-color: #414561;
&:hover {
color: #fff;
background: rgb(115, 103, 240);
border-color: transparent;
}
`;
export const CreateLabelButton = styled.button`

View File

@ -18,6 +18,7 @@ type PopupContextState = {
show: (target: RefObject<HTMLElement>, content: JSX.Element) => void;
setTab: (newTab: number) => void;
getCurrentTab: () => number;
hide: () => void;
};
type PopupProps = {
@ -46,11 +47,12 @@ const PopupContext = createContext<PopupContextState>({
show: () => {},
setTab: () => {},
getCurrentTab: () => 0,
hide: () => {},
});
export const usePopup = () => {
const ctx = useContext<PopupContextState>(PopupContext);
return { showPopup: ctx.show, setTab: ctx.setTab, getCurrentTab: ctx.getCurrentTab };
return { showPopup: ctx.show, setTab: ctx.setTab, getCurrentTab: ctx.getCurrentTab, hidePopup: ctx.hide };
};
type PopupState = {
@ -80,11 +82,9 @@ const defaultState = {
export const PopupProvider: React.FC = ({ children }) => {
const [currentState, setState] = useState<PopupState>(defaultState);
const show = (target: RefObject<HTMLElement>, content: JSX.Element) => {
console.log(target);
if (target && target.current) {
const bounds = target.current.getBoundingClientRect();
if (bounds.left + 304 + 30 > window.innerWidth) {
console.log('open!');
setState({
isOpen: true,
left: bounds.left + bounds.width,
@ -95,7 +95,6 @@ export const PopupProvider: React.FC = ({ children }) => {
content,
});
} else {
console.log('open NOT INVERT!');
setState({
isOpen: true,
left: bounds.left,
@ -108,6 +107,17 @@ export const PopupProvider: React.FC = ({ children }) => {
}
}
};
const hide = () => {
setState({
isOpen: false,
left: 0,
top: 0,
invert: true,
currentTab: 0,
previousTab: 0,
content: null,
});
};
const portalTarget = canUseDOM ? document.body : null; // appease flow
const setTab = (newTab: number) => {
@ -125,7 +135,7 @@ export const PopupProvider: React.FC = ({ children }) => {
};
return (
<Provider value={{ show, setTab, getCurrentTab }}>
<Provider value={{ hide, show, setTab, getCurrentTab }}>
{portalTarget &&
currentState.isOpen &&
createPortal(