UX extensions
[ccsdk/features.git] / sdnr / wt / odlux / apps / maintenanceApp / src / views / maintenenceView.tsx
1 import * as React from 'react';
2
3 import { Theme, createStyles, WithStyles, withStyles, Tooltip } from '@material-ui/core';
4
5 import AddIcon from '@material-ui/icons/Add';
6 import EditIcon from '@material-ui/icons/Edit';
7 import RemoveIcon from '@material-ui/icons/RemoveCircleOutline';
8
9 import Button from '@material-ui/core/Button';
10 import IconButton from '@material-ui/core/IconButton';
11
12 import connect, { IDispatcher, Connect } from '../../../../framework/src/flux/connect';
13 import MaterialTable, { MaterialTableCtorType, ColumnType } from '../../../../framework/src/components/material-table';
14 import { IApplicationStoreState } from '../../../../framework/src/store/applicationStore';
15
16 import { loadAllMountedNetworkElementsAsync } from '../../../connectApp/src/actions/mountedNetworkElementsActions';
17
18 import { loadAllMainteneceEntriesAsyncAction } from '../actions/maintenenceActions';
19 import { MaintenenceEntry, spoofSymbol } from '../models/maintenenceEntryType';
20
21 import EditMaintenenceEntryDialog, { EditMaintenenceEntryDialogMode } from '../components/editMaintenenceEntryDialog';
22 import { convertToLocaleString } from '../utils/timeUtils';
23
24 const styles = (theme: Theme) => createStyles({
25   button: {
26     margin: 0,
27     padding: "6px 6px",
28     minWidth: 'unset'
29   },
30   spacer: {
31     marginLeft: theme.spacing.unit,
32     marginRight: theme.spacing.unit,
33     display: "inline"
34   }
35 });
36
37 const MaintenenceEntriesTable = MaterialTable as MaterialTableCtorType<MaintenenceEntry>;
38
39 const mapProps = (state: IApplicationStoreState) => ({
40    maintenenceEntries: state.maintenanceApp.maintenenceEntries.entries,
41    busy: state.maintenanceApp.maintenenceEntries.busy
42 });
43
44 const mapDispatcher = (dispatcher: IDispatcher) => ({
45   onLoadMenteneceEntries: async () => {
46     await dispatcher.dispatch(loadAllMountedNetworkElementsAsync)
47     dispatcher.dispatch(loadAllMainteneceEntriesAsyncAction);
48   }
49 });
50
51 const emptyMaintenenceEntry: MaintenenceEntry = {
52   _id: '',
53   mountId: '',
54   description: '',
55   start: convertToLocaleString(new Date().valueOf()),
56   end: convertToLocaleString(new Date().valueOf()),
57   active: false,
58 };
59
60 type MaintenenceViewComponentProps = Connect<typeof mapProps, typeof mapDispatcher> & WithStyles<typeof styles> & {
61
62 }
63
64 type MaintenenceViewComponentState = {
65   maintenenceEntryToEdit: MaintenenceEntry;
66   maintenenceEntryEditorMode: EditMaintenenceEntryDialogMode;
67 }
68
69 class MaintenenceViewComponent extends React.Component<MaintenenceViewComponentProps, MaintenenceViewComponentState> {
70
71   constructor (props: MaintenenceViewComponentProps) {
72     super(props);
73
74     this.state = {
75       maintenenceEntryToEdit: emptyMaintenenceEntry,
76       maintenenceEntryEditorMode: EditMaintenenceEntryDialogMode.None,
77     };
78
79   }
80
81   render() {
82     const { classes } = this.props;
83     const addMaintenenceEntryAction = {
84       icon: AddIcon, tooltip: 'Add', onClick: () => {
85         const startTime = (new Date().valueOf());
86         const endTime = startTime;
87         this.setState({
88           maintenenceEntryToEdit: {
89             ...emptyMaintenenceEntry,
90             start: convertToLocaleString(startTime),
91             end: convertToLocaleString(endTime),
92           },
93           maintenenceEntryEditorMode: EditMaintenenceEntryDialogMode.AddMaintenenceEntry
94         });
95       }
96     };
97     return (
98       <>
99         <MaintenenceEntriesTable asynchronus rows={this.props.maintenenceEntries} customActionButtons={[ addMaintenenceEntryAction ]} columns={
100         [
101           { property: "mountId", title: "Mount Id", type: ColumnType.text },
102           { property: "active", title: "Active", type: ColumnType.boolean, labels: { "true": "active", "false": "not active" }, },
103           { property: "start", title: "Start Date", type: ColumnType.text },
104           { property: "end", title: "End Date", type: ColumnType.text },
105           { property: "actions", title: "Actions", type: ColumnType.custom, customControl : ({ rowData })=>(
106             <>
107               <div className={classes.spacer}>
108                 <Tooltip title={"1h from now"} ><Button className={classes.button} onClick={ (event) => this.onOpenPlus1hEditMaintenenceEntryDialog(event, rowData)} >+1h</Button></Tooltip>
109                 <Tooltip title={"8h from now"} ><Button className={classes.button} onClick={(event) => this.onOpenPlus8hEditMaintenenceEntryDialog(event, rowData)} >+8h</Button></Tooltip>
110               </div>
111               <div className={classes.spacer}>
112                 <Tooltip title={"Edit"} ><IconButton className={classes.button} onClick={(event) => this.onOpenEditMaintenenceEntryDialog(event, rowData)} ><EditIcon /></IconButton></Tooltip>
113                 <Tooltip title={"Remove"} ><IconButton disabled={ !!rowData[spoofSymbol] } className={classes.button} onClick={(event) => this.onOpenRemoveMaintenenceEntryDialog(event, rowData)} ><RemoveIcon /></IconButton></Tooltip>
114               </div>
115             </>
116           ) },
117         ]
118         } idProperty={'_id'}> </MaintenenceEntriesTable>
119         <EditMaintenenceEntryDialog initialMaintenenceEntry={this.state.maintenenceEntryToEdit} mode={this.state.maintenenceEntryEditorMode}
120           onClose={ this.onCloseEditMaintenenceEntryDialog } />
121        </>
122     );
123   }
124
125   componentDidMount(){
126     this.props.onLoadMenteneceEntries();
127   }
128
129   private onOpenPlus1hEditMaintenenceEntryDialog = (event: React.MouseEvent<HTMLElement>, entry: MaintenenceEntry) => {
130     event.preventDefault();
131     event.stopPropagation();
132     const startTime = (new Date().valueOf());
133     const endTime = startTime + (1 * 60 * 60 * 1000);
134     this.setState({
135       maintenenceEntryToEdit: {
136         ...entry,
137         start: convertToLocaleString(startTime),
138         end: convertToLocaleString(endTime),
139       },
140       maintenenceEntryEditorMode: EditMaintenenceEntryDialogMode.EditMaintenenceEntry
141     });
142   }
143
144   private onOpenPlus8hEditMaintenenceEntryDialog = (event: React.MouseEvent<HTMLElement>, entry: MaintenenceEntry) => {
145     event.preventDefault();
146     event.stopPropagation();
147     const startTime = (new Date().valueOf());
148     const endTime = startTime + (8 * 60 * 60 * 1000);
149     this.setState({
150       maintenenceEntryToEdit: {
151         ...entry,
152         start: convertToLocaleString(startTime),
153         end: convertToLocaleString(endTime),
154       },
155       maintenenceEntryEditorMode: EditMaintenenceEntryDialogMode.EditMaintenenceEntry
156     });
157   }
158
159   private onOpenEditMaintenenceEntryDialog = (event: React.MouseEvent<HTMLElement>, entry: MaintenenceEntry) => {
160     event.preventDefault();
161     event.stopPropagation();
162     const startTime = (new Date().valueOf());
163     const endTime = startTime ;
164     this.setState({
165       maintenenceEntryToEdit: {
166         ...entry,
167         ...(entry.start && endTime)
168           ? { start: entry.start, end: entry.end }
169           : { start: convertToLocaleString(startTime), end: convertToLocaleString(endTime)}
170       },
171       maintenenceEntryEditorMode: EditMaintenenceEntryDialogMode.EditMaintenenceEntry
172     });
173   }
174
175   private onOpenRemoveMaintenenceEntryDialog = (event: React.MouseEvent<HTMLElement>, entry: MaintenenceEntry) => {
176     event.preventDefault();
177     event.stopPropagation();
178     const startTime = (new Date().valueOf());
179     const endTime = startTime;
180     this.setState({
181       maintenenceEntryToEdit: {
182         ...entry,
183         ...(entry.start && endTime)
184           ? { start: entry.start, end: entry.end }
185           : { start: convertToLocaleString(startTime), end: convertToLocaleString(endTime) }
186       },
187       maintenenceEntryEditorMode: EditMaintenenceEntryDialogMode.RemoveMaintenenceEntry
188     });
189   }
190
191   private onCloseEditMaintenenceEntryDialog = () => {
192     this.setState({
193       maintenenceEntryToEdit: emptyMaintenenceEntry,
194       maintenenceEntryEditorMode: EditMaintenenceEntryDialogMode.None,
195     });
196   }
197 }
198
199 export const MaintenenceView = withStyles(styles)(connect(mapProps, mapDispatcher)(MaintenenceViewComponent));
200 export default MaintenenceView;