@gpa-gemstone/react-table
Version:
Table for GPA web applications
192 lines (191 loc) • 11.5 kB
JavaScript
"use strict";
// ******************************************************************************************************
// ConfigurableTable.tsx - Gbtc
//
// Copyright © 2021, Grid Protection Alliance. All Rights Reserved.
//
// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
// the NOTICE file distributed with this work for additional information regarding copyright ownership.
// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may not use this
// file except in compliance with the License. You may obtain a copy of the License at:
//
// http://opensource.org/licenses/MIT
//
// Unless agreed to in writing, the subject software distributed under the License is distributed on an
// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
// License for the specific language governing permissions and limitations.
//
// Code Modification History:
// ----------------------------------------------------------------------------------------------------
// 09/15/2021 - Christoph Lackner
// Generated original version of source code.
// ******************************************************************************************************
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = ConfigurableTable;
const React = require("react");
const Table_1 = require("../Table/Table");
const gpa_symbols_1 = require("@gpa-gemstone/gpa-symbols");
const react_interactive_1 = require("@gpa-gemstone/react-interactive");
const react_portal_1 = require("react-portal");
const helper_functions_1 = require("@gpa-gemstone/helper-functions");
const react_forms_1 = require("@gpa-gemstone/react-forms");
const _ = require("lodash");
const ConfigurableColumn_1 = require("./ConfigurableColumn");
/**
* Table with modal to show and hide columns
*/
function ConfigurableTable(props) {
const getKeyMappings = () => {
const u = new Map();
React.Children.forEach(props.children, (element) => {
var _a, _b;
if (!React.isValidElement(element))
return;
if (element.type === ConfigurableColumn_1.default) {
const c = {
Default: (_a = element.props.Default) !== null && _a !== void 0 ? _a : false,
Label: (_b = element.props.Label) !== null && _b !== void 0 ? _b : element.props.Key,
Enabled: false,
Key: element.props.Key,
};
c.Enabled = isEnabled(c);
u.set(c.Key, c);
}
});
return u;
};
const [showSettings, setShowSettings] = React.useState(false);
const [columns, setColumns] = React.useState(getKeyMappings());
const [hover, setHover] = React.useState(false);
const [guid] = React.useState((0, helper_functions_1.CreateGuid)());
const [widthDisabledAdd, setWidthDisabledAdd] = React.useState(false);
const handleReduceWidthCallback = React.useCallback((hiddenKeys) => {
if (hiddenKeys.length !== 0) {
setWidthDisabledAdd(true);
}
else {
setWidthDisabledAdd(false);
}
}, []);
React.useEffect(() => {
if (props.OnSettingsChange !== undefined)
props.OnSettingsChange(showSettings);
}, [showSettings]);
React.useEffect(() => {
saveLocal();
}, [columns]);
/**
*
* @returns
*/
function saveLocal() {
if (props.LocalStorageKey === undefined)
return;
const currentState = localStorage.getItem(props.LocalStorageKey);
let currentKeys = [];
if (currentState !== null)
currentKeys = currentState.split(',');
const allKeys = Array.from(columns.keys());
currentKeys = currentKeys.filter((k) => !allKeys.includes(k));
const enabled = Array.from(columns.keys()).filter((k) => { var _a; return (_a = columns.get(k)) === null || _a === void 0 ? void 0 : _a.Enabled; });
currentKeys.push(...enabled);
localStorage.setItem(props.LocalStorageKey, currentKeys.join(','));
}
function changeColumns(key) {
setColumns((d) => {
var _a, _b;
const u = _.cloneDeep(d);
const mapRef = u.get(key);
if (mapRef == null) {
console.error("Could not find reference for column " + key);
}
else
mapRef.Enabled = !((_b = (_a = u.get(key)) === null || _a === void 0 ? void 0 : _a.Enabled) !== null && _b !== void 0 ? _b : false);
return u;
});
}
function checkLocal(key) {
if (props.LocalStorageKey === undefined)
return false;
const keys = localStorage.getItem(props.LocalStorageKey);
if (keys === null)
return false;
const activeKeys = keys.split(',');
return activeKeys.includes(key !== null && key !== void 0 ? key : '');
}
/**
* * Determines if a column is enabled by default, required, or was saved in the users preferences
* * @param c Column to check
* * @param skipLocal If true, will return whether it is enabled as part of the default settings
* */
function isEnabled(c, skipLocal = false) {
var _a;
const isSort = props.SortKey === (c === null || c === void 0 ? void 0 : c.Key);
const isLocal = checkLocal(c === null || c === void 0 ? void 0 : c.Key) && !skipLocal;
return ((_a = c === null || c === void 0 ? void 0 : c.Default) !== null && _a !== void 0 ? _a : false) || isSort || isLocal;
}
return (React.createElement(React.Fragment, null,
React.createElement(Table_1.Table, Object.assign({}, props, { LastColumn: React.createElement("div", { style: { marginLeft: -5, marginBottom: 12, cursor: 'pointer' }, onMouseEnter: () => setHover(true), onMouseLeave: () => setHover(false), id: guid + '-tooltip', onClick: () => setShowSettings(true) },
React.createElement(gpa_symbols_1.ReactIcons.Settings, null)), ReduceWidthCallback: handleReduceWidthCallback }), React.Children.map(props.children, (element) => {
var _a, _b;
if (!React.isValidElement(element))
return null;
if (element.type === ConfigurableColumn_1.default)
return ((_b = (_a = columns.get(element.props.Key)) === null || _a === void 0 ? void 0 : _a.Enabled) !== null && _b !== void 0 ? _b : false) ? element.props.children : null;
return element;
})),
React.createElement(react_forms_1.ToolTip, { Show: hover, Position: 'bottom', Target: guid + '-tooltip', Zindex: 99999 },
React.createElement("p", null, "Change Columns")),
props.SettingsPortal === undefined ? (React.createElement(react_interactive_1.Modal, { Title: 'Table Columns', Show: showSettings, ShowX: true, ShowCancel: false, ZIndex: props.ModalZIndex, CallBack: (conf) => {
setShowSettings(false);
if (conf)
setColumns((d) => {
const u = _.cloneDeep(d);
Array.from(d.keys()).forEach((k) => {
var _a;
const ref = u.get(k);
if (ref != null)
ref.Enabled = (_a = isEnabled(u.get(k), true)) !== null && _a !== void 0 ? _a : true;
});
return u;
});
}, ConfirmText: 'Reset Defaults', ConfirmBtnClass: 'btn-warning float-left' },
React.createElement(ColumnSelection, { columns: Array.from(columns.values()), onChange: changeColumns, sortKey: props.SortKey, disableAdd: widthDisabledAdd }))) : showSettings ? (React.createElement(react_portal_1.Portal, { node: document === null || document === void 0 ? void 0 : document.getElementById(props.SettingsPortal) },
React.createElement("div", { className: "card" },
React.createElement("div", { className: "card-header" },
React.createElement("h4", { className: "modal-title" }, "Table Columns"),
React.createElement("button", { type: "button", className: "close", onClick: () => setShowSettings(false) }, "\u00D7")),
React.createElement("div", { className: "card-body", style: { maxHeight: 'calc(100% - 210px)', overflowY: 'auto' } },
React.createElement(ColumnSelection, { columns: Array.from(columns.values()), onChange: changeColumns, sortKey: props.SortKey, disableAdd: widthDisabledAdd })),
React.createElement("div", { className: "card-footer" },
React.createElement("button", { type: "button", className: 'btn btn-primary float-left', onClick: () => {
setShowSettings(false);
setColumns((d) => {
const u = _.cloneDeep(d);
Array.from(d.keys()).forEach((k) => {
var _a;
const ref = u.get(k);
if (ref != null)
ref.Enabled = (_a = isEnabled(u.get(k), true)) !== null && _a !== void 0 ? _a : true;
});
return u;
});
} }, "Reset Defaults"))))) : null));
}
function ColumnSelection(props) {
const [showAlert, setShowAlert] = React.useState(true);
return (React.createElement(React.Fragment, null,
React.createElement("div", { className: "row" },
React.createElement("div", { className: "col-4" }, props.columns.map((c, i) => i % 3 == 0 ? (React.createElement(react_forms_1.CheckBox, { Label: c.Label, Field: 'Enabled', Record: c, Setter: () => props.onChange(c.Key), key: c.Key, Disabled: c.Key == props.sortKey || (props.disableAdd && !c.Enabled), Help: c.Key == props.sortKey
? 'The Table is currently sorted by this column so it cannot be hidden.'
: undefined })) : null)),
React.createElement("div", { className: "col-4" }, props.columns.map((c, i) => i % 3 == 1 ? (React.createElement(react_forms_1.CheckBox, { Label: c.Label, Field: 'Enabled', Record: c, Setter: () => props.onChange(c.Key), key: c.Key, Disabled: c.Key == props.sortKey || (props.disableAdd && !c.Enabled), Help: c.Key == props.sortKey
? 'The Table is currently sorted by this column so it cannot be hidden.'
: undefined })) : null)),
React.createElement("div", { className: "col-4" }, props.columns.map((c, i) => i % 3 == 2 ? (React.createElement(react_forms_1.CheckBox, { Label: c.Label, Field: 'Enabled', Record: c, Setter: () => props.onChange(c.Key), key: c.Key, Disabled: c.Key == props.sortKey || (props.disableAdd && !c.Enabled), Help: c.Key == props.sortKey
? 'The Table is currently sorted by this column so it cannot be hidden.'
: undefined })) : null))),
props.disableAdd ?
React.createElement(react_interactive_1.Alert, { Class: 'alert-primary', Style: { marginBottom: 0, marginTop: '0.5em' } }, "Additional columns disabled due to table size.")
: null));
}