UNPKG

k2hr3-app

Version:

K2HR3 Web Application is K2hdkc based Resource and Roles and policy Rules

1,182 lines (1,077 loc) 36.1 kB
/* * * 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: Tue Nov 21 2017 * REVISION: * */ import React from 'react'; import ReactDOM from 'react-dom'; // eslint-disable-line no-unused-vars import PropTypes from 'prop-types'; import TextField from '@mui/material/TextField'; import Typography from '@mui/material/Typography'; import IconButton from '@mui/material/IconButton'; import Box from '@mui/material/Box'; import FormControlLabel from '@mui/material/FormControlLabel'; import RadioGroup from '@mui/material/RadioGroup'; import Radio from '@mui/material/Radio'; 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 Tooltip from '@mui/material/Tooltip'; import DeleteIcon from '@mui/icons-material/ClearRounded'; import AddIcon from '@mui/icons-material/AddRounded'; import EditIcon from '@mui/icons-material/Edit'; import { r3Service } from './r3styles'; import R3FormButtons from './r3formbuttons'; // Buttons import R3Message from '../util/r3message'; import R3CreateServiceDialog from './r3createservicedialog'; import R3PopupMsgDialog from './r3popupmsgdialog'; import { regYrnTenantPathPrefix, regYrnAnyTenantPath } from '../util/r3define'; import { getServiceResourceType, normalizeServiceReourceStaticObject } from '../util/r3verifyutil'; import { errorType, actionTypeValue, actionTypeDelete, actionTypeAdd, serviceResTypeUrl, serviceResTypeObject, serviceResTypeUnknown } from '../util/r3types'; import { r3DeepClone, r3DeepCompare, r3CompareCaseString, r3IsEmptyEntityObject, r3IsEmptyString, r3IsEmptyEntity, r3IsSafeTypedEntity, r3IsJSON, r3ConvertFromJSON } from '../util/r3util'; // // Local variables // const tooltipValues = { deleteTenantTooltip: 'deleteTenantTooltip', addTenantTooltip: 'addTenantTooltip', addResStaticObjTooltip: 'addResStaticObjTooltip', nameResStaticObjTooltip: 'nameResStaticObjTooltip', jsonResStaticObjTooltip: 'jsonResStaticObjTooltip', delResStaticObjTooltip: 'delResStaticObjTooltip', editResStaticObjTooltip: 'editResStaticObjTooltip' }; const serviceComponentValues = { serviceResourceTypeName: 'serviceResourceType', verifyUrlResourceName: 'serviceVerifyUrlResource', resStaticObjTextFieldName: 'resStaticObjTextField', resUnknownTextFieldName: 'resUnknownTextField', tenantTextFieldNamePrefix: 'tenantValue_', tenantNewTextFieldName: 'tenantNew' }; // // Service Contents Class // export default class R3Service extends React.Component { static propTypes = { r3provider: PropTypes.object.isRequired, tenant: PropTypes.string.isRequired, service: PropTypes.object.isRequired, dispUnique: PropTypes.number.isRequired, tableRawCount: PropTypes.number, onSave: PropTypes.func.isRequired, onUpdate: PropTypes.func.isRequired }; static defaultProps = { tableRawCount: 5 }; static orgServiceResource = { serviceResType: null, serviceResVerifyUrl: null, serviceResStaticObject: null, serviceResUnknown: null, }; state = R3Service.createState(this.props.service, this.props.dispUnique); constructor(props) { super(props); // Binding(do not define handlers as arrow functions for performance) this.handleSave = this.handleSave.bind(this); this.handleCancel = this.handleCancel.bind(this); this.handleConfirmDialogClose = this.handleConfirmDialogClose.bind(this); this.handleMessageDialogClose = this.handleMessageDialogClose.bind(this); this.handleVerifyChange = this.handleVerifyChange.bind(this); this.handleTenantsChange = this.handleTenantsChange.bind(this); this.handleAddTenantsChange = this.handleAddTenantsChange.bind(this); this.handleResourceTypeChange = this.handleResourceTypeChange.bind(this); this.handleResStaticObjPageChange = this.handleResStaticObjPageChange.bind(this); this.handleNewStaticResourceObj = this.handleNewStaticResourceObj.bind(this); this.handleDelStaticResourceObj = this.handleDelStaticResourceObj.bind(this); this.handleEditStaticResourceObj = this.handleEditStaticResourceObj.bind(this); this.handleCloseStaticResourceDialog = this.handleCloseStaticResourceDialog.bind(this); this.handleCheckStaticResourceName = this.handleCheckStaticResourceName.bind(this); // styles this.sxClasses = r3Service(props.theme); } componentDidMount() { // update State this.setState(R3Service.createState(this.props.service, this.props.dispUnique)); } // [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(nextProps.dispUnique !== prevState.dispUnique){ // Switching content return R3Service.createState(nextProps.service, nextProps.dispUnique); } return null; // Return null to indicate no change to state. } static createState(service, dispUnique) { // keep original analyzed verify data R3Service.orgServiceResource.serviceResType = getServiceResourceType(service.verify); R3Service.orgServiceResource.serviceResVerifyUrl = ''; R3Service.orgServiceResource.serviceResStaticObject = []; R3Service.orgServiceResource.serviceResUnknown = ''; if(R3Service.orgServiceResource.serviceResType == serviceResTypeUrl){ R3Service.orgServiceResource.serviceResVerifyUrl = service.verify; }else if(R3Service.orgServiceResource.serviceResType == serviceResTypeObject){ R3Service.orgServiceResource.serviceResStaticObject = normalizeServiceReourceStaticObject(service.verify); }else{ // serviceResTypeUnknown R3Service.orgServiceResource.serviceResUnknown = JSON.stringify(service.verify); } // new state return { dispUnique: dispUnique, service: r3DeepClone(service), serviceResType: R3Service.orgServiceResource.serviceResType, serviceResVerifyUrl: R3Service.orgServiceResource.serviceResVerifyUrl, serviceResStaticObject: R3Service.orgServiceResource.serviceResStaticObject, serviceResUnknown: R3Service.orgServiceResource.serviceResUnknown, serviceResStaticObjPageNum: 0, addTenant: '', changed: false, staticResourceDialog: false, staticResourceObjectPos: -1, staticResourceObject: [], confirmMessageObject: null, messageDialogObject: null, tooltips: { deleteTenantTooltip: -1, // position addTenantTooltip: false, addResStaticObjTooltip: false, nameResStaticObjTooltip: -1, jsonResStaticObjTooltip: -1, delResStaticObjTooltip: -1, editResStaticObjTooltip: -1 } }; } // // Check all state // isChangedState(newResType, newVerify, newTenants) { let is_changed = false; // check verify if(newResType != R3Service.orgServiceResource.serviceResType){ is_changed = true; }else{ if(newResType == serviceResTypeUrl && newVerify != R3Service.orgServiceResource.serviceResVerifyUrl){ is_changed = true; }else if(newResType == serviceResTypeObject){ if(!r3DeepCompare(newVerify, R3Service.orgServiceResource.serviceResStaticObject)){ is_changed = true; } }else if(newResType == serviceResTypeUnknown && newVerify != R3Service.orgServiceResource.serviceResUnknown){ is_changed = true; } } // check tenants if(r3IsSafeTypedEntity(newTenants, 'array')){ if(r3IsEmptyEntity(this.props.service) || !r3IsSafeTypedEntity(this.props.service.tenant, 'array')){ is_changed = true; }else{ if(!r3DeepCompare(this.props.service.tenant, newTenants)){ is_changed = true; } } } return is_changed; } // // Handle Form Button : Save // handleSave(event) // eslint-disable-line no-unused-vars { if(!this.state.changed){ // no change, nothing to do return; } // // Make new service // let newService = r3DeepClone(this.state.service); // // Check and Set service resource value to service // let errorMessage; if(this.state.serviceResType == serviceResTypeUrl){ newService.verify = this.state.serviceResVerifyUrl; errorMessage = this.props.r3provider.getErrorServiceResourceVerify(this.state.serviceResVerifyUrl); }else if(this.state.serviceResType == serviceResTypeObject){ newService.verify = r3DeepClone(this.state.serviceResStaticObject); errorMessage = this.props.r3provider.getErrorServiceResourceVerify(this.state.serviceResStaticObject); }else{ // serviceResTypeUnknown // block to set unknown type after changing resource errorMessage = this.props.r3provider.getR3TextRes().eNewWrongVerifyObject; } if(null != errorMessage){ this.setState({ messageDialogObject: new R3Message(errorMessage, errorType) }); return; } // // Tenant // if(!r3IsSafeTypedEntity(newService.tenant, 'array')){ newService.tenant = []; } // check empty and yrn path by regex let regTenantPath = new RegExp(regYrnAnyTenantPath); let cnt; let cnt2; for(cnt = 0; cnt < newService.tenant.length; ++cnt){ newService.tenant[cnt] = newService.tenant[cnt].trim(); if('*' !== newService.tenant[cnt] && null === newService.tenant[cnt].match(regTenantPath)){ this.setState({ messageDialogObject: new R3Message(this.props.r3provider.getR3TextRes().eNotYRNTenant, errorType) }); return; } } // check same value for(cnt = 0; cnt < newService.tenant.length; ++cnt){ for(cnt2 = (cnt + 1); cnt2 < newService.tenant.length; ++cnt2){ if(newService.tenant[cnt] === newService.tenant[cnt2]){ let tenantYrn = regYrnTenantPathPrefix + this.props.tenant; this.setState({ messageDialogObject: new R3Message((tenantYrn === newService.tenant[cnt] ? this.props.r3provider.getR3TextRes().eTenantOwnerArray : this.props.r3provider.getR3TextRes().eTenantArray), errorType) }); return; } } } // // Check changed // if(!this.isChangedState(this.state.serviceResType, newService.verify, newService.tenant)){ this.setState({ messageDialogObject: new R3Message(this.props.r3provider.getR3TextRes().eNoChange, errorType) }); return; } this.props.onSave(newService); } // // Handle Form Button : Cancel // handleCancel(event) // eslint-disable-line no-unused-vars { if(this.state.changed){ this.setState({ confirmMessageObject: new R3Message(this.props.r3provider.getR3TextRes().cUpdatingCancel) }); } } // // Handle Confirm Dialog : Close( OK / Cancel ) // handleConfirmDialogClose(event, reason, result) { if(result){ // case for 'cancel updating' to do this.props.onUpdate(false); // rewind State this.setState(R3Service.createState(this.props.service, this.props.dispUnique)); }else{ // case for 'cancel updating' to cancel this.setState({ confirmMessageObject: null }); } } // // Handle Message Dialog : Close // handleMessageDialogClose(event, reason, result) // eslint-disable-line no-unused-vars { this.setState({ messageDialogObject: null }); } // // Handle Verify Value : Change // handleVerifyChange(event) { let newValue = r3IsEmptyEntityObject(event.target, 'value') ? null : event.target.value; if(!r3IsSafeTypedEntity(newValue, 'string')){ console.warn('Changed verify new value is wrong.'); return; } if(newValue === this.state.serviceResVerifyUrl){ // nothing to update return; } // set parent changed state let changed = this.isChangedState(this.state.serviceResType, newValue, this.state.service.tenant); this.props.onUpdate(changed); // update state this.setState({ serviceResVerifyUrl: newValue, changed: changed }); } // // Handle Tenants : Change // handleTenantsChange(event, type, pos) { let changedValue = r3IsEmptyEntityObject(event.target, 'value') ? null : event.target.value; let newTenants = []; if(r3IsSafeTypedEntity(this.state.service.tenant, 'array')){ newTenants = r3DeepClone(this.state.service.tenant); } let isClearNewValue = false; if(actionTypeValue === type){ if(r3IsEmptyEntity(pos) || isNaN(pos) || pos < 0 || newTenants.length <= pos){ console.warn('unknown position(' + JSON.stringify(pos) + ') for tenants.'); return; } newTenants[pos] = changedValue.trim(); }else if(actionTypeDelete === type){ if(r3IsEmptyEntity(pos) || isNaN(pos) || pos < 0 || newTenants.length <= pos){ console.warn('unknown position(' + JSON.stringify(pos) + ') for tenants.'); return; } newTenants.splice(pos, 1); }else if(actionTypeAdd === type){ if(r3IsEmptyString(this.state.addTenant, true)){ this.setState({ messageDialogObject: new R3Message(this.props.r3provider.getR3TextRes().eNewTenant, errorType) }); return; } newTenants.push(this.state.addTenant.trim()); isClearNewValue = true; }else{ console.warn('unknown action(' + JSON.stringify(type) + ') for tenants.'); return; } // make new resource object let newService = r3DeepClone(this.state.service); newService.tenant = newTenants; // set parent changed state let nowVerify; if(this.state.serviceResType == serviceResTypeUrl){ nowVerify = this.state.serviceResVerifyUrl; }else if(this.state.serviceResType == serviceResTypeObject){ nowVerify = this.state.serviceResStaticObject; }else{ // serviceResTypeUnknown nowVerify = this.state.serviceResUnknown; } let changed = this.isChangedState(this.state.serviceResType, nowVerify, newTenants); this.props.onUpdate(changed); // update state this.setState({ service: newService, changed: changed, addTenant: (isClearNewValue ? '' : this.state.addTenant) }); } // // Handle Add New Tenant : Change // handleAddTenantsChange(event) { // update state this.setState({ addTenant: event.target.value }); } handTooltipChange = (event, type, extData) => { if(tooltipValues.deleteTenantTooltip === type){ this.setState({ tooltips: { deleteTenantTooltip: extData } }); }else if(tooltipValues.addTenantTooltip === type){ this.setState({ tooltips: { addTenantTooltip: extData } }); }else if(tooltipValues.nameResStaticObjTooltip === type){ this.setState({ tooltips: { nameResStaticObjTooltip: extData } }); }else if(tooltipValues.jsonResStaticObjTooltip === type){ this.setState({ tooltips: { jsonResStaticObjTooltip: extData } }); }else if(tooltipValues.addResStaticObjTooltip === type){ this.setState({ tooltips: { addResStaticObjTooltip: extData } }); }else if(tooltipValues.delResStaticObjTooltip === type){ this.setState({ tooltips: { delResStaticObjTooltip: extData } }); }else if(tooltipValues.editResStaticObjTooltip === type){ this.setState({ tooltips: { editResStaticObjTooltip: extData } }); } }; getTenantsContents(items) { const { theme, r3provider } = this.props; if(!r3IsSafeTypedEntity(items, 'array')){ return; } let tenantYrn = regYrnTenantPathPrefix + this.props.tenant; return items.map( (item, pos) => { if(r3CompareCaseString(tenantYrn, item)){ // item is owner tenant, this value could not change. return; } let deleteButton = ( <Tooltip title={ r3provider.getR3TextRes().tResServiceTenantDelTT } open={ ((r3IsEmptyEntityObject(this.state, 'tooltips') || !r3IsSafeTypedEntity(this.state.tooltips.deleteTenantTooltip, 'number') || (this.state.tooltips.deleteTenantTooltip != pos)) ? false : true) } > <IconButton onClick={ (event) => this.handleTenantsChange(event, actionTypeDelete, pos) } onMouseEnter={ (event) => this.handTooltipChange(event, tooltipValues.deleteTenantTooltip, pos) } onMouseLeave={ (event) => this.handTooltipChange(event, tooltipValues.deleteTenantTooltip, -1) } { ...theme.r3Service.deleteTenantButton } sx={ this.sxClasses.deleteTenantButton } size="large" > <DeleteIcon /> </IconButton> </Tooltip> ); return ( <Box key={ pos } sx={ this.sxClasses.enclosureElement } > <TextField name={ serviceComponentValues.tenantTextFieldNamePrefix + String(pos) } value={ item } placeholder={ r3provider.getR3TextRes().tResServiceTenantHint } onChange={ (event) => this.handleTenantsChange(event, actionTypeValue, pos) } slotProps ={{ input: { sx: this.sxClasses.inputTextField } }} { ...theme.r3Service.tenantTextField } sx={ this.sxClasses.tenantTextField } /> { deleteButton } </Box> ); }); } getAddTenantsContents() { const { theme, r3provider } = this.props; return ( <Box sx={ this.sxClasses.enclosureElement } > <TextField name={ serviceComponentValues.tenantNewTextFieldName } value={ this.state.addTenant } placeholder={ r3provider.getR3TextRes().tResServiceTenantHint } onChange={ (event) => this.handleAddTenantsChange(event) } slotProps ={{ input: { sx: this.sxClasses.inputTextField } }} { ...theme.r3Service.tenantTextField } sx={ this.sxClasses.tenantTextField } /> <Tooltip title={ r3provider.getR3TextRes().tResServiceTenantAddTT } open={ ((r3IsEmptyEntityObject(this.state, 'tooltips') || !r3IsSafeTypedEntity(this.state.tooltips.addTenantTooltip, 'boolean')) ? false : this.state.tooltips.addTenantTooltip) } > <IconButton onClick={ (event) => this.handleTenantsChange(event, actionTypeAdd, 0) } onMouseEnter={ (event) => this.handTooltipChange(event, tooltipValues.addTenantTooltip, true) } onMouseLeave={ (event) => this.handTooltipChange(event, tooltipValues.addTenantTooltip, false) } { ...theme.r3Service.addTenantButton } sx={ this.sxClasses.addTenantButton } size="large" > <AddIcon /> </IconButton> </Tooltip> </Box> ); } // // Handle Service resource type : Change // handleResourceTypeChange(event, type) { if(this.state.serviceResType === type){ console.warn('changed value type(' + JSON.stringify(type) + ') is something wrong.'); return; } let newResType = type; let newVerify; if(newResType == serviceResTypeUrl){ newVerify = this.state.serviceResVerifyUrl; }else if(newResType == serviceResTypeObject){ newVerify = this.state.serviceResStaticObject; }else{ // serviceResTypeUnknown newVerify = this.state.serviceResUnknown; } // set parent changed state let changed = this.isChangedState(newResType, newVerify, this.state.service.tenant); this.props.onUpdate(changed); // update state this.setState({ serviceResType: newResType, changed: changed }); } // // Handle Add new static resource // handleNewStaticResourceObj(event) // eslint-disable-line no-unused-vars { // update state this.setState({ staticResourceDialog: true, staticResourceObjectPos: -1, staticResourceObject: [] }); } // // Handle Delete static resource // handleDelStaticResourceObj(event, pos) { if(!r3IsSafeTypedEntity(this.state.serviceResStaticObject, 'array')){ return; } if(this.state.serviceResStaticObject.length <= pos){ return; } // remove resouce let newStaticRes = this.state.serviceResStaticObject.filter( (item, itemPos) => itemPos !== pos); // set parent changed state let changed = this.isChangedState(this.state.serviceResType, newStaticRes, this.state.service.tenant); this.props.onUpdate(changed); // update state this.setState({ serviceResStaticObject: newStaticRes, changed: changed }); } // // Handle Edit static resource // handleEditStaticResourceObj(event, pos) { if(!r3IsSafeTypedEntity(this.state.serviceResStaticObject, 'array')){ return; } if(this.state.serviceResStaticObject.length <= pos){ return; } let oneStaticRes = r3DeepClone(this.state.serviceResStaticObject[pos]); // add data type if(r3IsEmptyString(oneStaticRes.data)){ // data is empty(string or not) -> type: string oneStaticRes.type = 'string'; oneStaticRes.editingObjectData = ''; oneStaticRes.editingStringData = ''; }else if(r3IsJSON(oneStaticRes.data)){ let tempobj = r3ConvertFromJSON(oneStaticRes.data); if(r3IsSafeTypedEntity(tempobj, 'string')){ // data is JSON formatted, but it is string -> type: string oneStaticRes.type = 'string'; oneStaticRes.editingObjectData = ''; oneStaticRes.editingStringData = tempobj; }else if(r3IsSafeTypedEntity(tempobj, 'number')){ // data is JSON formatted, but it is number -> type: string oneStaticRes.type = 'string'; oneStaticRes.editingObjectData = ''; oneStaticRes.editingStringData = String(tempobj); }else{ // data is JSON formatted -> type: object oneStaticRes.type = 'object'; oneStaticRes.editingObjectData = oneStaticRes.data; oneStaticRes.editingStringData = ''; } }else if(r3IsSafeTypedEntity(oneStaticRes.data, 'string')){ // data is string -> type: string oneStaticRes.type = 'string'; oneStaticRes.editingObjectData = ''; oneStaticRes.editingStringData = oneStaticRes.data; }else{ // data is other -> type: string oneStaticRes.type = 'string'; oneStaticRes.editingObjectData = ''; oneStaticRes.editingStringData = JSON.stringify(oneStaticRes.data); } // update state this.setState({ staticResourceDialog: true, staticResourceObjectPos: pos, staticResourceObject: [ oneStaticRes ] }); } // // Handle Close static resource dialog // handleCloseStaticResourceDialog(event, reason, isAgree, newOneStaticRes) { if(!isAgree){ this.setState({ staticResourceDialog: false, staticResourceObjectPos: -1, staticResourceObject: [] }); return; } // add/edit new static resource let newStaticRes = r3DeepClone(this.state.serviceResStaticObject); if(0 <= this.state.staticResourceObjectPos && this.state.staticResourceObjectPos < newStaticRes.length){ newStaticRes[this.state.staticResourceObjectPos] = newOneStaticRes; }else{ newStaticRes.push(newOneStaticRes); } // set parent changed state let changed = this.isChangedState(this.state.serviceResType, newStaticRes, this.state.service.tenant); this.props.onUpdate(changed); // update state this.setState({ serviceResStaticObject: newStaticRes, changed: changed, staticResourceDialog: false, staticResourceObjectPos: -1, staticResourceObject: [] }); } // // Handle Check conflict static resource name // handleCheckStaticResourceName(staticResName) { for(let cnt = 0; cnt < this.state.serviceResStaticObject.length; ++cnt){ if(cnt == this.state.staticResourceObjectPos){ continue; } if(this.state.serviceResStaticObject[cnt].name == staticResName){ return false; } } return true; } // // Handle Static resource object page : Change // handleResStaticObjPageChange(event, page) { this.setState({ serviceResStaticObjPageNum: page }); } // // Render: Resource - Verify URL // renderServiceResourceVerifyUrl() { const { theme, r3provider } = this.props; return ( <TextField name={ serviceComponentValues.verifyUrlResourceName } value={ this.state.serviceResVerifyUrl } placeholder={ r3provider.getR3TextRes().tResServiceUrlResHint } onChange={ (event) => this.handleVerifyChange(event) } slotProps ={{ input: { sx: this.sxClasses.inputTextField } }} { ...theme.r3Service.resourceTextField } sx={ this.sxClasses.resourceTextField } /> ); } // // Render: Resource - Static resource object // getResStaticObjTableHead() { const { theme, r3provider } = this.props; return ( <TableHead sx={ this.sxClasses.tableHead } > <TableRow> <TableCell sx={ this.sxClasses.tableCell } > <Typography { ...theme.r3Service.textTableHead } sx={ this.sxClasses.textTableHead } > { r3provider.getR3TextRes().tResServiceNameTableHead } </Typography> </TableCell> <TableCell sx={ this.sxClasses.tableCell } > <Typography { ...theme.r3Service.textTableHead } sx={ this.sxClasses.textTableHead } > { r3provider.getR3TextRes().tResServiceJsonTableHead } </Typography> </TableCell> <TableCell sx={ this.sxClasses.tableCell } > <Tooltip title={ r3provider.getR3TextRes().tResServiceAddStaticResTT } open={ ((r3IsEmptyEntityObject(this.state, 'tooltips') || !r3IsSafeTypedEntity(this.state.tooltips.addResStaticObjTooltip, 'boolean')) ? false : this.state.tooltips.addResStaticObjTooltip) } > <IconButton onClick={ this.handleNewStaticResourceObj } onMouseEnter={ (event) => this.handTooltipChange(event, tooltipValues.addResStaticObjTooltip, true) } onMouseLeave={ (event) => this.handTooltipChange(event, tooltipValues.addResStaticObjTooltip, false) } { ...theme.r3Service.addResStaticObjButton } sx={ this.sxClasses.addResStaticObjButton } size="large" > <AddIcon /> </IconButton> </Tooltip> </TableCell> </TableRow> </TableHead> ); } getResStaticObjTableBody() { const { theme, r3provider } = this.props; if(!r3IsSafeTypedEntity(this.state.serviceResStaticObject, 'array')){ return; } let resources = this.state.serviceResStaticObject; return ( <TableBody> {resources.map( (item, pos) => { if(pos < (this.state.serviceResStaticObjPageNum * this.props.tableRawCount) || ((this.state.serviceResStaticObjPageNum + 1) * this.props.tableRawCount) <= pos){ return; } let orgName = item.name; let stripName = orgName; if(13 < stripName.length){ stripName = stripName.slice(0, 10) + '...'; } let orgJson = JSON.stringify(item); let stripJson = orgJson; if(53 < stripJson.length){ stripJson = stripJson.slice(0, 50) + '...'; } return ( <TableRow hover={ false } key={ pos } selected={ false } > <TableCell sx={ this.sxClasses.tableCell } > <Tooltip title={ orgName } open={ ((r3IsEmptyEntityObject(this.state, 'tooltips') || !r3IsSafeTypedEntity(this.state.tooltips.nameResStaticObjTooltip, 'number') || (this.state.tooltips.nameResStaticObjTooltip != pos)) ? false : true) } > <Typography onMouseEnter={ (event) => this.handTooltipChange(event, tooltipValues.nameResStaticObjTooltip, pos) } onMouseLeave={ (event) => this.handTooltipChange(event, tooltipValues.nameResStaticObjTooltip, -1) } { ...theme.r3Service.textTableContent } sx={ this.sxClasses.textTableContent } > { stripName } </Typography> </Tooltip> </TableCell> <TableCell sx={ this.sxClasses.tableCell } > <Tooltip title={ orgJson } open={ ((r3IsEmptyEntityObject(this.state, 'tooltips') || !r3IsSafeTypedEntity(this.state.tooltips.jsonResStaticObjTooltip, 'number') || (this.state.tooltips.jsonResStaticObjTooltip != pos)) ? false : true) } > <Typography onMouseEnter={ (event) => this.handTooltipChange(event, tooltipValues.jsonResStaticObjTooltip, pos) } onMouseLeave={ (event) => this.handTooltipChange(event, tooltipValues.jsonResStaticObjTooltip, -1) } { ...theme.r3Service.textTableContent } sx={ this.sxClasses.textTableContent } > { stripJson } </Typography> </Tooltip> </TableCell> <TableCell sx={ this.sxClasses.tableCell } > <Tooltip title={ r3provider.getR3TextRes().tResServiceDelStaticResTT } open={ ((r3IsEmptyEntityObject(this.state, 'tooltips') || !r3IsSafeTypedEntity(this.state.tooltips.delResStaticObjTooltip, 'number') || (this.state.tooltips.delResStaticObjTooltip != pos)) ? false : true) } > <IconButton onClick={ (event) => this.handleDelStaticResourceObj(event, pos) } onMouseEnter={ (event) => this.handTooltipChange(event, tooltipValues.delResStaticObjTooltip, pos) } onMouseLeave={ (event) => this.handTooltipChange(event, tooltipValues.delResStaticObjTooltip, -1) } { ...theme.r3Service.delResStaticObjButton } sx={ this.sxClasses.delResStaticObjButton } size="large" > <DeleteIcon /> </IconButton> </Tooltip> <Tooltip title={ r3provider.getR3TextRes().tResServiceEditStaticResTT } open={ ((r3IsEmptyEntityObject(this.state, 'tooltips') || !r3IsSafeTypedEntity(this.state.tooltips.editResStaticObjTooltip, 'number') || (this.state.tooltips.editResStaticObjTooltip != pos)) ? false : true) } > <IconButton onClick={ (event) => this.handleEditStaticResourceObj(event, pos) } onMouseEnter={ (event) => this.handTooltipChange(event, tooltipValues.editResStaticObjTooltip, pos) } onMouseLeave={ (event) => this.handTooltipChange(event, tooltipValues.editResStaticObjTooltip, -1) } { ...theme.r3Service.editResStaticObjButton } sx={ this.sxClasses.editResStaticObjButton } size="large" > <EditIcon /> </IconButton> </Tooltip> </TableCell> </TableRow> ); })} </TableBody> ); } renderServiceResourceStaticObj() { const { theme, r3provider } = this.props; if(!r3IsSafeTypedEntity(this.state.serviceResStaticObject, 'array')){ return; } let tablehead = this.getResStaticObjTableHead(); let tablebody = this.getResStaticObjTableBody(); let textValue = JSON.stringify(this.state.serviceResStaticObject); return ( <Box sx={ this.sxClasses.tableBox } > <Table { ...theme.r3Service.table } sx={ this.sxClasses.table } > { tablehead } { tablebody } </Table> <TablePagination component={ 'div' } count={ this.state.serviceResStaticObject.length } rowsPerPage={ this.props.tableRawCount } page={ this.state.serviceResStaticObjPageNum } rowsPerPageOptions={ [] } onPageChange={ (event) => this.handleResStaticObjPageChange(event) } /> <TextField name={ serviceComponentValues.resStaticObjTextFieldName } value={ textValue } disabled={ true } placeholder={ r3provider.getR3TextRes().tResServiceStaticObjHint } slotProps ={{ input: { sx: this.sxClasses.inputTextField } }} { ...theme.r3Service.resourceTextField } sx={ this.sxClasses.staticResourceTextField } /> </Box> ); } // // Render: Resource - Unknown // renderServiceResourceUnknown() { const { theme, r3provider } = this.props; return ( <React.Fragment> <Typography { ...theme.r3Service.unknownMessage } sx={ this.sxClasses.unknownMessage } > { r3provider.getR3TextRes().tResServiceUnknownType } </Typography> <TextField name={ serviceComponentValues.resUnknownTextFieldName } value={ this.state.serviceResUnknown } disabled={ true } slotProps ={{ input: { sx: this.sxClasses.inputTextField } }} { ...theme.r3Service.resourceTextField } sx={ this.sxClasses.resourceTextField } /> </React.Fragment> ); } // // Render: Resource all // renderServiceResourceGroup() { const { theme, r3provider } = this.props; let leftTypeSelectLabel = ( <Typography { ...theme.r3Resource.valueFormControlLabel } > { r3provider.getR3TextRes().tResServiceResTypeUrl } </Typography> ); let rightTypeSelectLabel = ( <Typography { ...theme.r3Resource.valueFormControlLabel } > { r3provider.getR3TextRes().tResServiceResTypeStatic } </Typography> ); let radioValue; let serviceResource; if(serviceResTypeUrl == this.state.serviceResType){ radioValue = serviceResTypeUrl; serviceResource = this.renderServiceResourceVerifyUrl(); }else if(serviceResTypeObject == this.state.serviceResType){ radioValue = serviceResTypeObject; serviceResource = this.renderServiceResourceStaticObj(); }else{ // unknown radioValue = serviceResTypeUnknown; serviceResource = this.renderServiceResourceUnknown(); } return ( <React.Fragment> <RadioGroup name={ serviceComponentValues.serviceResourceTypeName } value={ radioValue } onChange={ (event) => this.handleResourceTypeChange(event) } { ...theme.r3Service.valueRadioGroup } sx={ this.sxClasses.valueRadioGroup } > <FormControlLabel value={ serviceResTypeUrl } label={ leftTypeSelectLabel } disabled={ false } control={ <Radio /> } { ...theme.r3Service.valueLeftFormControlLabel } sx={ this.sxClasses.valueLeftFormControlLabel } /> <FormControlLabel value={ serviceResTypeObject } label={ rightTypeSelectLabel } disabled={ false } control={ <Radio /> } { ...theme.r3Service.valueRightFormControlLabel } sx={ this.sxClasses.valueRightFormControlLabel } /> </RadioGroup> { serviceResource } </React.Fragment> ); } // // Render: main // render() { console.log('CALL: service::render()'); const { theme, r3provider } = this.props; let serviceResourceGroup = this.renderServiceResourceGroup(); return ( <Box sx={ this.sxClasses.root } > <Typography { ...theme.r3Service.subTitle } sx={ this.sxClasses.subTitleTop } > { r3provider.getR3TextRes().tResServiceUrlResSubTitle } </Typography> { serviceResourceGroup } <Typography { ...theme.r3Service.subTitle } sx={ this.sxClasses.subTitle } > { r3provider.getR3TextRes().tResServiceTenantsSubTitle } </Typography> { this.getTenantsContents(this.state.service.tenant) } { this.getAddTenantsContents() } <R3FormButtons theme={ theme } r3provider={ this.props.r3provider } status={ this.state.changed } onSave={ (event) => this.handleSave(event) } onCancel={ (event) => this.handleCancel(event) } /> <R3CreateServiceDialog theme={ theme } r3provider={ this.props.r3provider } open={ this.state.staticResourceDialog } createMode={ false } newStaticRes={ this.state.staticResourceObject } onCheckConflictName={ this.handleCheckStaticResourceName } onClose={ this.handleCloseStaticResourceDialog } /> <R3PopupMsgDialog theme={ theme } r3provider={ this.props.r3provider } title={ this.props.r3provider.getR3TextRes().cUpdatingTitle } r3Message={ this.state.confirmMessageObject } twoButton={ true } onClose={ this.handleConfirmDialogClose } /> <R3PopupMsgDialog theme={ theme } r3provider={ this.props.r3provider } r3Message={ this.state.messageDialogObject } onClose={ this.handleMessageDialogClose } /> </Box> ); } } /* * 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 */