Skip to content

Commit 107c092

Browse files
committed
NewProfilePopover.tsx init
1 parent 477135f commit 107c092

File tree

6 files changed

+101
-27
lines changed

6 files changed

+101
-27
lines changed
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import React, { ChangeEvent, useCallback, useState } from 'react';
2+
import { createUseStyles } from 'react-jss';
3+
import { Button, Input, Popover, Space } from 'antd';
4+
import { UserAddOutlined } from '@ant-design/icons';
5+
import rootStore from '../../modules/RootStore';
6+
7+
interface INewProfilePopoverProps {
8+
visible: boolean;
9+
setVisible: (visible: boolean) => void;
10+
}
11+
12+
const { settingsStore } = rootStore;
13+
14+
const NewProfilePopover: React.FC<INewProfilePopoverProps> = (
15+
props: INewProfilePopoverProps
16+
) => {
17+
const { visible, setVisible } = props;
18+
const classes = useStyles();
19+
20+
const [profile, setProfile] = useState<string>('');
21+
const [isValid, setIsValid] = useState<boolean>(false);
22+
23+
const isProfileValid = useCallback((profile: string) => {
24+
if (!/^[\w\d ]{2,}$/.test(profile)) {
25+
return false;
26+
}
27+
return !settingsStore.settings.profiles.includes(profile);
28+
}, []);
29+
30+
const handleChange = useCallback((event: ChangeEvent<HTMLInputElement>) => {
31+
const profile = event.target.value;
32+
setProfile(profile);
33+
setIsValid(isProfileValid(profile));
34+
}, []);
35+
36+
return (
37+
<Popover
38+
content={
39+
<Space>
40+
<Input
41+
placeholder="Enter a new profile name"
42+
value={profile}
43+
onChange={handleChange}
44+
/>
45+
<Button type="primary" disabled={!isValid}>
46+
Create
47+
</Button>
48+
</Space>
49+
}
50+
title="Create a new profile"
51+
trigger="click"
52+
visible={visible}
53+
onVisibleChange={setVisible}
54+
>
55+
<Button type="primary">
56+
<UserAddOutlined />
57+
</Button>
58+
</Popover>
59+
);
60+
};
61+
62+
const useStyles = createUseStyles({
63+
root: {},
64+
});
65+
66+
export default NewProfilePopover;

src/components/SettingsModal/SettingsModal.tsx

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,23 @@
1-
import React from 'react';
2-
import { Col, Form, Modal, Row, Select } from 'antd';
1+
import React, { useState } from 'react';
2+
import { Col, Form, Modal, Row, Select, Space } from 'antd';
33
import { createUseStyles } from 'react-jss';
44

55
import rootStore from '../../modules/RootStore';
6+
import IModalProps from '../../types/IModalProps';
7+
import NewProfilePopover from './NewProfilePopover';
68

79
const { settingsStore } = rootStore;
810

9-
interface ISettingsModalProps {
10-
visible: boolean;
11-
onClose: () => void;
12-
}
11+
interface ISettingsModalProps extends IModalProps {}
1312

14-
const SettingsModal: React.VFC<ISettingsModalProps> = (props: ISettingsModalProps) => {
13+
const SettingsModal: React.VFC<ISettingsModalProps> = (
14+
props: ISettingsModalProps
15+
) => {
1516
const { visible, onClose } = props;
17+
const [showNewProfilePopover, setShowNewProfilePopover] = useState<boolean>(
18+
false
19+
);
20+
1621
return (
1722
<Modal
1823
title="Settings"
@@ -23,15 +28,21 @@ const SettingsModal: React.VFC<ISettingsModalProps> = (props: ISettingsModalProp
2328
onCancel={onClose}
2429
>
2530
<Row>
26-
<Col span={8}>
31+
<Col span={24}>
2732
<Form.Item label="Profile" labelCol={{ span: 24 }}>
28-
<Select>
29-
{settingsStore.settings.profiles.map((profile) => (
30-
<Select.Option key={profile} value={profile}>
31-
{profile}
32-
</Select.Option>
33-
))}
34-
</Select>
33+
<Space>
34+
<Select>
35+
{settingsStore.settings.profiles.map((profile) => (
36+
<Select.Option key={profile} value={profile}>
37+
{profile}
38+
</Select.Option>
39+
))}
40+
</Select>
41+
<NewProfilePopover
42+
visible={showNewProfilePopover}
43+
setVisible={setShowNewProfilePopover}
44+
/>
45+
</Space>
3546
</Form.Item>
3647
</Col>
3748
</Row>

src/components/TimeRangeModal/TimeRangeModal.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import TaskTimeItemModel from '../../modules/tasks/models/TaskTimeItemModel';
1111
import { ITimeRangeModel } from '../../modules/tasks/models/TaskModel';
1212
import { Undefined } from '../../types/CommonTypes';
1313
import TimeRangeDuration from './components/TimeRangeDuration';
14+
import IModalProps from '../../types/IModalProps';
1415

1516
const { tasksStore } = rootStore;
1617

@@ -19,10 +20,8 @@ enum RangeField {
1920
end = 'end',
2021
}
2122

22-
interface TimeRangeModalProps {
23+
interface TimeRangeModalProps extends IModalProps {
2324
taskTime?: TaskTimeItemModel;
24-
visible: boolean;
25-
onClose: () => void;
2625
}
2726

2827
const TimeRangeModal = observer(

src/helpers/ClassNameHelper.ts

Lines changed: 0 additions & 5 deletions
This file was deleted.

src/screens/projects/components/DrawerTask/DrawerTask.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,12 @@ import Duration from './components/Duration';
1212
import TimeRangeModal from '../../../../components/TimeRangeModal/TimeRangeModal';
1313
import { Undefined } from '../../../../types/CommonTypes';
1414
import TaskTimeItemModel from '../../../../modules/tasks/models/TaskTimeItemModel';
15+
import IModalProps from '../../../../types/IModalProps';
1516

1617
const { projectStore } = rootStore;
1718

18-
interface DrawerTaskProps {
19-
task: TaskModel | undefined;
20-
visible: boolean;
21-
onClose: () => void;
19+
interface DrawerTaskProps extends IModalProps {
20+
task?: TaskModel;
2221
}
2322

2423
export default observer(function DrawerTask({

src/types/IModalProps.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export default interface IModalProps {
2+
visible: boolean;
3+
onClose: () => void;
4+
}

0 commit comments

Comments
 (0)