Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
node_modules
dist
dist/bundle.js.map
dist/bundle.js
package-lock.json
dist/bundle.js.map
dist/bundle.js
npm-debug.log
14 changes: 14 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html>

<head>
<meta charset="UTF-8" />
<title>Hello React!</title>
</head>

<body>
<div id="example"></div>

</body>

</html>
57 changes: 57 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
{
"name": "sureify.pbpraveen.me",
"version": "1.0.0",
"description": "React Tutorial with Typescript",
"main": "index.js",
"scripts": {
"clean": "rm -rf /dist",
"build": "webpack --mode=development",
"dev": "set NODE_ENV=dev && npm run clean && npm run build && webpack-dev-server --mode=development --content-base dist/",
"start": ""
},
"author": "Praveen Kumar",
"license": "ISC",
"dependencies": {
"@blueprintjs/core": "^3.29.0",
"@blueprintjs/datetime": "^3.18.3",
"@blueprintjs/select": "^3.13.4",
"@blueprintjs/table": "^3.8.10",
"@types/lodash": "^4.14.157",
"@types/pure-render-decorator": "^0.2.28",
"@types/react": "^16.0.36",
"@types/react-addons-css-transition-group": "^15.0.3",
"@types/react-dom": "^16.0.3",
"@types/react-redux": "^7.1.9",
"babel-loader": "^8.1.0",
"babel-preset-es2015": "^6.24.1",
"babel-preset-react": "^6.24.1",
"es6-promise": "^4.2.8",
"firebase": "^4.11.0",
"html-webpack-plugin": "^4.3.0",
"lodash": "^4.17.15",
"react": "^16.2.0",
"react-addons-css-transition-group": "^15.6.2",
"react-dom": "^16.2.0",
"react-redux": "^7.2.0",
"redux": "^4.0.5",
"redux-thunk": "^2.3.0",
"runtypes": "^4.3.0",
"style-loader": "^1.2.1",
"url-loader": "^4.1.0",
"webpack": "^4.43.0",
"whatwg-fetch": "^3.1.0"
},
"devDependencies": {
"awesome-typescript-loader": "^5.2.1",
"css-loader": "^3.6.0",
"extract-text-webpack-plugin": "^2.1.2",
"mini-css-extract-plugin": "^0.9.0",
"node-sass": "^4.14.1",
"postcss-loader": "^3.0.0",
"sass-loader": "^8.0.2",
"source-map-loader": "^1.0.1",
"typescript": "^3.9.6",
"webpack-cli": "^3.3.12",
"webpack-dev-server": "^3.11.0"
}
}
1 change: 1 addition & 0 deletions src/components/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './tasks';
190 changes: 190 additions & 0 deletions src/components/tasks/AddTaskForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
import * as React from 'react';
import { Dialog, Classes, Button, Intent } from '@blueprintjs/core';
import { FormGroup, InputGroup, TextArea } from '@blueprintjs/core';
import { DateInput, IDateFormatProps } from "@blueprintjs/datetime";
import { Task, UIOption, Priority } from '../../models';
import { StoreUtils } from '../../store';
import { Sf } from '../../services';

export interface AddTaskFormProps {
openModal?: boolean;
onClose?: (value?: any) => any;
taskRecord?: Task;
mode?: 'add' | 'edit' | 'view';
}

export interface AddTaskFormState {
openModal?: boolean;
taskRecord?: Task;
mode?: 'add' | 'edit' | 'view';
}

export class AddTaskForm extends React.Component<AddTaskFormProps, AddTaskFormState>
{


constructor(props: AddTaskFormProps) {
super(props);
this.state = {
openModal: props.openModal,
taskRecord: props.taskRecord || new Task(),
mode: props.taskRecord ? 'edit' : 'add'
}
}

public componentWillReceiveProps(nextProps: AddTaskFormProps) {
if (nextProps.taskRecord) {
const taskRecord = JSON.parse(JSON.stringify(nextProps.taskRecord));
taskRecord.dueDate = new Date(taskRecord.dueDate);
this.setState({ openModal: nextProps.openModal, taskRecord: nextProps.taskRecord, mode: nextProps.mode ? nextProps.mode : 'edit' })
} else {
this.setState({ openModal: nextProps.openModal, taskRecord: undefined, mode: 'add' })
}
}


public render() {
const state = this.state;
const jsDateFormatter: IDateFormatProps = {
// note that the native implementation of Date functions differs between browsers
formatDate: date => date.toLocaleDateString(),
parseDate: str => new Date(str),
placeholder: "MM/DD/YYYY",
};
const taskRecord = state.taskRecord ? JSON.parse(JSON.stringify(state.taskRecord)) : state.taskRecord;
const dueDate = taskRecord && taskRecord.dueDate && new Date(taskRecord.dueDate);
return (
<Dialog
isOpen={this.state.openModal}
icon={state.mode === 'add' ? 'add' : state.mode === 'view' ? 'eye-open' : 'edit'}
onClose={this.handleClose}
title={`${state.mode === 'add' ? 'Add' : state.mode === 'view' ? 'View' : 'Edit'} Task`}
{...this.state}
>
<div className={Classes.DIALOG_BODY}>
<FormGroup

label={'Summary'}
labelFor="text-summary"

>
<InputGroup disabled={this.state.mode === 'view'} value={taskRecord ? taskRecord.title : undefined} onChange={(e: any) => this.handleOnChange('title', e.target.value)} type='text' id="text-summary" />
</FormGroup>
<FormGroup

label={'Description'}
labelFor="text-description"

>
<TextArea
disabled={this.state.mode === 'view'}
fill
value={taskRecord ? taskRecord.description : undefined}
growVertically={true}
large={true}
id='text-description'
onChange={(e: any) => this.handleOnChange('description', e.target.value)}
/>
</FormGroup>
<FormGroup

label={'Priority'}
labelFor="text-priority"
>
<select disabled={this.state.mode === 'view'} onChange={(event: any) => this.handleOnChange('priority', event.target.value)}>
{Priority.map((x: UIOption, index: number) => {
return (
<option selected={taskRecord ? x.value === taskRecord.priority : false} value={x.value}>{x.label}</option>
)
})}
</select>
</FormGroup>
<FormGroup

label={'Due Date'}
labelFor="text-duedate"
>
<DateInput disabled={this.state.mode === 'view'} value={dueDate} onChange={this.onDateChange} fill {...jsDateFormatter} />
</FormGroup>
{this.state.mode === 'view' &&

<FormGroup label={'Status'} >
<InputGroup disabled={this.state.mode === 'view'} value={taskRecord ? taskRecord.currentState === true ? 'Open' : 'Closed' : undefined} type='text' />
</FormGroup>
}
{this.state.mode === 'view' &&
<FormGroup label={'Created On'} >
<InputGroup disabled={this.state.mode === 'view'} value={taskRecord ? taskRecord.createdAt : undefined} type='text' />
</FormGroup>
}
</div>
<div className={Classes.DIALOG_FOOTER}>
<div className={Classes.DIALOG_FOOTER_ACTIONS}>
<Button onClick={this.handleClose}>Cancel</Button>
<Button disabled={this.state.mode === 'view'} onClick={this.handleOnSave} type="button" intent={Intent.PRIMARY} >
{this.state.mode === 'edit' ? 'Update' : 'Save'}
</Button>
</div>
</div>
</Dialog>
);
}

private handleOnSave = () => {
const state = this.state;
const taskRecord = state.taskRecord;
if (taskRecord && taskRecord.dueDate && taskRecord.dueDate instanceof Date) {
taskRecord.dueDate = (taskRecord?.dueDate as Date).toLocaleDateString();
}
const taskIndex = taskRecord && taskRecord.index;
const taskslist = StoreUtils.getNewRecord(Sf.store.getState(), 'tasklist');
if (!taskslist) {
const _tasklist: Task[] = [];

_tasklist.unshift(taskRecord as Task);
Sf.store.dispatch({
type: 'Service_GetNewRecord_Success',
object: 'tasklist',
record: _tasklist,
});
} else {
if (taskIndex != undefined) {
taskslist.splice(taskIndex, 1, taskRecord);
} else {
taskslist.unshift(taskRecord);
}
Sf.store.dispatch({
type: 'Service_GetNewRecord_Success',
object: 'tasklist',
record: taskslist,
});

}
console.log(Sf.store.getState());
this.props.onClose && this.props.onClose();
}

private handleOnChange = (key: string, value: any) => {
const state = this.state;
let taskRecord = state.taskRecord;
if (!taskRecord) {
taskRecord = new Task();
}
taskRecord[key] = value;
this.setState({ taskRecord });
}

private onDateChange = (selectedDate: Date, isUserChange: boolean) => {
this.handleOnChange('dueDate', selectedDate);
}

private handleClose = () => {
this.setState({ openModal: false, taskRecord: undefined, mode: undefined });
this.props.onClose && this.props.onClose();
}



}


53 changes: 53 additions & 0 deletions src/components/tasks/Task.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
@import "~@blueprintjs/datetime/lib/css/blueprint-datetime.css";

.task-grid {

.bp3-input-group {
width: 30%;
margin-bottom: 10px;
}

table {
font-family: arial, sans-serif;
border-collapse: collapse;
width: 100%;
}

td,
th {
border: 1px solid #dddddd;
text-align: left;
padding: 8px;
}

td.actions {
span {
margin-right: 5px;
text-decoration: underline;
cursor: pointer;
color: navy;
}
}


tr:nth-child(even) {
background-color: #dddddd;
}
}


.bp3-form-group {
select {
width: 100%;
height: 30px;
;
}
}



#btndisclaimer {
position: fixed;
right: 20px;
bottom: 20px;
}
Loading