1

The below code contains the data that will be displayed in react table format. Here Sometimes I am getting intermittent issue while saving the data. The save button will be enabled only once we do any update on table, that is after addition, update(edit), delete and disable otherwise.

But sometimes it is getting disabled, even after updation.

import React, { useState, useEffect, forwardRef } from 'react';
import PropTypes from 'prop-types';
import withContext from 'shared/HOCs/withContext';
import Select from 'app/shared/components/Select/Select';
import { getShops, getShopConfiguration, updateShopConfiguration } from './api';

import MaterialTable from "material-table";
import Check from '@material-ui/icons/Check';
import Clear from '@material-ui/icons/Clear';
import Edit from '@material-ui/icons/Edit';
import ViewColumn from '@material-ui/icons/ViewColumn';
import AddBox from '@material-ui/icons/AddBox';
import FilterList from '@material-ui/icons/FilterList';
import FirstPage from '@material-ui/icons/FirstPage';
import LastPage from '@material-ui/icons/LastPage';
import Search from '@material-ui/icons/Search';
import ChevronLeft from '@material-ui/icons/ChevronLeft';
import ChevronRight from '@material-ui/icons/ChevronRight';
import Remove from '@material-ui/icons/Remove';
import DeleteOutline from '@material-ui/icons/DeleteOutline';
import Button from '@material-ui/core/Button';

const FeatureFlags = (props) => {
  const [allShops, setAllShops] = useState([]);
  const [data, setData] = useState([]);
  const [configLabel, setConfigLabel] = useState("Default Configuration");
  const [selectedShop, setSelectedShop] = useState({
    value: "All",
    label: "All",
  });
  const [isSaveEnabled, setIsSaveEnabled] = useState(true);
  const [actionPerformed, setActionPerformed] = useState(false);

  const columns = [
    {
      title: "Type",
      field: 'flag'.trim(),
      editable: 'onAdd',
      validate: rowData => {
        if(rowData.flag===undefined || /^ *$/.test(rowData.flag)){
          return 'Required'
        }
        return true
      }},    {
      title: "Value",
      field: "value",
      initialEditValue: 'false',
      lookup: {
        true: 'true',
        false: 'false'
      }
    },
    {
      title: "State",
      field: "shopId",
      editable: 'never',
      initialEditValue: 'All',
      sorting: false

    }
  ];

  /* eslint-disable react/display-name */
  const tableIcons = {
    Add: forwardRef((props, ref) => selectedShop.value === 'All' && <AddBox onClick={() => setIsSaveEnabled(false)} {...props} ref={ref} />),
    Check: forwardRef((props, ref) => <Check {...props} onClick={() => setIsSaveEnabled(true)} ref={ref} />),
    Clear: forwardRef((props, ref) => <Clear {...props} onClick={() => setIsSaveEnabled(true)} ref={ref} />),
    Edit: forwardRef((props, ref) => <Edit {...props} onClick={() => setIsSaveEnabled(false)} ref={ref} />),
    ViewColumn: forwardRef((props, ref) => <ViewColumn {...props} ref={ref} />),
    Filter: forwardRef((props, ref) => <FilterList {...props} ref={ref} />),
    FirstPage: forwardRef((props, ref) => <FirstPage {...props} ref={ref} />),
    LastPage: forwardRef((props, ref) => <LastPage {...props} ref={ref} />),
    NextPage: forwardRef((props, ref) => <ChevronRight {...props} ref={ref} />),
    PreviousPage: forwardRef((props, ref) => <ChevronLeft {...props} ref={ref} />),
    ResetSearch: forwardRef((props, ref) => <Clear {...props} ref={ref} />),
    Search: forwardRef((props, ref) => <Search {...props} ref={ref} />),
    ThirdStateCheck: forwardRef((props, ref) => <Remove {...props} ref={ref} />),
    Delete: forwardRef((props, ref) => <DeleteOutline {...props} onClick={() => setIsSaveEnabled(false)} ref={ref} />),
  };
  /* eslint-disable react/display-name */
  useEffect(() => {
    if (allShops.length === 0) {
      getShopsList();
    }
  }, [allShops]);

  useEffect(() => {
    getConfiguration(selectedShop);
  }, [selectedShop])

  const getShopsList = async () => {
    const response = await (await getShops(props.context)).data;
    setAllShops(response);
  };

  const getConfiguration = async (shop) => {
    let currentShop
    if (shop) {
      currentShop = shop.value
    }
    const response = await (await getShopConfiguration(props.context, currentShop)).data;
    console.log('response :>> ', response);
    setData(response);
  }

  const handleChange = (shop) => {
    setSelectedShop(shop);
    if (shop === null) {
      setConfigLabel("Default Configuration");
      setSelectedShop({ value: "All", label: "All" });
    } else {
      setConfigLabel("Shop " + shop.value + " Configuration");

    }
  };

  const updateTableData = (newData, oldData) => {
    newData.shopId = selectedShop.value
    setActionPerformed(true)
    // eslint-disable-next-line no-unused-vars
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        const dataUpdate = [...data];
        const index = oldData.tableData.id;
        dataUpdate[index] = newData;
        setData([...dataUpdate]);
        resolve();
      }, 300)
    })
  }

  const addRowToTable = (newData) => {
    setActionPerformed(true)

    const checkData = data.some( x => x.flag === newData.flag);
    if(checkData){
      return new Promise((resolve) => {
        setTimeout(() => {
           setData([...data]);
          resolve();
        }, 300);
      })    
    }else{
    // eslint-disable-next-line no-unused-vars
    return new Promise((resolve, reject) => {
      setTimeout(() => {
         setData([...data, newData]);
        resolve();
      }, 300);
    })
   }
  }

  const deleteRow = (oldData) => {
    setActionPerformed(true)
     // eslint-disable-next-line no-unused-vars
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        const dataDelete = [...data];
        const index = oldData.tableData.id;
        dataDelete.splice(index, 1);
        setData([...dataDelete]);
        resolve();
      }, 300);
    })
  }

  const saveConfig = async () => {
    var currentShop = selectedShop.value
    var updatedData
    if (currentShop !== 'All') {
      updatedData = data.filter( item => item.shopId !== 'All')
    } else {
      updatedData = data
    }
    if (updatedData.length > 0 && actionPerformed) {
      const response = await updateShopConfiguration(props.context, currentShop, updatedData);
      console.log(`response ===`, response)
      if (response === 'error') {
        getConfiguration(selectedShop);
      }
    }
    setActionPerformed(false)
  }
  console.log('isSaveEnabled :>> ', isSaveEnabled, actionPerformed);
  return (
    <div className="page page-dashboard">
      <header>
        <h1>Feature Flags</h1>
      </header>
      <div className="content no-padding">
        <div className="advanced-filter">
          <div className="filters active">
            <div className="filter">
              <label htmlFor={'shop'}>Select Shop</label>
              <Select
                id="shop"
                defaultValue={{ label: "All", value: "All" }}
                placeholder={"Select Shop"}
                options={allShops}
                value={selectedShop}
                onChange={handleChange}
                isClearable
              />
            </div>
          </div>
        </div>
        {data.length > 0 && (
          <div className="list overflow-list">
            <MaterialTable
              icons={tableIcons}
              options={{
                paging: false,
                addRowPosition: 'first'
              }}
              columns={columns}
              data={data}
              editable={{
                isDeleteHidden: (row)=>row.shopId!=selectedShop.value,
                onRowUpdate: (newData, oldData) => updateTableData(newData, oldData),
                onRowAdd: (newData) =>addRowToTable(newData),
                onRowDelete: ( oldData ) => deleteRow(oldData)
              }}
              title={configLabel}
            />
          </div>
        )}
        {actionPerformed && <div style={{marginTop:'50px'}}>
          <Button variant="contained" color="primary" disabled={ !isSaveEnabled } onClick = {saveConfig} >Save Changes</Button>
        </div>}
      </div>
    </div>
  );
};

FeatureFlags.propTypes = {
  context: PropTypes.object.isRequired,
};

export default withContext(FeatureFlags);

Any leads would be appreciated.

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.