types#Label TypeScript Examples
The following examples show how to use
types#Label.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: LabelSlice.tsx From knboard with MIT License | 6 votes |
patchLabel = createAsyncThunk<
Label,
{ id: Id; fields: Partial<Label> }
>(
"label/patchLabelStatus",
async ({ id, fields }, { dispatch, rejectWithValue }) => {
try {
const response = await api.patch(`${API_LABELS}${id}/`, fields);
dispatch(createInfoToast("Label updated"));
return response.data;
} catch (err) {
const error: AxiosError = err;
if (!error.response) {
throw err;
}
dispatch(createErrorToast(error.response.data));
return rejectWithValue(error.response.data);
}
}
)
Example #2
Source File: TaskLabels.tsx From knboard with MIT License | 6 votes |
TaskLabels = ({ task }: Props) => {
const labelsById = useSelector(selectLabelEntities);
const labels = task.labels.map((labelId) => labelsById[labelId]) as Label[];
return (
<Container>
{labels.map((label) => (
<LabelChip key={label.id} label={label} onCard />
))}
</Container>
);
}
Example #3
Source File: LabelDialog.test.tsx From knboard with MIT License | 5 votes |
docLabel: Label = {
id: 1,
name: "Documentation",
color: "#111fff",
board: 1,
}
Example #4
Source File: LabelSlice.tsx From knboard with MIT License | 5 votes |
createLabel = createAsyncThunk<Label, Omit<Label, "id">>(
"label/createLabelStatus",
async (label, { dispatch }) => {
const response = await api.post(`${API_LABELS}`, label);
dispatch(createInfoToast("Label created"));
return response.data;
}
)
Example #5
Source File: LabelSlice.tsx From knboard with MIT License | 5 votes |
labelAdapter = createEntityAdapter<Label>({
sortComparer: (a, b) => a.name.localeCompare(b.name),
})
Example #6
Source File: CreateTaskDialog.tsx From knboard with MIT License | 4 votes |
CreateTaskDialog = () => {
const theme = useTheme();
const dispatch = useDispatch();
const labelsOptions = useSelector(selectAllLabels);
const members = useSelector(selectAllMembers);
const open = useSelector((state: RootState) => state.task.createDialogOpen);
const columnId = useSelector(
(state: RootState) => state.task.createDialogColumn
);
const createLoading = useSelector(
(state: RootState) => state.task.createLoading
);
const [titleTouched, setTitleTouched] = useState<boolean>(false);
const [title, setTitle] = useState<string>("");
const [description, setDescription] = useState<string>("");
const [assignees, setAssignees] = useState<BoardMember[]>([]);
const [priority, setPriority] = useState<Priority | null>({
value: "M",
label: "Medium",
});
const [labels, setLabels] = useState<Label[]>([]);
const xsDown = useMediaQuery(theme.breakpoints.down("xs"));
const handleEditorChange = ({ text }: any) => {
setDescription(text);
};
const setInitialValues = () => {
if (columnId) {
setTitleTouched(false);
setTitle("");
setDescription("");
setAssignees([]);
setPriority(PRIORITY_2);
setLabels([]);
}
};
useEffect(() => {
setInitialValues();
}, [open]);
const handleClose = () => {
if (window.confirm("Are you sure? Any progress made will be lost.")) {
dispatch(setCreateDialogOpen(false));
}
};
const handleCreate = async () => {
setTitleTouched(true);
if (columnId && priority) {
const newTask = {
title,
description,
column: columnId,
labels: labels.map((l) => l.id),
assignees: assignees.map((a) => a.id),
priority: priority.value,
};
dispatch(createTask(newTask));
}
};
const handleKeyDown = (e: React.KeyboardEvent) => {
if (e.keyCode == Key.Enter && e.metaKey) {
handleCreate();
}
};
return (
<Dialog
open={open}
onClose={handleClose}
maxWidth="sm"
fullWidth
keepMounted={false}
fullScreen={xsDown}
>
<Content onKeyDown={handleKeyDown}>
<DialogTitle>New issue</DialogTitle>
<TextField
autoFocus
id="create-task-title"
data-testid="create-task-title"
label="Title"
value={title}
onChange={(e) => setTitle(e.target.value)}
variant="outlined"
fullWidth
size="small"
onBlur={() => setTitleTouched(true)}
error={titleTouched && !title}
/>
<EditorWrapper>
<MdEditor
plugins={MD_EDITOR_PLUGINS}
config={MD_EDITOR_CONFIG}
value={description}
renderHTML={(text) => mdParser.render(text)}
onChange={handleEditorChange}
placeholder="Describe the issue..."
/>
</EditorWrapper>
<Autocomplete
multiple
filterSelectedOptions
disableClearable
openOnFocus
id="create-assignee-select"
size="small"
options={members}
getOptionLabel={(option) => option.username}
value={assignees}
onChange={(_event, value) => setAssignees(value)}
renderOption={(option) => <AvatarOption option={option} />}
renderInput={(params) => (
<TextField {...params} label="Assignees" variant="outlined" />
)}
renderTags={(value, getTagProps) =>
value.map((option, index) => (
<AvatarTag
key={option.id}
option={option}
{...getTagProps({ index })}
/>
))
}
css={css`
width: 100%;
margin-top: 1rem;
`}
/>
<Autocomplete
id="create-priority-select"
size="small"
autoHighlight
options={PRIORITY_OPTIONS}
getOptionLabel={(option) => option.label}
value={priority}
onChange={(_: any, value: Priority | null) => setPriority(value)}
renderOption={(option) => <PriorityOption option={option} />}
renderInput={(params) => (
<TextField {...params} label="Priority" variant="outlined" />
)}
openOnFocus
disableClearable
css={css`
width: 100%;
margin-top: 1rem;
`}
/>
<Autocomplete
multiple
id="create-labels-select"
size="small"
filterSelectedOptions
autoHighlight
openOnFocus
options={labelsOptions}
getOptionLabel={(option) => option.name}
value={labels}
onChange={(_, newLabels) => setLabels(newLabels)}
renderInput={(params) => (
<TextField {...params} label="Labels" variant="outlined" />
)}
renderTags={(value, getTagProps) =>
value.map((option, index) => (
<LabelChip
key={option.id}
label={option}
size="small"
{...getTagProps({ index })}
/>
))
}
renderOption={(option) => <LabelChip label={option} size="small" />}
css={css`
margin-top: 1rem;
width: 100%;
`}
/>
</Content>
<Footer theme={theme}>
<Button
startIcon={
createLoading ? (
<CircularProgress color="inherit" size={16} />
) : (
<FontAwesomeIcon icon={faRocket} />
)
}
variant="contained"
color="primary"
size="small"
onClick={handleCreate}
disabled={createLoading}
data-testid="task-create"
css={css`
${theme.breakpoints.down("xs")} {
flex-grow: 1;
}
`}
>
Create issue ({getMetaKey()}+⏎)
</Button>
<Button
css={css`
margin-left: 1rem;
`}
onClick={handleClose}
>
Cancel (Esc)
</Button>
</Footer>
</Dialog>
);
}
Example #7
Source File: EditTaskDialog.tsx From knboard with MIT License | 4 votes |
EditTaskDialog = () => {
const theme = useTheme();
const dispatch = useDispatch();
const columns = useSelector(selectAllColumns);
const labels = useSelector(selectAllLabels);
const labelsById = useSelector(selectLabelEntities);
const columnsById = useSelector(selectColumnsEntities);
const tasksByColumn = useSelector((state: RootState) => state.task.byColumn);
const taskId = useSelector((state: RootState) => state.task.editDialogOpen);
const tasksById = useSelector((state: RootState) => state.task.byId);
const [title, setTitle] = useState("");
const [description, setDescription] = useState("");
const [editingDescription, setEditingDescription] = useState(false);
const titleTextAreaRef = useRef<HTMLTextAreaElement>(null);
const wrapperRef = useRef<HTMLDivElement>(null);
const editorRef = useRef<MdEditor>(null);
const cancelRef = useRef<HTMLButtonElement>(null);
const xsDown = useMediaQuery(theme.breakpoints.down("xs"));
const open = taskId !== null;
useEffect(() => {
if (taskId && tasksById[taskId]) {
setDescription(tasksById[taskId].description);
setTitle(tasksById[taskId].title);
}
}, [open, taskId]);
const handleSaveTitle = () => {
if (taskId) {
dispatch(patchTask({ id: taskId, fields: { title } }));
}
};
const handleSaveDescription = () => {
if (taskId) {
dispatch(patchTask({ id: taskId, fields: { description } }));
setEditingDescription(false);
}
};
const handleCancelDescription = () => {
if (taskId && tasksById[taskId]) {
setDescription(tasksById[taskId].description);
setEditingDescription(false);
}
};
useEffect(() => {
const handleClickOutside = (event: any) => {
if (
wrapperRef.current &&
!wrapperRef.current.contains(event.target) &&
cancelRef.current &&
!cancelRef.current?.contains(event.target)
) {
handleSaveDescription();
}
};
document.addEventListener("mousedown", handleClickOutside);
return () => {
document.removeEventListener("mousedown", handleClickOutside);
};
}, [wrapperRef, taskId, description]);
useEffect(() => {
if (editingDescription && editorRef && editorRef.current) {
editorRef.current.setSelection({
start: 0,
end: description.length,
});
}
}, [editingDescription]);
const findTaskColumnId = () => {
for (const columnId in tasksByColumn) {
for (const id of tasksByColumn[columnId]) {
if (id === taskId) {
return columnId;
}
}
}
return null;
};
const columnId = findTaskColumnId();
if (!taskId || !tasksById[taskId] || !columnId) {
return null;
}
const task = tasksById[taskId];
const column = columnsById[columnId];
const handleEditorKeyDown = (e: React.KeyboardEvent) => {
if (e.keyCode == Key.Enter && e.metaKey) {
handleSaveDescription();
}
if (e.keyCode === Key.Escape) {
// Prevent propagation from reaching the Dialog
e.stopPropagation();
handleCancelDescription();
}
};
const handleTitleKeyDown = (e: React.KeyboardEvent) => {
if (e.keyCode === Key.Enter) {
e.preventDefault();
titleTextAreaRef?.current?.blur();
}
if (e.keyCode === Key.Escape) {
// Prevent propagation from reaching the Dialog
e.stopPropagation();
}
};
const handleClose = () => {
dispatch(setEditDialogOpen(null));
setEditingDescription(false);
};
const handleTitleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
setTitle(e.target.value);
};
const handleColumnChange = (_: any, value: IColumn | null) => {
if (!column || !value || column.id === value.id) {
return;
}
const current: Id[] = [...tasksByColumn[column.id]];
const next: Id[] = [...tasksByColumn[value.id]];
const currentId = current.indexOf(task.id);
const newPosition = 0;
// remove from original
current.splice(currentId, 1);
// insert into next
next.splice(newPosition, 0, task.id);
const updatedTasksByColumn: TasksByColumn = {
...tasksByColumn,
[column.id]: current,
[value.id]: next,
};
dispatch(updateTasksByColumn(updatedTasksByColumn));
handleClose();
};
const handlePriorityChange = (_: any, priority: Priority | null) => {
if (priority) {
dispatch(patchTask({ id: taskId, fields: { priority: priority.value } }));
}
};
const handleNotImplemented = () => {
dispatch(createInfoToast("Not implemented yet ?"));
};
const handleDelete = () => {
if (window.confirm("Are you sure? Deleting a task cannot be undone.")) {
dispatch(deleteTask(task.id));
handleClose();
}
};
const handleDescriptionClick = () => {
setEditingDescription(true);
};
const handleEditorChange = ({ text }: any) => {
setDescription(text);
};
const handleLabelsChange = (newLabels: Label[]) => {
dispatch(
patchTask({
id: taskId,
fields: { labels: newLabels.map((label) => label.id) },
})
);
};
const handleKeyDown = (e: React.KeyboardEvent) => {
// don't listen for input when inputs are focused
if (
document.activeElement instanceof HTMLInputElement ||
document.activeElement instanceof HTMLTextAreaElement
) {
return;
}
if (e.key === "Backspace" && e.metaKey) {
handleDelete();
}
if (e.key === "Escape" && e.metaKey) {
handleClose();
}
if (e.key === "l" && e.metaKey) {
e.preventDefault();
handleNotImplemented();
}
};
return (
<Dialog
open={open}
onClose={handleClose}
onKeyDown={handleKeyDown}
fullWidth
keepMounted={false}
fullScreen={xsDown}
css={css`
.MuiDialog-paper {
max-width: 920px;
}
`}
>
<Content theme={theme}>
<Close onClose={handleClose} />
<Main>
<Header>id: {task.id}</Header>
<Title>
<FontAwesomeIcon icon={faArrowUp} />
<TextareaAutosize
ref={titleTextAreaRef}
value={title}
onChange={handleTitleChange}
onBlur={handleSaveTitle}
onKeyDown={handleTitleKeyDown}
data-testid="task-title"
/>
</Title>
<DescriptionHeader>
<FontAwesomeIcon icon={faAlignLeft} />
<h3>Description</h3>
</DescriptionHeader>
<Description
key={`${taskId}${editingDescription}`}
data-testid="task-description"
>
<EditorWrapper
onDoubleClick={
editingDescription ? undefined : handleDescriptionClick
}
editing={editingDescription}
ref={wrapperRef}
theme={theme}
onKeyDown={handleEditorKeyDown}
>
<MdEditor
ref={editorRef}
plugins={MD_EDITOR_PLUGINS}
config={
editingDescription ? MD_EDITING_CONFIG : MD_READ_ONLY_CONFIG
}
value={
editingDescription
? description
: description || DESCRIPTION_PLACEHOLDER
}
renderHTML={(text) => mdParser.render(text)}
onChange={handleEditorChange}
placeholder={DESCRIPTION_PLACEHOLDER}
/>
</EditorWrapper>
{editingDescription && (
<DescriptionActions>
<Button
variant="contained"
data-testid="save-description"
onClick={handleSaveDescription}
color="primary"
size="small"
>
Save ({getMetaKey()}+⏎)
</Button>
<Button
variant="outlined"
data-testid="cancel-description"
onClick={handleCancelDescription}
ref={cancelRef}
size="small"
css={css`
margin-left: 0.5rem;
`}
>
Cancel (Esc)
</Button>
</DescriptionActions>
)}
</Description>
<CommentSection taskId={task.id} />
</Main>
<Side theme={theme}>
<TaskAssignees task={task} />
<Autocomplete
id="column-select"
size="small"
options={columns}
getOptionLabel={(option) => option.title}
renderInput={(params) => (
<TextField {...params} label="Column" variant="outlined" />
)}
value={column}
onChange={handleColumnChange}
disableClearable
openOnFocus
data-testid="edit-column"
css={css`
width: 100%;
`}
/>
<Autocomplete
id="priority-select"
size="small"
blurOnSelect
autoHighlight
options={PRIORITY_OPTIONS}
getOptionLabel={(option) => option.label}
value={PRIORITY_MAP[task.priority]}
onChange={handlePriorityChange}
renderInput={(params) => (
<TextField {...params} label="Priority" variant="outlined" />
)}
renderOption={(option) => <PriorityOption option={option} />}
openOnFocus
disableClearable
data-testid="edit-priority"
css={css`
width: 100%;
margin-top: 1rem;
`}
/>
<Autocomplete
multiple
id="labels-select"
data-testid="edit-labels"
size="small"
filterSelectedOptions
autoHighlight
openOnFocus
blurOnSelect
disableClearable
options={labels}
getOptionLabel={(option) => option.name}
value={
tasksById[taskId].labels.map(
(labelId) => labelsById[labelId]
) as Label[]
}
onChange={(_, newLabels) => handleLabelsChange(newLabels)}
renderInput={(params) => (
<TextField {...params} label="Labels" variant="outlined" />
)}
renderTags={(value, getTagProps) =>
value.map((option, index) => (
<LabelChip
key={option.id}
label={option}
size="small"
{...getTagProps({ index })}
/>
))
}
renderOption={(option) => <LabelChip label={option} size="small" />}
css={css`
width: 100%;
margin-top: 1rem;
margin-bottom: 2rem;
`}
/>
<ButtonsContainer>
<Button
startIcon={<FontAwesomeIcon fixedWidth icon={faLock} />}
onClick={handleNotImplemented}
size="small"
css={css`
font-size: 12px;
font-weight: bold;
color: ${TASK_G};
`}
>
Lock task ({getMetaKey()}+L)
</Button>
<Button
startIcon={<FontAwesomeIcon fixedWidth icon={faTrash} />}
onClick={handleDelete}
data-testid="delete-task"
size="small"
css={css`
font-size: 12px;
font-weight: bold;
color: ${TASK_G};
margin-bottom: 2rem;
`}
>
Delete task ({getMetaKey()}+⌫)
</Button>
</ButtonsContainer>
<Text>
Updated {formatDistanceToNow(new Date(task.modified))} ago
</Text>
<Text
css={css`
margin-bottom: 1rem;
`}
>
Created {formatDistanceToNow(new Date(task.created))} ago
</Text>
</Side>
</Content>
</Dialog>
);
}