summaryrefslogtreecommitdiffstats
path: root/openecomp-ui/src/sdc-app/onboarding/licenseModel/licenseKeyGroups/LicenseKeyGroupsEditorView.jsx
blob: b53ce8f0a9cc403875977a3d724ed70f64ea9a76 (plain)
1
2
3
4
5
6
7

@media only all and (prefers-color-scheme: dark) {
.highlight .hll { background-color: #49483e }
.highlight .c { color: #75715e } /* Comment */
.highlight .err { color: #960050; background-color: #1e0010 } /* Error */
.highlight .k { color: #66d9ef } /* Keyword */
.highlight .l { color: #ae81ff } /* Literal */
.highlight .n { color: #f8f8f2 } /* Name */
.highlight .o { color: #f92672 } /* Operator */
.highlight .p { color: #f8f8f2 } /* Punctuation */
.highlight .ch { color: #75715e } /* Comment.Hashbang */
.highlight .cm { color: #75715e } /* Comment.Multiline */
.highlight .cp { color: #75715e } /* Comment.Preproc */
.highlight .cpf { color: #75715e } /* Comment.PreprocFile */
.highlight .c1 { color: #75715e } /* Comment.Single */
.highlight .cs { color: #75715e } /* Comment.Special */
.highlight .gd { color: #f92672 } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gi { color: #a6e22e } /* Generic.Inserted */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #75715e } /* Generic.Subheading */
.highlight .kc { color: #66d9ef } /* Keyword.Constant */
.highlight .kd { color: #66d9ef } /* Keyword.Declaration */
.highlight .kn { color: #f92672 } /* Keyword.Namespace */
.highlight .kp { color: #66d9ef } /* Keyword.Pseudo */
.highlight .kr { color: #66d9ef } /* Keyword.Reserved */
.highlight .kt { color: #66d9ef } /* Keyword.Type */
.highlight .ld { color: #e6db74 } /* Literal.Date */
.highlight .m { color: #ae81ff } /* Literal.Number */
.highlight .s { color: #e6db74 } /* Literal.String */
.highlight .na { color: #a6e22e } /* Name.Attribute */
.highlight .nb { color: #f8f8f2 } /* Name.Builtin */
.highlight .nc { color: #a6e22e } /* Name.Class */
.highlight .no { color: #66d9ef } /* Name.Constant */
.highlight .nd { color: #a6e22e } /* Name.Decorator */
.highlight .ni { color: #f8f8f2 } /* Name.Entity */
.highlight .ne { color: #a6e22e } /* Name.Exception */
.highlight .nf { color: #a6e22e } /* Name.Function */
.highlight .nl { color: #f8f8f2 } /* Name.Label */
.highlight .nn { color: #f8f8f2 } /* Name.Namespace */
.highlight .nx { color: #a6e22e } /* Name.Other */
.highlight .py { color: #f8f8f2 } /* Name.Property */
.highlight .nt { color: #f92672 } /* Name.Tag */
.highlight .nv { color: #f8f8f2 } /* Name.Variable */
.highlight .ow { color: #f92672 } /* Operator.Word */
.highlight .w { color: #f8f8f2 } /* Text.Whitespace */
.highlight .mb { color: #ae81ff } /* Literal.Number.Bin */
.highlight .mf { color: #ae81ff } /* Literal.Number.Float */
.highlight .mh { color: #ae81ff } /* Literal.Number.Hex */
.highlight .mi { color: #ae81ff } /* Literal.Number.Integer */
.highlight .mo { color: #ae81ff } /* Literal.Number.Oct */
.highlight .sa { color: #e6db74 } /* Literal.String.Affix */
.highlight .sb { color: #e6db74 } /* Literal.String.Backtick */
.highlight .sc { color: #e6db74 } /* Literal.String.Char */
.highlight .dl { color: #e6db74 } /* Literal.String.Delimiter */
.highlight .sd { color: #e6db74 } /* Literal.String.Doc */
.highlight .s2 { color: #e6db74 } /* Literal.String.Double */
.highlight .se { color: #ae81ff } /* Literal.String.Escape */
.highlight .sh { color: #e6db74 } /* Literal.String.Heredoc */
.highlight .si { color: #e6db74 } /* Literal.String.Interpol */
.highlight .sx { color: #e6db74 } /* Literal.String.Other */
.highlight .sr { color: #e6db74 } /* Literal.String.Regex */
.highlight .s1 { color: #e6db74 } /* Literal.String.Single */
.highlight .ss { color: #e6db74 } /* Literal.String.Symbol */
.highlight .bp { color: #f8f8f2 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #a6e22e } /* Name.Function.Magic */
.highlight .vc { color: #f8f8f2 } /* Name.Variable.Class */
.highlight .vg { color: #f8f8f2 } /* Name.Variable.Global */
.highlight .vi { color: #f8f8f2 } /* Name.Variable.Instance */
.highlight .vm { color: #f8f8f2 } /* Name.Variable.Magic */
.highlight .il { color: #ae81ff } /* Literal.Number.Integer.Long */
}
@media (prefers-color-scheme: light) {
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #888888 } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { color: #008800; font-weight: bold } /* Keyword */
.highlight .ch { color: #888888 } /* Comment.Hashbang */
.highlight .cm { color: #888888 } /* Comment.Multiline */
.highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.highlight .cpf { color: #888888 } /* Comment.PreprocFile */
.highlight .c1 { color: #888888 } /* Comment.Single */
.highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #333333 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #666666 } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008800 } /* Keyword.Pseudo */
.highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */
.highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.highlight .na { color: #336699 } /* Name.Attribute */
.highlight .nb { color: #003388 } /* Name.Builtin */
.highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */
.highlight .no { color: #003366; font-weight: bold } /* Name.Constant */
.highlight .nd { color: #555555 } /* Name.Decorator */
.highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */
.highlight .nl { color: #336699; font-style: italic } /* Name.Label */
.highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.highlight .py { color: #336699; font-weight: bold } /* Name.Property */
.highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #336699 } /* Name.Variable */
.highlight .ow { color: #008800 } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */
.highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */
.highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */
.highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */
.highlight .vc { color: #336699 } /* Name.Variable.Class */
.highlight .vg { color: #dd7700 } /* Name.Variable.Global */
.highlight .vi { color: #3333bb } /* Name.Variable.Instance */
.highlight .vm { color: #336699 } /* Name.Variable.Magic */
.highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
}
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.onap.ccsdk.parent</groupId>
        <artifactId>single-feature-parent</artifactId>
        <version>1.5.0</version>
        <relativePath/>
    </parent>

    <groupId>org.onap.ccsdk.sli.plugins</groupId>
    <artifactId>ccsdk-sshapi-call-node</artifactId>
    <version>0.7.0-SNAPSHOT</version>
    <packaging>feature</packaging>

    <name>ccsdk-sli-plugins :: sshapi-call-node :: ${project.artifactId}</name>



<!--
    <properties>
        <ccsdk.sli.core.version>${project.version}</ccsdk.sli.core.version>
    </properties>

    <dependencies>

        <dependency>
            <groupId>org.onap.ccsdk.sli.core</groupId>
            <artifactId>ccsdk-sli</artifactId>
            <version>${ccsdk.sli.core.version}</version>
            <type>xml</type>
            <classifier>features</classifier>
        </dependency>
        <dependency>
            <groupId>${project.groupId}</groupId>
            <artifactId>sshapi-call-node-provider</artifactId>
            <version>${project.version}</version>
        </dependency>
    </dependencies>
    -->
</project>
7' href='#n427'>427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523
/*!
 * Copyright © 2016-2018 European Support Limited
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */
import React from 'react';
import PropTypes from 'prop-types';
import i18n from 'nfvo-utils/i18n/i18n.js';
import Validator from 'nfvo-utils/Validator.js';

import Tabs from 'sdc-ui/lib/react/Tabs.js';
import Tab from 'sdc-ui/lib/react/Tab.js';

import Button from 'sdc-ui/lib/react/Button.js';
import Form from 'nfvo-components/input/validation/Form.jsx';
import Input from 'nfvo-components/input/validation/Input.jsx';
import GridSection from 'nfvo-components/grid/GridSection.jsx';
import GridItem from 'nfvo-components/grid/GridItem.jsx';
import {
    optionsInputValues as licenseKeyGroupOptionsInputValues,
    LKG_FORM_NAME,
    tabIds
} from './LicenseKeyGroupsConstants.js';
import { optionsInputValues as LicenseModelOptionsInputValues } from '../LicenseModelConstants.js';
import {
    validateStartDate,
    thresholdValueValidation
} from '../LicenseModelValidations.js';
import { other as optionInputOther } from 'nfvo-components/input/validation/InputOptions.jsx';
import InputOptions from 'nfvo-components/input/validation/InputOptions.jsx';

import { DATE_FORMAT } from 'sdc-app/onboarding/OnboardingConstants.js';

import LicenseKeyGroupsLimits from './LicenseKeyGroupsLimits.js';
import {
    limitType,
    NEW_LIMIT_TEMP_ID
} from '../limits/LimitEditorConstants.js';

const LicenseKeyGroupPropType = PropTypes.shape({
    id: PropTypes.string,
    name: PropTypes.string,
    description: PropTypes.string,
    increments: PropTypes.string,
    operationalScope: PropTypes.shape({
        choices: PropTypes.array,
        other: PropTypes.string
    }),
    type: PropTypes.string,
    thresholdUnits: PropTypes.string,
    thresholdValue: PropTypes.number,
    startDate: PropTypes.string,
    expiryDate: PropTypes.string
});

const LicenseKeyGroupFormContent = ({
    data,
    onDataChanged,
    genericFieldInfo,
    validateName,
    validateStartDate,
    thresholdValueValidation
}) => {
    let {
        name,
        description,
        increments,
        operationalScope,
        type,
        thresholdUnits,
        thresholdValue,
        startDate,
        expiryDate
    } = data;
    return (
        <GridSection hasLostColSet>
            <GridItem colSpan={2}>
                <Input
                    onChange={name =>
                        onDataChanged({ name }, LKG_FORM_NAME, {
                            name: validateName
                        })
                    }
                    label={i18n('Name')}
                    data-test-id="create-lkg-name"
                    value={name}
                    isValid={genericFieldInfo.name.isValid}
                    errorText={genericFieldInfo.name.errorText}
                    isRequired={true}
                    type="text"
                />
            </GridItem>
            <GridItem colSpan={2} lastColInRow>
                <InputOptions
                    onInputChange={() => {}}
                    isMultiSelect={true}
                    onEnumChange={operationalScope =>
                        onDataChanged(
                            {
                                operationalScope: {
                                    choices: operationalScope,
                                    other: ''
                                }
                            },
                            LKG_FORM_NAME
                        )
                    }
                    onOtherChange={operationalScope =>
                        onDataChanged(
                            {
                                operationalScope: {
                                    choices: [optionInputOther.OTHER],
                                    other: operationalScope
                                }
                            },
                            LKG_FORM_NAME
                        )
                    }
                    label={i18n('Operational Scope')}
                    data-test-id="create-lkg-operational-scope"
                    type="select"
                    multiSelectedEnum={
                        operationalScope && operationalScope.choices
                    }
                    otherValue={operationalScope && operationalScope.other}
                    values={licenseKeyGroupOptionsInputValues.OPERATIONAL_SCOPE}
                    isValid={genericFieldInfo.operationalScope.isValid}
                    errorText={genericFieldInfo.operationalScope.errorText}
                />
            </GridItem>
            <GridItem colSpan={2}>
                <Input
                    onChange={description =>
                        onDataChanged({ description }, LKG_FORM_NAME)
                    }
                    label={i18n('Description')}
                    data-test-id="create-lkg-description"
                    value={description}
                    isValid={genericFieldInfo.description.isValid}
                    errorText={genericFieldInfo.description.errorText}
                    type="textarea"
                    overlayPos="bottom"
                />
            </GridItem>
            <GridItem colSpan={2} lastColInRow>
                <Input
                    isRequired={true}
                    onChange={e => {
                        const selectedIndex = e.target.selectedIndex;
                        const val = e.target.options[selectedIndex].value;
                        onDataChanged({ type: val }, LKG_FORM_NAME);
                    }}
                    value={type}
                    label={i18n('Type')}
                    data-test-id="create-lkg-type"
                    isValid={genericFieldInfo.type.isValid}
                    errorText={genericFieldInfo.type.errorText}
                    groupClassName="bootstrap-input-options"
                    className="input-options-select"
                    overlayPos="bottom"
                    type="select">
                    {licenseKeyGroupOptionsInputValues.TYPE.map(type => (
                        <option key={type.enum} value={type.enum}>
                            {type.title}
                        </option>
                    ))}
                </Input>
            </GridItem>
            <GridItem>
                <Input
                    onChange={e => {
                        // setting the unit to the correct value
                        const selectedIndex = e.target.selectedIndex;
                        const val = e.target.options[selectedIndex].value;
                        onDataChanged({ thresholdUnits: val }, LKG_FORM_NAME);
                        // TODO make sure that the value is valid too
                        onDataChanged(
                            { thresholdValue: thresholdValue },
                            LKG_FORM_NAME,
                            {
                                thresholdValue: thresholdValueValidation
                            }
                        );
                    }}
                    value={thresholdUnits}
                    label={i18n('Threshold Units')}
                    data-test-id="create-ep-threshold-units"
                    isValid={genericFieldInfo.thresholdUnits.isValid}
                    errorText={genericFieldInfo.thresholdUnits.errorText}
                    groupClassName="bootstrap-input-options"
                    className="input-options-select"
                    type="select">
                    {LicenseModelOptionsInputValues.THRESHOLD_UNITS.map(
                        mtype => (
                            <option key={mtype.enum} value={mtype.enum}>{`${
                                mtype.title
                            }`}</option>
                        )
                    )}
                </Input>
            </GridItem>
            <GridItem>
                <Input
                    className="entitlement-pools-form-row-threshold-value"
                    onChange={thresholdValue =>
                        onDataChanged({ thresholdValue }, LKG_FORM_NAME, {
                            thresholdValue: thresholdValueValidation
                        })
                    }
                    label={i18n('Threshold Value')}
                    isValid={genericFieldInfo.thresholdValue.isValid}
                    errorText={genericFieldInfo.thresholdValue.errorText}
                    data-test-id="create-ep-threshold-value"
                    value={thresholdValue}
                    type="text"
                />
            </GridItem>
            <GridItem>
                <Input
                    type="date"
                    label={i18n('Start Date')}
                    value={startDate}
                    dateFormat={DATE_FORMAT}
                    startDate={startDate}
                    endDate={expiryDate}
                    onChange={startDate =>
                        onDataChanged(
                            {
                                startDate: startDate
                                    ? startDate.format(DATE_FORMAT)
                                    : ''
                            },
                            LKG_FORM_NAME,
                            { startDate: validateStartDate }
                        )
                    }
                    isValid={genericFieldInfo.startDate.isValid}
                    errorText={genericFieldInfo.startDate.errorText}
                    selectsStart
                />
            </GridItem>
            <GridItem lastColInRow>
                <Input
                    type="date"
                    label={i18n('Expiry Date')}
                    value={expiryDate}
                    dateFormat={DATE_FORMAT}
                    startDate={startDate}
                    endDate={expiryDate}
                    onChange={expiryDate => {
                        onDataChanged(
                            {
                                expiryDate: expiryDate
                                    ? expiryDate.format(DATE_FORMAT)
                                    : ''
                            },
                            LKG_FORM_NAME
                        );
                        onDataChanged({ startDate }, LKG_FORM_NAME, {
                            startDate: validateStartDate
                        });
                    }}
                    isValid={genericFieldInfo.expiryDate.isValid}
                    errorText={genericFieldInfo.expiryDate.errorText}
                    selectsEnd
                />
            </GridItem>
            <GridItem colSpan={2}>
                <Input
                    onChange={increments =>
                        onDataChanged({ increments }, LKG_FORM_NAME)
                    }
                    label={i18n('Increments')}
                    value={increments}
                    data-test-id="create-ep-increments"
                    type="text"
                />
            </GridItem>
        </GridSection>
    );
};

class LicenseKeyGroupsEditorView extends React.Component {
    static propTypes = {
        data: LicenseKeyGroupPropType,
        previousData: LicenseKeyGroupPropType,
        LKGNames: PropTypes.object,
        isReadOnlyMode: PropTypes.bool,
        onDataChanged: PropTypes.func.isRequired,
        onSubmit: PropTypes.func.isRequired,
        onCancel: PropTypes.func.isRequired
    };

    static defaultProps = {
        data: {}
    };

    componentDidUpdate(prevProps) {
        if (
            this.props.formReady &&
            this.props.formReady !== prevProps.formReady
        ) {
            // if form validation succeeded -> continue with submit
            this.submit();
        }
    }

    state = {
        localFeatureGroupsListFilter: '',
        selectedTab: tabIds.GENERAL,
        selectedLimit: ''
    };

    render() {
        let {
            data = {},
            onDataChanged,
            isReadOnlyMode,
            onCloseLimitEditor,
            genericFieldInfo,
            limitsList = []
        } = this.props;
        let { selectedTab } = this.state;
        const isTabsDisabled = !data.id || !this.props.isFormValid;
        return (
            <div className="license-keygroup-editor">
                <Tabs
                    type="menu"
                    activeTab={selectedTab}
                    onTabClick={tabIndex => {
                        if (tabIndex === tabIds.ADD_LIMIT_BUTTON) {
                            this.onAddLimit();
                        } else {
                            this.setState({ selectedTab: tabIndex });
                            onCloseLimitEditor();
                            this.setState({ selectedLimit: '' });
                        }
                    }}
                    invalidTabs={[]}>
                    <Tab
                        tabId={tabIds.GENERAL}
                        data-test-id="general-tab"
                        title={i18n('General')}>
                        {genericFieldInfo && (
                            <Form
                                ref="validationForm"
                                hasButtons={false}
                                isValid={this.props.isFormValid}
                                formReady={this.props.formReady}
                                onValidateForm={() =>
                                    this.props.onValidateForm(LKG_FORM_NAME)
                                }
                                labledButtons={true}
                                isReadOnlyMode={isReadOnlyMode}
                                className="license-model-form license-key-groups-form">
                                <LicenseKeyGroupFormContent
                                    data={data}
                                    onDataChanged={onDataChanged}
                                    genericFieldInfo={genericFieldInfo}
                                    validateName={value =>
                                        this.validateName(value)
                                    }
                                    validateStartDate={(value, state) =>
                                        validateStartDate(value, state)
                                    }
                                    thresholdValueValidation={(value, state) =>
                                        thresholdValueValidation(value, state)
                                    }
                                />
                            </Form>
                        )}
                    </Tab>
                    <Tab
                        tabId={tabIds.SP_LIMITS}
                        disabled={isTabsDisabled}
                        data-test-id="general-tab"
                        title={i18n('SP Limits')}>
                        {selectedTab === tabIds.SP_LIMITS && (
                            <LicenseKeyGroupsLimits
                                limitType={limitType.SERVICE_PROVIDER}
                                limitsList={limitsList.filter(
                                    item =>
                                        item.type === limitType.SERVICE_PROVIDER
                                )}
                                selectedLimit={this.state.selectedLimit}
                                onCloseLimitEditor={() =>
                                    this.onCloseLimitEditor()
                                }
                                onSelectLimit={limit =>
                                    this.onSelectLimit(limit)
                                }
                                isReadOnlyMode={isReadOnlyMode}
                            />
                        )}
                    </Tab>
                    <Tab
                        tabId={tabIds.VENDOR_LIMITS}
                        disabled={isTabsDisabled}
                        data-test-id="general-tab"
                        title={i18n('Vendor Limits')}>
                        {selectedTab === tabIds.VENDOR_LIMITS && (
                            <LicenseKeyGroupsLimits
                                limitType={limitType.VENDOR}
                                limitsList={limitsList.filter(
                                    item => item.type === limitType.VENDOR
                                )}
                                selectedLimit={this.state.selectedLimit}
                                onCloseLimitEditor={() =>
                                    this.onCloseLimitEditor()
                                }
                                onSelectLimit={limit =>
                                    this.onSelectLimit(limit)
                                }
                                isReadOnlyMode={isReadOnlyMode}
                            />
                        )}
                    </Tab>
                    {selectedTab !== tabIds.GENERAL ? (
                        <Button
                            className="add-limit-button"
                            tabId={tabIds.ADD_LIMIT_BUTTON}
                            btnType="link"
                            iconName="plus"
                            disabled={
                                this.state.selectedLimit || isReadOnlyMode
                            }>
                            {i18n('Add Limit')}
                        </Button>
                    ) : (
                        <div key="empty_lm_tab_key" />
                    ) // Render empty div to not break tabs
                    }
                </Tabs>

                <GridSection className="license-model-modal-buttons license-key-group-editor-buttons">
                    {!this.state.selectedLimit && (
                        <Button
                            btnType="primary"
                            disabled={!this.props.isFormValid || isReadOnlyMode}
                            onClick={() => this.submit()}
                            type="reset">
                            {i18n('Save')}
                        </Button>
                    )}
                    <Button
                        btnType={
                            this.state.selectedLimit ? 'primary' : 'secondary'
                        }
                        onClick={() => this.props.onCancel()}
                        type="reset">
                        {i18n('Cancel')}
                    </Button>
                </GridSection>
            </div>
        );
    }

    submit() {
        const {
            data: licenseKeyGroup,
            previousData: previousLicenseKeyGroup,
            formReady,
            onValidateForm,
            onSubmit
        } = this.props;
        if (!formReady) {
            onValidateForm(LKG_FORM_NAME);
        } else {
            onSubmit({ licenseKeyGroup, previousLicenseKeyGroup });
        }
    }

    validateName(value) {
        const { data: { id }, LKGNames } = this.props;
        const isExists = Validator.isItemNameAlreadyExistsInList({
            itemId: id,
            itemName: value,
            list: LKGNames
        });

        return !isExists
            ? { isValid: true, errorText: '' }
            : {
                  isValid: false,
                  errorText: i18n(
                      "License key group by the name '" +
                          value +
                          "' already exists. License key group name must be unique"
                  )
              };
    }

    onSelectLimit(limit) {
        if (limit.id === this.state.selectedLimit) {
            this.setState({ selectedLimit: '' });
            return;
        }
        this.setState({ selectedLimit: limit.id });
        this.props.onOpenLimitEditor(limit);
    }

    onCloseLimitEditor() {
        this.setState({ selectedLimit: '' });
        this.props.onCloseLimitEditor();
    }

    onAddLimit() {
        this.setState({ selectedLimit: NEW_LIMIT_TEMP_ID });
        this.props.onOpenLimitEditor();
    }
}

export default LicenseKeyGroupsEditorView;