Skip to content

Commit 309cdf3

Browse files
committed
chore: update latest design in tasks
1 parent 7b4cc5b commit 309cdf3

File tree

3 files changed

+152
-64
lines changed

3 files changed

+152
-64
lines changed

examples/kendo-react-freemium/src/pages/Task.tsx

Lines changed: 109 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
import { useParams } from "react-router";
22
import { useNavigate } from "react-router-dom";
3-
import { projectsData, tasksData } from "./data";
3+
import { priorities, projectManagers, projectsData, tasksData } from "./data";
44
import { Button } from "@progress/kendo-react-buttons";
5-
import { Breadcrumb, BreadcrumbLinkMouseEvent, ExpansionPanel, ExpansionPanelContent } from "@progress/kendo-react-layout";
5+
import { Avatar, Breadcrumb, BreadcrumbLinkMouseEvent, ExpansionPanel, ExpansionPanelContent } from "@progress/kendo-react-layout";
66
import { homeIcon, folderIcon, trashIcon, checkIcon } from "@progress/kendo-svg-icons";
77
import { SvgIcon } from "@progress/kendo-react-common";
88
import { Reveal } from '@progress/kendo-react-animation';
9-
import React from "react";
9+
import React, { ReactElement } from "react";
1010
import { TextArea } from "@progress/kendo-react-inputs";
11-
import { DropDownList, MultiSelect } from "@progress/kendo-react-dropdowns";
11+
import { DropDownList, ListItemProps, MultiSelect, TagData } from "@progress/kendo-react-dropdowns";
1212
import { DateInput } from "@progress/kendo-react-dateinputs";
1313
import { FloatingLabel } from "@progress/kendo-react-labels";
14+
import { Badge } from "@progress/kendo-react-indicators";
1415

1516
interface DataModel {
1617
id: string;
@@ -24,12 +25,16 @@ export default function Task() {
2425
const [projExpanded, setProjExpanded] = React.useState(true);
2526
const [dateExpanded, setDateExpanded] = React.useState(true);
2627
const [assigneeExpanded, setAssigneeExpanded] = React.useState(true);
28+
const [priorityExpanded, setPriorityExpanded] = React.useState(true);
2729
const [statusExpanded, setStatusExpanded] = React.useState(true);
2830
const [tagsExpanded, setTagsExpanded] = React.useState(true);
29-
const [project, setProject] = React.useState('Online Learning Management System (LMS)');
30-
const [assignee, setAssignee] = React.useState(['Alden_Upton']);
31-
const [status, setStatus] = React.useState(['🚧 On Hold']);
32-
const [tag, setTag] = React.useState(['Compliance', 'Maintenance']);
31+
const projectId = tasksData.filter(task => task.taskId === params.taskId)[0].projectId;
32+
const [project, setProject] = React.useState(projectsData.filter(proj => proj.ProjectID === projectId)[0].ProjectName);
33+
const [assignee, setAssignee] = React.useState([tasksData.filter(task => task.taskId === params.taskId)[0].assignedTo] as string[]);
34+
const [dueDate, setDueDate] = React.useState(new Date(tasksData.filter(task => task.taskId === params.taskId)[0].dueDate));
35+
const [priority, setPriority] = React.useState(tasksData.filter(task => task.taskId === params.taskId)[0].priority);
36+
const [status, setStatus] = React.useState(tasksData.filter(task => task.taskId === params.taskId)[0].status);
37+
const [tag, setTag] = React.useState(tasksData.filter(task => task.taskId === params.taskId)[0].tags as string[]);
3338
const projects = projectsData.map(proj => { return proj.ProjectName }).slice(0, 10);
3439
const assignees = tasksData.map(task => { return task.assignedTo });
3540
const statuses = tasksData.map(task => { return task.status });
@@ -58,6 +63,84 @@ export default function Task() {
5863
}
5964
}
6065

66+
const tagRender = (tagData: TagData, li: ReactElement<any>) => React.cloneElement(li, li.props, [
67+
<span key={assignees.indexOf(tagData.data[0])} className="k-chip-label">
68+
<Avatar rounded="full" type="image" size="small" className="k-chip-avatar mr-1">
69+
<img src={projectManagers.map(manager => manager.name === tagData.data[0] ? manager.avatarSrc : "").filter(src => src !== "")[0]} alt="user-image" />
70+
</Avatar>
71+
{tagData.data[0]}
72+
</span>, li.props.children]);
73+
74+
const itemRender = (li: React.ReactElement<HTMLLIElement>, itemProps: ListItemProps) => {
75+
const index = itemProps.index;
76+
console.log(itemProps);
77+
const itemChildren = (
78+
<span key={index}>
79+
<Avatar rounded="full" type="image" size="small" className="mr-1">
80+
<img src={projectManagers.map(manager => manager.name === itemProps.dataItem ? manager.avatarSrc : "").filter(src => src !== "")[0]} alt="user-image" />
81+
</Avatar>
82+
{li.props.children as any} {index}
83+
</span>
84+
);
85+
86+
return React.cloneElement(li, li.props, itemChildren);
87+
};
88+
89+
const priorityValueRender = (element: React.ReactElement<HTMLSpanElement>, value: any) => {
90+
if (!value) {
91+
return element;
92+
}
93+
94+
const children = [
95+
<Badge
96+
key={value}
97+
rounded="full"
98+
position="inside"
99+
className="!relative !z-0"
100+
themeColor={
101+
value === "Urgent"
102+
? "error"
103+
: value === "Medium priority"
104+
? "warning"
105+
: value === "Low priority"
106+
? "success"
107+
: value === "Routine"
108+
? "tertiary"
109+
: "primary"
110+
}
111+
>
112+
{element.props.children as any}
113+
</Badge>
114+
];
115+
116+
return React.cloneElement(element, { ...element.props }, children);
117+
};
118+
119+
const priorityItemRender = (li: React.ReactElement<HTMLLIElement>, itemProps: ListItemProps) => {
120+
const itemChildren = (
121+
<Badge
122+
rounded="full"
123+
position="inside"
124+
className="!relative !z-0"
125+
themeColor={
126+
itemProps.dataItem === "Urgent"
127+
? "error"
128+
: itemProps.dataItem === "Medium priority"
129+
? "warning"
130+
: itemProps.dataItem === "Low priority"
131+
? "success"
132+
: itemProps.dataItem === "Routine"
133+
? "tertiary"
134+
: "primary"
135+
}
136+
>
137+
{li.props.children as any}
138+
</Badge>
139+
);
140+
141+
return React.cloneElement(li, li.props, itemChildren);
142+
};
143+
61144
return (
62145
<>
63146
<div style={{minHeight: 'calc(100vh - 106px)'}} className="flex flex-col p-10 gap-6">
@@ -115,10 +198,17 @@ Monitor key metrics post-launch to evaluate the effectiveness of the content man
115198
<ExpansionPanel title="Project" expanded={projExpanded} onAction={() => setProjExpanded(!projExpanded)} className="rounded-2xl">
116199
<Reveal>
117200
{projExpanded && <ExpansionPanelContent>
118-
<FloatingLabel label="Choose project" editorId={'project'} editorValue={project}>
119-
<DropDownList size="large" defaultValue="Online Learning Management System (LMS)"
120-
value={project} onChange={e => setProject(e.value as string)}
121-
data={projects} />
201+
<FloatingLabel label="Choose project" editorId={'project'} editorValue={project} className="flex">
202+
<DropDownList size="large" value={project} onChange={e => setProject(e.value as string)} data={projects} />
203+
</FloatingLabel>
204+
</ExpansionPanelContent>}
205+
</Reveal>
206+
</ExpansionPanel>
207+
<ExpansionPanel title="Assigned to" expanded={assigneeExpanded} onAction={() => setAssigneeExpanded(!assigneeExpanded)} className="rounded-2xl">
208+
<Reveal>
209+
{assigneeExpanded && <ExpansionPanelContent>
210+
<FloatingLabel label="Select assignee(s)" editorId={'assignee'} editorValue={assigneeExpanded} className="flex">
211+
<MultiSelect size="large" data={assignees} value={assignee} onChange={e => setAssignee([...e.value] as string[])} tagRender={tagRender} itemRender={itemRender} />
122212
</FloatingLabel>
123213
</ExpansionPanelContent>}
124214
</Reveal>
@@ -127,25 +217,25 @@ Monitor key metrics post-launch to evaluate the effectiveness of the content man
127217
<Reveal>
128218
{dateExpanded && <ExpansionPanelContent>
129219
<FloatingLabel label="Set due date" editorId={'due-date'} editorValue={dateExpanded} className="flex">
130-
<DateInput size="large" value={new Date("05/03/2025")} />
220+
<DateInput size="large" value={dueDate} onChange={e => setDueDate(e.value as Date)} />
131221
</FloatingLabel>
132222
</ExpansionPanelContent>}
133223
</Reveal>
134224
</ExpansionPanel>
135-
<ExpansionPanel title="Assigned to" expanded={assigneeExpanded} onAction={() => setAssigneeExpanded(!assigneeExpanded)} className="rounded-2xl">
225+
<ExpansionPanel title="Priority" expanded={priorityExpanded} onAction={() => setPriorityExpanded(!priorityExpanded)} className="rounded-2xl">
136226
<Reveal>
137-
{assigneeExpanded && <ExpansionPanelContent>
138-
<FloatingLabel label="Select assignee(s)" editorId={'assignee'} editorValue={assigneeExpanded} className="flex">
139-
<MultiSelect size="large" data={assignees} value={assignee} onChange={e => setAssignee([...e.value] as string[])} />
227+
{priorityExpanded && <ExpansionPanelContent>
228+
<FloatingLabel label="Priority" editorId={'priority'} editorValue={priority} className="flex">
229+
<DropDownList size="large" value={priority} onChange={e => setPriority(e.value as string)} data={priorities} valueRender={priorityValueRender} itemRender={priorityItemRender} />
140230
</FloatingLabel>
141231
</ExpansionPanelContent>}
142232
</Reveal>
143-
</ExpansionPanel>
233+
</ExpansionPanel>
144234
<ExpansionPanel title="Status" expanded={statusExpanded} onAction={() => setStatusExpanded(!statusExpanded)} className="rounded-2xl">
145235
<Reveal>
146236
{statusExpanded && <ExpansionPanelContent>
147237
<FloatingLabel label="Select assignee(s)" editorId={'status'} editorValue={statusExpanded} className="flex">
148-
<DropDownList size="large" data={statuses} value={status} onChange={e => setStatus([e.value as string])} />
238+
<DropDownList size="large" data={statuses} value={status} onChange={e => setStatus(e.value as string)} />
149239
</FloatingLabel>
150240
</ExpansionPanelContent>}
151241
</Reveal>

examples/kendo-react-freemium/src/pages/Tasks.tsx

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { filterBy } from "@progress/kendo-data-query";
22
import { Button } from "@progress/kendo-react-buttons";
33
import { GridFilterChangeEvent, GridItemChangeEvent, Grid, GridToolbar, GridSearchBox, GridColumn } from "@progress/kendo-react-grid";
44
import { BreadcrumbLinkMouseEvent, Breadcrumb } from "@progress/kendo-react-layout";
5-
import { exportIcon, homeIcon, printIcon } from "@progress/kendo-svg-icons";
5+
import { exportIcon, homeIcon, plusIcon, printIcon } from "@progress/kendo-svg-icons";
66
import React from "react";
77
import { CSVLink } from "react-csv";
88
import { useNavigate } from "react-router-dom";
@@ -50,7 +50,7 @@ export default function Tasks() {
5050

5151
setData(newData);
5252
};
53-
53+
5454
const handleRowDoubleClick = (event: any) => {
5555
navigate(`/tasks/${event.dataItem.taskId}`);
5656
};
@@ -66,8 +66,9 @@ export default function Tasks() {
6666
className="!bg-app-surface"
6767
/>
6868

69-
<div className="flex flex-wrap items-center">
69+
<div className="flex flex-wrap items-center justify-between">
7070
<h1 className="text-4xl">Tasks</h1>
71+
<Button themeColor="primary" fillMode="outline" svgIcon={plusIcon}>Add new task</Button>
7172
</div>
7273

7374
<Grid
@@ -112,37 +113,22 @@ export default function Tasks() {
112113
Print
113114
</Button>
114115
</GridToolbar>
115-
<GridColumn field="taskName" title="Task Name" width={350} editable={false} />
116+
<GridColumn field="taskName" title="Task Name" editable={false} />
116117
<GridColumn
117118
field="assignedTo"
118119
title="Assigned To"
119-
width={195}
120120
editable={false}
121121
/>
122122
<GridColumn
123123
field="dueDate"
124124
title="Due Date"
125-
width={195}
126125
format="{0:d}"
127126
filter="date"
128127
editable={false}
129128
/>
130-
<GridColumn
131-
field="priority"
132-
title="Priority"
133-
width={195}
134-
editable={false}
135-
/>
136129
<GridColumn
137130
field="status"
138131
title="Status"
139-
width={200}
140-
editable={false}
141-
/>
142-
<GridColumn
143-
field="tags"
144-
title="Tags"
145-
width={270}
146132
editable={false}
147133
/>
148134
</Grid>

0 commit comments

Comments
 (0)