k2hr3-app
Version:
K2HR3 Web Application is K2hdkc based Resource and Roles and policy Rules
1,546 lines (1,396 loc) • 46 kB
JSX
/*
*
* K2HR3 Web Application
*
* Copyright 2017 Yahoo Japan Corporation.
*
* K2HR3 is K2hdkc based Resource and Roles and policy Rules, gathers
* common management information for the cloud.
* K2HR3 can dynamically manage information as "who", "what", "operate".
* These are stored as roles, resources, policies in K2hdkc, and the
* client system can dynamically read and modify these information.
*
* For the full copyright and license information, please view
* the license file that was distributed with this source code.
*
* AUTHOR: Takeshi Nakatani
* CREATE: Mon Sep 4 2017
* REVISION:
*
*/
import React from 'react';
import ReactDOM from 'react-dom'; // eslint-disable-line no-unused-vars
import PropTypes from 'prop-types';
import Button from '@mui/material/Button';
import Dialog from '@mui/material/Dialog';
import DialogTitle from '@mui/material/DialogTitle';
import DialogContent from '@mui/material/DialogContent';
import DialogActions from '@mui/material/DialogActions';
import Typography from '@mui/material/Typography';
import TextField from '@mui/material/TextField';
import Tooltip from '@mui/material/Tooltip';
import Table from '@mui/material/Table';
import TableBody from '@mui/material/TableBody';
import TableCell from '@mui/material/TableCell';
import TableHead from '@mui/material/TableHead';
import TablePagination from '@mui/material/TablePagination';
import TableRow from '@mui/material/TableRow';
import Popover from '@mui/material/Popover';
import FormControlLabel from '@mui/material/FormControlLabel';
import Checkbox from '@mui/material/Checkbox';
import Select from '@mui/material/Select';
import MenuItem from '@mui/material/MenuItem'; // for select
import Box from '@mui/material/Box';
import CheckCircleIcon from '@mui/icons-material/CheckCircle';
import CopyClipBoardIcon from '@mui/icons-material/AssignmentTurnedInRounded';
import SettingActionIcon from '@mui/icons-material/SettingsApplicationsRounded';
import CreateRoleTokenIcon from '@mui/icons-material/AddBoxRounded';
import DeleteIcon from '@mui/icons-material/Delete';
import DispCodeIcon from '@mui/icons-material/ViewListRounded';
import BackPageIcon from '@mui/icons-material/Cancel';
import R3MsgBox from './r3msgbox'; // Message Box
import R3Message from '../util/r3message';
import { r3PathInfoDialog } from './r3styles';
import { roleType, errorType } from '../util/r3types';
import { r3IsEmptyEntity, r3IsEmptyEntityObject, r3IsEmptyStringObject, r3CompareCaseString, r3IsEmptyString, r3IsSafeTypedEntity, r3CompareString, convertISOStringToLocaleString, getDiffTimeFromISOString, diffRoundType, getDiffRoundStringFromISOString, r3DeepClone } from '../util/r3util';
//
// Local variables
//
const pageTypeValues = {
pageMain: 0,
pageManageRoleToken: 1,
pageDisplayCode: 2
};
const tooltipInTableValues = {
deleteRoleTokenButtonTooltip: 'deleteRoleTokenButtonTooltip',
dispCodeButtonTooltip: 'dispCodeButtonTooltip',
detailCreateTimeTooltip: 'detailCreateTimeTooltip',
detailExpireTimeTooltip: 'detailExpireTimeTooltip',
detailRoleTokenTooltip: 'detailRoleTokenTooltip'
};
const roleTokenSortKeys = {
createTime: 'date',
expireTime: 'expire',
roleToken: 'token',
};
const codeTypeValues = {
uds: 'uds',
secretYaml: 'secret',
sidecarYaml: 'sidecar',
crcObject: 'crc:'
};
const codeType = [
{
name: 'User Data Script for OpenStack',
value: codeTypeValues.uds
},
{
name: 'Secret Yaml for kubernetes',
value: codeTypeValues.secretYaml
},
{
name: 'Sidecar Yaml for kubernetes',
value: codeTypeValues.sidecarYaml
}
];
const roletokenTextFieldName= 'roletoken-textfield';
const codeTextFieldName = 'register-code-textfield';
//
// Path Information Class
//
export default class R3PathInfoDialog extends React.Component
{
static propTypes = {
r3provider: PropTypes.object.isRequired,
open: PropTypes.bool.isRequired,
tenant: PropTypes.object,
service: PropTypes.string,
type: PropTypes.string,
fullpath: PropTypes.string,
currentpath: PropTypes.string,
tableRawCount: PropTypes.number,
onClose: PropTypes.func.isRequired
};
static defaultProps = {
tenant: null,
service: null,
type: null,
fullpath: null,
currentpath: null,
tableRawCount: 5
};
roletokenInputElement = null; // input textfield for registration code.
codeInputElement = null; // input textfield for registration code.
state = {
// common
open: this.props.open,
pageType: pageTypeValues.pageMain,
stackedPreviousPages: [],
message: null,
// In manage role token page
manageRoleTokenPageNum: 0,
roleTokenList: [],
roleTokenSortKey: roleTokenSortKeys.createTime, // default is sorting by create time
roleTokenSortNormal: false, // default is reverse sorting
newRoleTokenPopoverAnchorEl: null,
newRoleTokenNoExpire: false,
// In openstack page
selectedRoleToken: null,
selectedRoleTokenTime: null,
codeType: codeTypeValues.uds,
codeUDS: null,
codeSecretYaml: null,
codeSidecarYaml: null,
objCrc: {},
tooltips: {
// In main page
manageRoleTokenButtonTooltip: false,
dispCodeNewRoleTokenButtonTooltip: false,
// In manage role token page
deleteRoleTokenButtonTooltip: -1,
newRoleTokenButtonTooltip: false,
dispCodeButtonTooltip: -1,
detailCreateTimeTooltip: -1,
detailExpireTimeTooltip: -1,
detailRoleTokenTooltip: -1,
// In OpenStack page
roletokenClipboardButtonTooltip: false,
copyClipboardButtonTooltip: false
}
};
constructor(props)
{
super(props);
// Binding(do not define handlers as arrow functions for performance)
// common
this.handleClose = this.handleClose.bind(this);
this.handleBackPage = this.handleBackPage.bind(this);
// In main page
this.handleManageRoleToken = this.handleManageRoleToken.bind(this);
this.handleDispCodeNewRoleToken = this.handleDispCodeNewRoleToken.bind(this);
// In manage role token page
this.handleNewRoleToken = this.handleNewRoleToken.bind(this);
this.handleNoExpireCheckboxChange = this.handleNoExpireCheckboxChange.bind(this);
this.handleConfirmNewRoleToken = this.handleConfirmNewRoleToken.bind(this);
this.handleCancelNewRoleToken = this.handleCancelNewRoleToken.bind(this);
this.handleManageRoleTokenPageChange= this.handleManageRoleTokenPageChange.bind(this);
this.handleDeleteRoleToken = this.handleDeleteRoleToken.bind(this);
this.handleDispCode = this.handleDispCode.bind(this);
// In openstack page
this.handleCodeTypeChange = this.handleCodeTypeChange.bind(this);
this.handleRoleTokenClipboard = this.handleRoleTokenClipboard.bind(this);
this.handleCopyClipboard = this.handleCopyClipboard.bind(this);
// styles
this.sxClasses = r3PathInfoDialog(props.theme);
}
// [NOTE]
// Use getDerivedStateFromProps by deprecating componentWillReceiveProps in React 17.x.
// The only purpose is to set the state data from props when the dialog changes from hidden to visible.
//
static getDerivedStateFromProps(nextProps, prevState)
{
if(prevState.open != nextProps.open){
return {
open: nextProps.open,
pageType: pageTypeValues.pageMain,
stackedPreviousPages: [],
message: null,
manageRoleTokenPageNum: 0,
roleTokenList: [],
selectedRoleToken: null,
selectedRoleTokenTime: null,
codeUDS: null,
codeSecretYaml: null,
codeSidecarYaml: null,
objCrc: {}
};
}
return null; // Return null to indicate no change to state.
}
handleClose(event, reason)
{
this.props.onClose(event, reason);
}
handleBackPage(event) // eslint-disable-line no-unused-vars
{
if(!r3IsSafeTypedEntity(this.state.stackedPreviousPages, 'array') || 0 == this.state.stackedPreviousPages.length){
return;
}
let newStackedPages = this.state.stackedPreviousPages.slice();
let prevPageType = newStackedPages.pop();
this.setState({
message: null,
pageType: prevPageType,
stackedPreviousPages: newStackedPages
});
}
handleManageRoleToken(event) // eslint-disable-line no-unused-vars
{
const { r3provider } = this.props;
let _comErrorMessage = r3provider.getR3TextRes().eCommunication;
let _newStackedPages = this.state.stackedPreviousPages.slice();
_newStackedPages.push(pageTypeValues.pageMain);
// Get Role Token Lists
this.getRoleTokenList((error, resobj) =>
{
if(null !== error){
console.info(error.message);
this.setState({
message: new R3Message(_comErrorMessage + error.message, errorType)
});
return;
}
// convert and set for display
this.complementRoleTokenList(resobj);
// sort
this.sortRoleTokenList(resobj);
this.setState({
message: null,
pageType: pageTypeValues.pageManageRoleToken,
stackedPreviousPages: _newStackedPages,
manageRoleTokenPageNum: 0,
roleTokenList: resobj,
});
});
}
handleDispCodeNewRoleToken(event) // eslint-disable-line no-unused-vars
{
const { r3provider } = this.props;
let _comErrorMessage = r3provider.getR3TextRes().eCommunication;
// get new role token(expire is default)
this.getNewRoleToken(null, (error, resobj) =>
{
if(null !== error){
console.info(error.message);
this.setState({
pageType: pageTypeValues.pageMain,
stackedPreviousPages: [],
message: new R3Message(_comErrorMessage + error.message, errorType)
});
return;
}
// keep new role token
let _newRoleToken = resobj.roleToken;
// remake role token list
this.getRoleTokenList((error, resobj) =>
{
if(null !== error){
console.info(error.message);
this.setState({
pageType: pageTypeValues.pageMain,
stackedPreviousPages: [],
message: new R3Message(_comErrorMessage + error.message, errorType)
});
return;
}
// convert and set for display
this.complementRoleTokenList(resobj, _newRoleToken);
// sort
this.sortRoleTokenList(resobj);
// search new role token in result(token list)
for(let cnt = 0; cnt < resobj.length; ++cnt){
if(resobj[cnt].token == _newRoleToken){
// found
let newStackedPages = this.state.stackedPreviousPages.slice();
newStackedPages.push(pageTypeValues.pageMain);
// update
this.setState({
message: null,
pageType: pageTypeValues.pageDisplayCode,
stackedPreviousPages: newStackedPages,
manageRoleTokenPageNum: 0,
selectedRoleToken: resobj[cnt].token,
selectedRoleTokenTime: resobj[cnt].dispTime,
codeUDS: resobj[cnt].codeUDS,
codeSecretYaml: resobj[cnt].codeSecretYaml,
codeSidecarYaml: resobj[cnt].codeSidecarYaml,
objCrc: resobj[cnt].objCrc
});
return;
}
}
// not found new role token
this.setState({
pageType: pageTypeValues.pageMain,
stackedPreviousPages: [],
message: new R3Message('Failed to create new role token', errorType)
});
});
});
}
handleDispCode(event, pos)
{
if(!r3IsSafeTypedEntity(this.state.roleTokenList, 'array') || pos < 0 || this.state.roleTokenList.length <= pos || r3IsEmptyEntity(this.state.roleTokenList[pos])){
return;
}
let newStackedPages = this.state.stackedPreviousPages.slice();
newStackedPages.push(pageTypeValues.pageManageRoleToken);
this.setState({
message: null,
pageType: pageTypeValues.pageDisplayCode,
stackedPreviousPages: newStackedPages,
manageRoleTokenPageNum: 0,
selectedRoleToken: this.state.roleTokenList[pos].token,
selectedRoleTokenTime: this.state.roleTokenList[pos].dispTime,
codeUDS: this.state.roleTokenList[pos].codeUDS,
codeSecretYaml: this.state.roleTokenList[pos].codeSecretYaml,
codeSidecarYaml: this.state.roleTokenList[pos].codeSidecarYaml,
objCrc: this.state.roleTokenList[pos].objCrc
});
}
handleManageRoleTokenPageChange(event, page)
{
this.setState({
message: null,
manageRoleTokenPageNum: page
});
}
handleNewRoleToken(event)
{
this.setState({
newRoleTokenButtonTooltip: false,
newRoleTokenPopoverAnchorEl: event.currentTarget,
newRoleTokenNoExpire: false
});
}
handleCancelNewRoleToken(event) // eslint-disable-line no-unused-vars
{
this.setState({
newRoleTokenButtonTooltip: false,
newRoleTokenPopoverAnchorEl: null,
newRoleTokenNoExpire: false
});
}
handleNoExpireCheckboxChange(event)
{
let isChecked = r3IsEmptyEntityObject(event.target, 'checked') ? null : event.target.checked;
if(this.state.newRoleTokenNoExpire === isChecked){
return;
}
this.setState({
newRoleTokenNoExpire: isChecked
});
}
handleConfirmNewRoleToken(event) // eslint-disable-line no-unused-vars
{
const { r3provider } = this.props;
let _comErrorMessage = r3provider.getR3TextRes().eCommunication;
let expire = (this.state.newRoleTokenNoExpire ? 0 : null);
// get new role token
this.getNewRoleToken(expire, (error, resobj) =>
{
if(null !== error){
console.info(error.message);
this.setState({
message: new R3Message(_comErrorMessage + error.message, errorType),
newRoleTokenButtonTooltip: false,
newRoleTokenPopoverAnchorEl: null,
newRoleTokenNoExpire: false
});
return;
}
// new role token
let _newRoleToken = resobj.roleToken;
// remake role token list
this.getRoleTokenList((error, resobj) =>
{
if(null !== error){
console.info(error.message);
this.setState({
message: new R3Message(_comErrorMessage + error.message, errorType),
newRoleTokenButtonTooltip: false,
newRoleTokenPopoverAnchorEl: null,
newRoleTokenNoExpire: false
});
return;
}
// convert and set for display
this.complementRoleTokenList(resobj, _newRoleToken);
// sort
this.sortRoleTokenList(resobj);
this.setState({
message: null,
manageRoleTokenPageNum: 0,
roleTokenList: resobj,
newRoleTokenButtonTooltip: false,
newRoleTokenPopoverAnchorEl: null,
newRoleTokenNoExpire: false
});
});
});
}
handleDeleteRoleToken(event, pos)
{
const { r3provider } = this.props;
let _comErrorMessage = r3provider.getR3TextRes().eCommunication;
if(isNaN(pos) || pos < 0 || this.state.roleTokenList.length <= pos){
return;
}
let roletoken = this.state.roleTokenList[pos].token;
// delete role token
this.deleteRoleToken(roletoken, (error) =>
{
if(null !== error){
console.info(error.message);
this.setState({
message: new R3Message(_comErrorMessage + error.message, errorType),
});
return;
}
// remake role token list
this.getRoleTokenList((error, resobj) =>
{
if(null !== error){
console.info(error.message);
this.setState({
message: new R3Message(_comErrorMessage + error.message, errorType),
});
return;
}
// convert and set for display
this.complementRoleTokenList(resobj);
// sort
this.sortRoleTokenList(resobj);
this.setState({
message: null,
roleTokenList: resobj
});
});
});
}
handleManageRoleTokenButtonTooltipChange = (event, isOpen) =>
{
this.setState({
tooltips: {
manageRoleTokenButtonTooltip: isOpen
}
});
};
handleDispCodeNewRoleTokenButtonTooltipChange = (event, isOpen) =>
{
this.setState({
tooltips: {
dispCodeNewRoleTokenButtonTooltip: isOpen
}
});
};
handleNewRoleTokenButtonTooltipChange = (event, isOpen) =>
{
this.setState({
tooltips: {
newRoleTokenButtonTooltip: isOpen
}
});
};
handleInTableTooltipChange = (event, type, extData) =>
{
if(tooltipInTableValues.deleteRoleTokenButtonTooltip === type){
this.setState({
tooltips: {
deleteRoleTokenButtonTooltip: extData
}
});
}else if(tooltipInTableValues.dispCodeButtonTooltip === type){
this.setState({
tooltips: {
dispCodeButtonTooltip: extData
}
});
}else if(tooltipInTableValues.detailCreateTimeTooltip === type){
this.setState({
tooltips: {
detailCreateTimeTooltip: extData
}
});
}else if(tooltipInTableValues.detailExpireTimeTooltip === type){
this.setState({
tooltips: {
detailExpireTimeTooltip: extData
}
});
}else if(tooltipInTableValues.detailRoleTokenTooltip === type){
this.setState({
tooltips: {
detailRoleTokenTooltip: extData
}
});
}
};
handleRoleTokenClipboardButtonTooltipChange = (event, isOpen) =>
{
this.setState({
tooltips: {
roletokenClipboardButtonTooltip: isOpen
}
});
};
handleRoleTokenClipboard(event) // eslint-disable-line no-unused-vars
{
if(r3IsEmptyEntityObject(this.roletokenInputElement, 'select') || !r3IsSafeTypedEntity(this.roletokenInputElement.select, 'function')){
return;
}
this.roletokenInputElement.select(); // select all text in text field
document.execCommand('copy'); // cpoy to clipboard
window.getSelection().removeAllRanges(); // unselect text
this.roletokenInputElement.blur(); // off furcus
this.setState({
tooltips: {
roletokenClipboardButtonTooltip: false
}
});
}
handleCopyClipboardButtonTooltipChange = (event, isOpen) =>
{
this.setState({
tooltips: {
copyClipboardButtonTooltip: isOpen
}
});
};
handleCopyClipboard(event) // eslint-disable-line no-unused-vars
{
if(r3IsEmptyEntityObject(this.codeInputElement, 'select') || !r3IsSafeTypedEntity(this.codeInputElement.select, 'function')){
return;
}
this.codeInputElement.select(); // select all text in text field
document.execCommand('copy'); // cpoy to clipboard
window.getSelection().removeAllRanges(); // unselect text
this.codeInputElement.blur(); // off furcus
this.setState({
tooltips: {
copyClipboardButtonTooltip: false
}
});
}
handleCodeTypeChange(event)
{
//let key = r3IsEmptyEntityObject(event.target, 'name') ? null : event.target.name;
let newValue= r3IsEmptyEntityObject(event.target, 'value') ? null : event.target.value;
if(r3IsEmptyString(newValue)){
console.warn('Changed new register code type is wrong.');
return;
}
if(newValue === this.state.codeType){
// nothing to update
return;
}
this.setState({
codeType: newValue
});
}
//
// Get Role Token List
//
getRoleTokenList(callback)
{
const { r3provider } = this.props;
let _callback = callback;
r3provider.getRoleTokenList(this.props.tenant, this.props.currentpath, true, (error, resobj) =>
{
if(null !== error){
console.info(error.message);
_callback(error, null);
return;
}
if(null === resobj){
error = new Error('Could not get role token list');
console.error(error.message);
_callback(error, null);
return;
}
_callback(null, resobj);
});
}
compareRoleToken = (token1, token2) =>
{
let result = this.state.roleTokenSortNormal ? 1 : -1;
if(r3IsEmptyString(token1[this.state.roleTokenSortKey]) && r3IsEmptyString(token2[this.state.roleTokenSortKey])){
result *= 0;
}else if(r3IsEmptyString(token1[this.state.roleTokenSortKey])){
result *= 1;
}else if(r3IsEmptyString(token2[this.state.roleTokenSortKey])){
result *= -1;
}else{
if(token1[this.state.roleTokenSortKey] > token2[this.state.roleTokenSortKey]){
result *= 1;
}else if(token1[this.state.roleTokenSortKey] < token2[this.state.roleTokenSortKey]){
result *= -1;
}else{
result *= 0;
}
}
return result;
};
sortRoleTokenList(roleTokens)
{
if(!r3IsSafeTypedEntity(roleTokens, 'array')){
return;
}
roleTokens.sort(this.compareRoleToken);
}
complementRoleTokenList(roleTokens, newRoleToken)
{
const { r3provider } = this.props;
if(!r3IsSafeTypedEntity(roleTokens, 'array')){
return;
}
let unknownString = r3provider.getR3TextRes().tResUnknownTimeUnit;
for(let cnt = 0; cnt < roleTokens.length; ++cnt){
let isNewToken = r3CompareString(roleTokens[cnt].token, newRoleToken);
let shortToken = r3IsEmptyString(roleTokens[cnt].token) ? '...' : (roleTokens[cnt].token.slice(0, 8) + '...');
let createTimeString= convertISOStringToLocaleString(roleTokens[cnt].date);
let expireTimeString= convertISOStringToLocaleString(roleTokens[cnt].expire);
let expireUnixTime = getDiffTimeFromISOString(roleTokens[cnt].expire, roleTokens[cnt].date);
let expireObject = getDiffRoundStringFromISOString(roleTokens[cnt].expire, roleTokens[cnt].date);
let expireString;
if(diffRoundType.days == expireObject.type){
expireString = String(expireObject.value) + r3provider.getR3TextRes().tResDaysTimeUnit;
}else if(diffRoundType.hours == expireObject.type){
expireString = String(expireObject.value) + r3provider.getR3TextRes().tResHoursTimeUnit;
}else if(diffRoundType.minutes == expireObject.type){
expireString = String(expireObject.value) + r3provider.getR3TextRes().tResMinutesTimeUnit;
}else{ // diffRoundType.seconds == expireObject.type
expireString = String(expireObject.value) + r3provider.getR3TextRes().tResSecondsTimeUnit;
}
let dispTime = (null == createTimeString ? unknownString : createTimeString) + ' ( ' + (null == expireTimeString ? unknownString : expireTimeString) + ' )';
let codeUDS = r3provider.getUserDataScript(roleTokens[cnt].registerpath);
let codeSecretYaml = r3provider.getSecretYaml(roleTokens[cnt].token);
let codeSidecarYaml = r3provider.getSidecarYaml(this.props.fullpath);
let objCrc = r3provider.getCRCObject(roleTokens[cnt].token, this.props.fullpath, roleTokens[cnt].registerpath);
// set
roleTokens[cnt].newToken = isNewToken;
roleTokens[cnt].shortToken = shortToken;
roleTokens[cnt].createTime = (null == createTimeString ? unknownString : createTimeString);
roleTokens[cnt].expireUnixTime = expireUnixTime;
roleTokens[cnt].expireTime = expireString;
roleTokens[cnt].dispTime = dispTime;
roleTokens[cnt].codeUDS = codeUDS;
roleTokens[cnt].codeSecretYaml = codeSecretYaml;
roleTokens[cnt].codeSidecarYaml = codeSidecarYaml;
roleTokens[cnt].objCrc = objCrc;
}
}
//
// Get New Role Token
//
getNewRoleToken(expire, callback)
{
const { r3provider } = this.props;
let _callback = callback;
r3provider.getNewRoleToken(this.props.tenant, this.props.currentpath, expire, (error, resobj) =>
{
if(null !== error){
console.info(error.message);
_callback(error, null);
return;
}
if(null === resobj || r3IsEmptyString(resobj.roleToken, true)){
error = new Error('Failed to create new role token');
console.error(error.message);
_callback(error, null);
return;
}
_callback(null, resobj);
});
}
//
// Delete Role Token
//
deleteRoleToken(roletoken, callback)
{
const { r3provider } = this.props;
let _callback = callback;
r3provider.deleteRoleToken(this.props.tenant, roletoken, (error) =>
{
if(null !== error){
console.info(error.message);
_callback(error);
return;
}
_callback(null);
});
}
//---------------------------------------------------------
// render Main Page
//---------------------------------------------------------
getActionToRoleTokenButtons()
{
const { theme, r3provider } = this.props;
return (
<React.Fragment>
<Typography
{ ...theme.r3PathInfoDialog.keyTitle }
sx={ this.sxClasses.keyTitle }
>
{ r3provider.getR3TextRes().tResRoleTokenSubTitle }
</Typography>
<Tooltip
title={ r3provider.getR3TextRes().tResRoleTokenManageTT }
open={ ((r3IsEmptyEntityObject(this.state, 'tooltips') || !r3IsSafeTypedEntity(this.state.tooltips.manageRoleTokenButtonTooltip, 'boolean')) ? false : this.state.tooltips.manageRoleTokenButtonTooltip) }
>
<Button
onClick={ this.handleManageRoleToken }
onMouseEnter={ event => this.handleManageRoleTokenButtonTooltipChange(event, true) }
onMouseLeave={ event => this.handleManageRoleTokenButtonTooltipChange(event, false) }
{ ...theme.r3PathInfoDialog.manageRoleTokenButton }
sx={ this.sxClasses.roleTokenButton }
>
<SettingActionIcon
sx={ this.sxClasses.roleTokenButtonIcon }
/>
{ r3provider.getR3TextRes().tResRoleTokenManageButton }
</Button>
</Tooltip>
<Tooltip
title={ r3provider.getR3TextRes().tResDispCodeNewRoleTokenTT }
open={ ((r3IsEmptyEntityObject(this.state, 'tooltips') || !r3IsSafeTypedEntity(this.state.tooltips.dispCodeNewRoleTokenButtonTooltip, 'boolean')) ? false : this.state.tooltips.dispCodeNewRoleTokenButtonTooltip) }
>
<Button
onClick={ this.handleDispCodeNewRoleToken }
onMouseEnter={ event => this.handleDispCodeNewRoleTokenButtonTooltipChange(event, true) }
onMouseLeave={ event => this.handleDispCodeNewRoleTokenButtonTooltipChange(event, false) }
{ ...theme.r3PathInfoDialog.dispCodeNewRoleTokenButton }
sx={ this.sxClasses.roleTokenButton }
>
<SettingActionIcon
sx={ this.sxClasses.roleTokenButtonIcon }
/>
{ r3provider.getR3TextRes().tResDispCodeNewRoleToken }
</Button>
</Tooltip>
</React.Fragment>
);
}
renderMain()
{
const { theme, r3provider } = this.props;
let tenant;
let tenantKey = (
<Typography
{ ...theme.r3PathInfoDialog.keyTitle }
sx={ this.sxClasses.keyTitle }
>
{ r3provider.getR3TextRes().tResTenantSubTitle }
</Typography>
);
if(r3IsEmptyStringObject(this.props.tenant, 'display')){
tenant = (
<React.Fragment>
{ tenantKey }
<Typography
{ ...theme.r3PathInfoDialog.value }
sx={ this.sxClasses.valueItalic }
>
{ r3provider.getR3TextRes().tResUnselected }
</Typography>
</React.Fragment>
);
}else{
tenant = (
<React.Fragment>
{ tenantKey }
<Typography
{ ...theme.r3PathInfoDialog.value }
sx={ this.sxClasses.value }
>
{ this.props.tenant.display }
</Typography>
</React.Fragment>
);
}
let serviceContents;
if(!r3IsEmptyString(this.props.service)){
serviceContents = (
<React.Fragment>
<Typography
{ ...theme.r3PathInfoDialog.keyTitle }
sx={ this.sxClasses.keyTitle }
>
{ r3provider.getR3TextRes().tResServiceSubTitle }
</Typography>
<Typography
{ ...theme.r3PathInfoDialog.value }
sx={ this.sxClasses.value }
>
{ this.props.service }
</Typography>
</React.Fragment>
);
}
let typeContents;
if(!r3IsEmptyString(this.props.type)){
typeContents = (
<React.Fragment>
<Typography
{ ...theme.r3PathInfoDialog.keyTitle }
sx={ this.sxClasses.keyTitle }
>
{ r3provider.getR3TextRes().tResTypeSubTitle }
</Typography>
<Typography
{ ...theme.r3PathInfoDialog.value }
sx={ this.sxClasses.value }
>
{ this.props.type }
</Typography>
</React.Fragment>
);
}
let fullpathContents;
if(!r3IsEmptyString(this.props.fullpath)){
fullpathContents = (
<React.Fragment>
<Typography
{ ...theme.r3PathInfoDialog.keyTitle }
sx={ this.sxClasses.keyTitle }
>
{ r3provider.getR3TextRes().tResPathSubTitle }
</Typography>
<Typography
{ ...theme.r3PathInfoDialog.value }
sx={ this.sxClasses.value }
>
{ this.props.fullpath }
</Typography>
</React.Fragment>
);
}
let roleTokenButtons;
if(!r3IsEmptyString(this.props.currentpath) && r3CompareCaseString(roleType, this.props.type) && r3IsEmptyString(this.props.service)){
roleTokenButtons = this.getActionToRoleTokenButtons();
}
return (
<React.Fragment>
{ tenant }
{ serviceContents }
{ typeContents }
{ fullpathContents }
{ roleTokenButtons }
</React.Fragment>
);
}
//---------------------------------------------------------
// render Manage Role Tokens Page
//---------------------------------------------------------
getManageRoleTokenInTableButtons(pos)
{
const { theme, r3provider } = this.props;
return(
<Box>
<Tooltip
title={ r3provider.getR3TextRes().tResDeleteRoleTokenTT }
open={ ((r3IsEmptyEntityObject(this.state, 'tooltips') || !r3IsSafeTypedEntity(this.state.tooltips.deleteRoleTokenButtonTooltip, 'number') || (this.state.tooltips.deleteRoleTokenButtonTooltip != pos)) ? false : true) }
>
<Button
onClick={ (event) => this.handleDeleteRoleToken(event, pos) }
onMouseEnter={ event => this.handleInTableTooltipChange(event, tooltipInTableValues.deleteRoleTokenButtonTooltip, pos) }
onMouseLeave={ event => this.handleInTableTooltipChange(event, tooltipInTableValues.deleteRoleTokenButtonTooltip, -1) }
{ ...theme.r3PathInfoDialog.manageDeleteButton }
sx={ this.sxClasses.manageActionButton }
>
<DeleteIcon />
</Button>
</Tooltip>
<Tooltip
title={ r3provider.getR3TextRes().tResDispCodeButtonTT }
open={ ((r3IsEmptyEntityObject(this.state, 'tooltips') || !r3IsSafeTypedEntity(this.state.tooltips.dispCodeButtonTooltip, 'number') || (this.state.tooltips.dispCodeButtonTooltip != pos)) ? false : true) }
>
<Button
onClick={ (event) => this.handleDispCode(event, pos) }
onMouseEnter={ event => this.handleInTableTooltipChange(event, tooltipInTableValues.dispCodeButtonTooltip, pos) }
onMouseLeave={ event => this.handleInTableTooltipChange(event, tooltipInTableValues.dispCodeButtonTooltip, -1) }
{ ...theme.r3PathInfoDialog.manageDispCodeButton }
sx={ this.sxClasses.manageActionButton }
>
<DispCodeIcon />
</Button>
</Tooltip>
</Box>
);
}
getNewRoleTokenPopover()
{
const { theme, r3provider } = this.props;
return (
<Popover
open={ Boolean(this.state.newRoleTokenPopoverAnchorEl) }
anchorEl={ this.state.newRoleTokenPopoverAnchorEl }
onClose={ this.handleCancelNewRoleToken }
{ ...theme.r3PathInfoDialog.newRoleTokenPopover }
sx={ this.sxClasses.newRoleTokenPopover }
>
<Typography
{ ...theme.r3PathInfoDialog.newRoleTokenPopoverTitle }
sx={ this.sxClasses.newRoleTokenPopoverTitle }
>
{ r3provider.getR3TextRes().tResRoleTokenPopoverTitle }
</Typography>
<FormControlLabel
control={
<Checkbox
disabled={ false }
value={ 'noexpire' }
checked={ this.state.newRoleTokenNoExpire }
onChange={ this.handleNoExpireCheckboxChange }
sx={ this.sxClasses.newRoleTokenExpireCheck }
/>
}
label={
<Typography
{ ...theme.r3PathInfoDialog.newRoleTokenExpireLabel }
sx={ this.sxClasses.newRoleTokenExpireLabel }
>
{ r3provider.getR3TextRes().tResRoleTokenExpireCheck }
</Typography>
}
sx={ this.sxClasses.newRoleTokenExpireForm }
/>
<Button
onClick={ this.handleConfirmNewRoleToken }
{ ...theme.r3PathInfoDialog.createRoleTokenButton }
sx={ this.sxClasses.createRoleTokenButton }
>
{ r3provider.getR3TextRes().tResNewRoleTokenButton }
<CheckCircleIcon
sx={ this.sxClasses.buttonIcon }
/>
</Button>
</Popover>
);
}
getManageRoleTokenTableHead()
{
const { theme, r3provider } = this.props;
let newRoleTokenPopover = this.getNewRoleTokenPopover();
return (
<TableHead
sx={ this.sxClasses.tableHead }
>
<TableRow>
<TableCell
sx={ this.sxClasses.tableCell }
>
<Tooltip
title={ r3provider.getR3TextRes().tResAddRoleTokenTT }
open={ ((r3IsEmptyEntityObject(this.state, 'tooltips') || !r3IsSafeTypedEntity(this.state.tooltips.newRoleTokenButtonTooltip, 'boolean')) ? false : this.state.tooltips.newRoleTokenButtonTooltip) }
>
<React.Fragment>
<Button
onClick={ this.handleNewRoleToken }
onMouseEnter={ event => this.handleNewRoleTokenButtonTooltipChange(event, true) }
onMouseLeave={ event => this.handleNewRoleTokenButtonTooltipChange(event, false) }
{ ...theme.r3PathInfoDialog.manageAddButton }
sx={ this.sxClasses.manageAddButton }
>
<CreateRoleTokenIcon />
</Button>
{ newRoleTokenPopover }
</React.Fragment>
</Tooltip>
<Typography
{ ...theme.r3PathInfoDialog.textTableHead }
sx={ this.sxClasses.textActionTableHead }
>
{ r3provider.getR3TextRes().tResActionTableHead }
</Typography>
</TableCell>
<TableCell
sx={ this.sxClasses.tableCell }
>
<Typography
{ ...theme.r3PathInfoDialog.textTableHead }
sx={ this.sxClasses.textTableHead }
>
{ r3provider.getR3TextRes().tResCreateTimeTableHead }
</Typography>
</TableCell>
<TableCell
sx={ this.sxClasses.tableCell }
>
<Typography
{ ...theme.r3PathInfoDialog.textTableHead }
sx={ this.sxClasses.textTableHead }
>
{ r3provider.getR3TextRes().tResExpireTimeTableHead }
</Typography>
</TableCell>
<TableCell
sx={ this.sxClasses.tableCell }
>
<Typography
{ ...theme.r3PathInfoDialog.textTableHead }
sx={ this.sxClasses.textTableHead }
>
{ r3provider.getR3TextRes().tResRoleTokenTableHead }
</Typography>
</TableCell>
</TableRow>
</TableHead>
);
}
getManageRoleTokenTableBody()
{
const { theme } = this.props;
if(!r3IsSafeTypedEntity(this.state.roleTokenList, 'array')){
return;
}
let roleTokens = this.state.roleTokenList;
return (
<TableBody>
{roleTokens.map( (item, pos) => {
if(pos < (this.state.manageRoleTokenPageNum * this.props.tableRawCount) || ((this.state.manageRoleTokenPageNum + 1) * this.props.tableRawCount) <= pos){
return;
}
let textTheme = (item.newToken ? theme.r3PathInfoDialog.textNewTableContent : theme.r3PathInfoDialog.textTableContent);
let textCalsses = (item.newToken ? this.sxClasses.textNewTableContent : this.sxClasses.textTableContent);
return (
<TableRow
hover={ false }
key={ pos }
selected={ false }
>
<TableCell
sx={ this.sxClasses.tableCell }
>
<Typography
{ ...theme.r3PathInfoDialog.textTableContent }
sx={ this.sxClasses.textTableContent }
>
{ this.getManageRoleTokenInTableButtons(pos) }
</Typography>
</TableCell>
<TableCell
sx={ this.sxClasses.tableCell }
>
<Tooltip
title={ item.expire }
open={ ((r3IsEmptyEntityObject(this.state, 'tooltips') || !r3IsSafeTypedEntity(this.state.tooltips.detailCreateTimeTooltip, 'number') || (this.state.tooltips.detailCreateTimeTooltip != pos)) ? false : true) }
>
<Typography
onMouseEnter={ event => this.handleInTableTooltipChange(event, tooltipInTableValues.detailCreateTimeTooltip, pos) }
onMouseLeave={ event => this.handleInTableTooltipChange(event, tooltipInTableValues.detailCreateTimeTooltip, -1) }
{ ...textTheme }
sx={ textCalsses }
>
{ item.createTime }
</Typography>
</Tooltip>
</TableCell>
<TableCell
sx={ this.sxClasses.tableCell }
>
<Tooltip
title={ item.expire }
open={ ((r3IsEmptyEntityObject(this.state, 'tooltips') || !r3IsSafeTypedEntity(this.state.tooltips.detailExpireTimeTooltip, 'number') || (this.state.tooltips.detailExpireTimeTooltip != pos)) ? false : true) }
>
<Typography
onMouseEnter={ event => this.handleInTableTooltipChange(event, tooltipInTableValues.detailExpireTimeTooltip, pos) }
onMouseLeave={ event => this.handleInTableTooltipChange(event, tooltipInTableValues.detailExpireTimeTooltip, -1) }
{ ...textTheme }
sx={ textCalsses }
>
{ item.expireTime }
</Typography>
</Tooltip>
</TableCell>
<TableCell
sx={ this.sxClasses.tableCell }
>
<Tooltip
title={ item.token }
open={ ((r3IsEmptyEntityObject(this.state, 'tooltips') || !r3IsSafeTypedEntity(this.state.tooltips.detailRoleTokenTooltip, 'number') || (this.state.tooltips.detailRoleTokenTooltip != pos)) ? false : true) }
PopperProps={{ sx: this.sxClasses.wordBreakTooltip }}
>
<Typography
onMouseEnter={ event => this.handleInTableTooltipChange(event, tooltipInTableValues.detailRoleTokenTooltip, pos) }
onMouseLeave={ event => this.handleInTableTooltipChange(event, tooltipInTableValues.detailRoleTokenTooltip, -1) }
{ ...textTheme }
sx={ textCalsses }
>
{ item.shortToken }
</Typography>
</Tooltip>
</TableCell>
</TableRow>
);
})}
</TableBody>
);
}
renderManageRoleToken()
{
const { theme } = this.props;
if(!r3IsSafeTypedEntity(this.state.roleTokenList, 'array')){
return;
}
let tablehead = this.getManageRoleTokenTableHead();
let tablebody = this.getManageRoleTokenTableBody();
return (
<React.Fragment>
<Table
{ ...theme.r3PathInfoDialog.table }
sx={ this.sxClasses.table }
>
{tablehead}
{tablebody}
</Table>
<TablePagination
component={ 'div' }
count={ this.state.roleTokenList.length }
rowsPerPage={ this.props.tableRawCount }
page={ this.state.manageRoleTokenPageNum }
rowsPerPageOptions={ [] }
onPageChange={ this.handleManageRoleTokenPageChange }
/>
</React.Fragment>
);
}
//---------------------------------------------------------
// render Display Role Token and Registration Code page
//---------------------------------------------------------
renderDispCode()
{
const { theme, r3provider } = this.props;
let roletokenContents = (
<React.Fragment>
<Typography
{ ...theme.r3PathInfoDialog.keyTitle }
sx={ this.sxClasses.keyTitle }
>
{ r3provider.getR3TextRes().tResRoleTokenSubTitle }
</Typography>
<TextField
name={ roletokenTextFieldName }
value={ this.state.selectedRoleToken }
inputRef = { (element) => { this.roletokenInputElement = element; } }
InputProps={{ sx: this.sxClasses.roletokenInputTextField }}
inputProps={{ style: { padding: 0 } }}
{ ...theme.r3PathInfoDialog.roletokenTextField }
sx={ this.sxClasses.roletokenTextField }
/>
<Tooltip
title={ r3provider.getR3TextRes().tResCopyClipboardTT }
open={ ((r3IsEmptyEntityObject(this.state, 'tooltips') || !r3IsSafeTypedEntity(this.state.tooltips.roletokenClipboardButtonTooltip, 'boolean')) ? false : this.state.tooltips.roletokenClipboardButtonTooltip) }
>
<Button
onClick={ this.handleRoleTokenClipboard }
onMouseEnter={ event => this.handleRoleTokenClipboardButtonTooltipChange(event, true) }
onMouseLeave={ event => this.handleRoleTokenClipboardButtonTooltipChange(event, false) }
{ ...theme.r3PathInfoDialog.roletokenClipboardButton }
sx={ this.sxClasses.roletokenClipboardButton }
>
<CopyClipBoardIcon
sx={ this.sxClasses.copyClipboardIcon }
/>
{ r3provider.getR3TextRes().tResCopyClipboardButton }
</Button>
</Tooltip>
</React.Fragment>
);
let timeContents = (
<React.Fragment>
<Typography
{ ...theme.r3PathInfoDialog.keyTitle }
sx={ this.sxClasses.keyTitle }
>
{ r3provider.getR3TextRes().tResRoleTokenTimeSubTitle }
</Typography>
<Typography
{ ...theme.r3PathInfoDialog.value }
sx={ this.sxClasses.value }
>
{ this.state.selectedRoleTokenTime }
</Typography>
</React.Fragment>
);
let codeText = null;
if(codeTypeValues.crcObject == this.state.codeType.substr(0, codeTypeValues.crcObject.length)){
let _crcKey = this.state.codeType.substr(codeTypeValues.crcObject.length);
if(r3IsSafeTypedEntity(this.state.objCrc[_crcKey], 'object') && !r3IsSafeTypedEntity(this.state.objCrc[_crcKey], 'array')){
codeText = '';
let _crcSubobj = this.state.objCrc[_crcKey];
Object.keys(_crcSubobj).forEach(function(subobjkey){
if(0 < codeText.length){
codeText += '\n';
}
codeText += subobjkey;
codeText += '=';
codeText += _crcSubobj[subobjkey];
});
}
}
if(null == codeText){
if(codeTypeValues.secretYaml == this.state.codeType){
codeText = (null === this.state.codeSecretYaml ? '' : this.state.codeSecretYaml);
}else if(codeTypeValues.sidecarYaml == this.state.codeType){
codeText = (null === this.state.codeSidecarYaml ? '' : this.state.codeSidecarYaml);
}else{ // codeTypeValues.uds == this.state.codeType
codeText = (null === this.state.codeUDS ? '' : this.state.codeUDS);
}
}
// make select items
let _margedCodeType = r3DeepClone(codeType);
Object.keys(this.state.objCrc).forEach(function(crcKey){
_margedCodeType.push({
name: crcKey,
value: codeTypeValues.crcObject + crcKey
});
});
let codeContents = (
<React.Fragment>
<Typography
{ ...theme.r3PathInfoDialog.keyTitle }
sx={ this.sxClasses.keyTitle }
>
{ r3provider.getR3TextRes().tResCodeSubTitle }
</Typography>
<Select
value={ this.state.codeType }
onChange={ this.handleCodeTypeChange }
inputProps={{ sx: this.sxClasses.codeTypeSelectInput }}
{ ...theme.r3PathInfoDialog.codeTypeSelect }
sx={ this.sxClasses.codeTypeSelect }
>
{
_margedCodeType.map( (item, pos) => {
return (
<MenuItem
key={ pos }
value={ item.value }
>
{ item.name }
</MenuItem>
);
})
}
</Select>
<TextField
name={ codeTextFieldName }
value={ codeText }
inputRef = { (element) => { this.codeInputElement = element; } }
InputProps={{ sx: this.sxClasses.codeInputTextField }}
{ ...theme.r3PathInfoDialog.codeTextField }
sx={ this.sxClasses.codeTextField }
/>
<Tooltip
title={ r3provider.getR3TextRes().tResCopyClipboardTT }
open={ ((r3IsEmptyEntityObject(this.state, 'tooltips') || !r3IsSafeTypedEntity(this.state.tooltips.copyClipboardButtonTooltip, 'boolean')) ? false : this.state.tooltips.copyClipboardButtonTooltip) }
>
<Button
onClick={ this.handleCopyClipboard }
onMouseEnter={ event => this.handleCopyClipboardButtonTooltipChange(event, true) }
onMouseLeave={ event => this.handleCopyClipboardButtonTooltipChange(event, false) }
{ ...theme.r3PathInfoDialog.copyClipboardButton }
sx={ this.sxClasses.copyClipboardButton }
>
<CopyClipBoardIcon
sx={ this.sxClasses.copyClipboardIcon }
/>
{ r3provider.getR3TextRes().tResCopyClipboardButton }
</Button>
</Tooltip>
</React.Fragment>
);
return (
<React.Fragment>
{ roletokenContents }
{ timeContents }
{ codeContents }
</React.Fragment>
);
}
//---------------------------------------------------------
// render Common parts
//---------------------------------------------------------
getBackPageButton()
{
const { theme, r3provider } = this.props;
if(!r3IsSafeTypedEntity(this.state.stackedPreviousPages, 'array') || 0 == this.state.stackedPreviousPages.length){
return;
}
return (
<Button
onClick={ this.handleBackPage }
{ ...theme.r3PathInfoDialog.previousButton }
sx={ this.sxClasses.previousButton }
>
{ r3provider.getR3TextRes().tResButtonPrevious }
<BackPageIcon
sx={ this.sxClasses.buttonIcon }
/>
</Button>
);
}
//---------------------------------------------------------
// render
//---------------------------------------------------------
render()
{
const { theme, r3provider } = this.props;
let title;
let contents;
let backpagebutton;
if(pageTypeValues.pageManageRoleToken == this.state.pageType){
title = r3provider.getR3TextRes().tResRoleTokenDialogTitle;
contents = this.renderManageRoleToken();
backpagebutton = this.getBackPageButton();
}else if(pageTypeValues.pageDisplayCode == this.state.pageType){
title = r3provider.getR3TextRes().tResDispCodeDialogTitle;
contents = this.renderDispCode();
backpagebutton = this.getBackPageButton();
}else{ // pageTypeValues.pageMain == this.state.pageType
title = r3provider.getR3TextRes().tResPathInfoDialogTitle;
contents = this.renderMain();
}
return (
<Dialog
open={ this.props.open }
onClose={ (event, reason) => this.handleClose(event, reason) }
{ ...theme.r3PathInfoDialog.root }
sx={ this.sxClasses.root }
>
<DialogTitle
{ ...theme.r3PathInfoDialog.dialogTitle }
sx={ this.sxClasses.dialogTitle }
>
<Typography
{ ...theme.r3PathInfoDialog.title }
sx={ this.sxClasses.title }
>
{ title }
</Typography>
</DialogTitle>
<DialogContent
sx={ this.sxClasses.dialogContent }
>
<R3MsgBox
theme={ theme }
message={ this.state.message }
/>
{ contents }
</DialogContent>
<DialogActions>
{ backpagebutton }
<Button
onClick={ (event, reason) => this.handleClose(event, reason) }
{ ...theme.r3PathInfoDialog.button }
sx={ this.sxClasses.button }
>
{ r3provider.getR3TextRes().tResButtonClose }
<CheckCircleIcon
sx={ this.sxClasses.buttonIcon }
/>
</Button>
</DialogActions>
</Dialog>
);
}
}
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noexpandtab sw=4 ts=4 fdm=marker
* vim<600: noexpandtab sw=4 ts=4
*/