Create wt-odlux directory
[ccsdk/features.git] / sdnr / wt-odlux / odlux / framework / src / components / material-table / showColumnDialog.tsx
1 /**
2  * ============LICENSE_START========================================================================
3  * ONAP : ccsdk feature sdnr wt odlux
4  * =================================================================================================
5  * Copyright (C) 2022 highstreet technologies GmbH Intellectual Property. All rights reserved.
6  * =================================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
8  * in compliance with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software distributed under the License
13  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
14  * or implied. See the License for the specific language governing permissions and limitations under
15  * the License.
16  * ============LICENSE_END==========================================================================
17  */
18
19 import React from 'react';
20 import { Button, FormControlLabel, Popover, Switch, Typography } from '@mui/material';
21 import { connect, Connect, IDispatcher } from '../../flux/connect';
22
23 import { ColumnModel } from './columnModel';
24 import { IApplicationStoreState } from '../../store/applicationStore';
25 import { TableSettingsColumn } from '../../models/settings';
26 import { updateTableSettings } from '../../actions/settingsAction';
27
28 const mapStateToProps = (state: IApplicationStoreState) => ({
29     settings: state.framework.applicationState.settings,
30     settingsDoneLoading: state.framework.applicationState.settings.isInitialLoadDone
31 });
32
33 const mapDispatchToProps = (dispatcher: IDispatcher) => ({
34     saveToSettings: (tableName: string, columns: TableSettingsColumn[]) => dispatcher.dispatch(updateTableSettings(tableName, columns))
35 })
36
37 type DialogProps = {
38     columns: ColumnModel<{}>[],
39     settingsName: string | null,
40     anchorEl: HTMLElement | null;
41     hideColumns: (columnNames: string[]) => void
42     showColumns: (columnNames: string[]) => void
43     onClose(): void
44
45 } & Connect<typeof mapStateToProps, typeof mapDispatchToProps>;
46
47         //TODO: figure out why everything gets triggered twice...
48
49 const ShowColumnsDialog: React.FunctionComponent<DialogProps> = (props) => {
50
51     const savedSettings = props.settingsName && props.settings.tables[props.settingsName];
52
53     const [checkedColumns, setCheckedColumns] = React.useState<{ property: string, display: boolean, title: string | undefined }[]>([]);
54
55     const open = Boolean(props.anchorEl);
56     const allColumnNames = props.columns.map(e => e.property);
57
58     React.useEffect(() => {
59
60         createHideShowSelection();
61
62     }, []);
63
64     React.useEffect(() => {
65
66         createHideShowSelection();
67
68     }, [props.settings.isInitialLoadDone]);
69
70
71     const createHideShowSelection = () => {
72         let columns = props.columns.map(e => { return { property: e.property, display: !Boolean(e.hide), title: e.title } });
73
74
75         if (savedSettings) {
76
77             if (columns.length !== savedSettings.columns.length) {
78                 console.error("saved column length does not match current column length. Maybe a settings entry got wrongly overridden?")
79             }
80
81             //overwrite column data with settings
82             savedSettings?.columns.forEach(el => {
83                 let foundIndex = columns.findIndex(e => e.property == el.property);
84                 if (columns[foundIndex] !== undefined)
85                     columns[foundIndex].display = el.displayed;
86             });
87
88         } else {
89             console.warn("No settingsName set, changes will not be saved.")
90         }
91
92         setCheckedColumns(columns);
93
94         const hideColumns = columns.filter(el => !el.display).map(e => e.property);
95         props.hideColumns(hideColumns);
96     }
97
98
99     const handleChange = (propertyName: string, checked: boolean) => {
100         if (!checked) {
101             props.hideColumns([propertyName]);
102         } else {
103             props.showColumns([propertyName])
104
105         }
106      
107         let updatedList = checkedColumns.map(item => {
108             if (item.property == propertyName) {
109                 return { ...item, display: checked }; 
110             }
111             return item; 
112         });
113
114         setCheckedColumns(updatedList);
115     };
116
117     const onHideAll = () => {
118
119         switchCheckedColumns(false);
120         props.hideColumns(allColumnNames);
121     }
122
123     const onShowAll = () => {
124
125         switchCheckedColumns(true);
126         props.showColumns(allColumnNames);
127     }
128
129     const onClose = () => {
130
131         const tableColumns: TableSettingsColumn[] = checkedColumns.map(el => {
132             return {
133                 property: el.property,
134                 displayed: el.display
135             }
136         });
137
138         if (props.settingsName) {
139             props.saveToSettings(props.settingsName, tableColumns);
140         }
141         props.onClose();
142
143     }
144
145     const switchCheckedColumns = (changeToValue: boolean) => {
146         let updatedList = checkedColumns.map(item => {
147             return { ...item, display: changeToValue };
148         });
149
150         setCheckedColumns(updatedList);
151
152     }
153
154     return (<Popover open={open} onClose={onClose}
155         anchorEl={props.anchorEl}
156         anchorOrigin={{
157             vertical: 'top',
158             horizontal: 'left',
159         }} >
160         <div>
161             <Typography fontWeight={600} style={{ margin: 10 }} >Hide / Show Columns</Typography>
162         </div>
163         <div style={{ display: "flex", flexDirection: "column", margin: 10 }}>
164             {
165                 checkedColumns?.map((el, i) => {
166
167                     return <>
168
169                         <FormControlLabel
170                             value="end"
171                             key={"hide-show-column-"+i}
172                             aria-label={"hide-or-show-column-button"}
173                             control={<Switch color="secondary" checked={el.display} onChange={e => handleChange(el.property, e.target.checked)} />}
174                             label={el.title || el.property}
175                             labelPlacement="end"
176                         />
177                     </>
178                 })
179             }
180             <div style={{ display: "flex", flexDirection: "row", justifyContent: "space-between" }}>
181                 <Button color="secondary" aria-label="hide-all-columns-button" onClick={(e) => onHideAll()}>Hide all</Button>
182                 <Button color="secondary" aria-label="show-all-columns-button" onClick={(e) => onShowAll()}>Show all</Button>
183             </div>
184         </div>
185     </Popover>)
186 }
187
188 export default connect(mapStateToProps, mapDispatchToProps)(ShowColumnsDialog);