IT/코딩 관련 팁

List 에 onClick 시 이슈

KeepGooing 2021. 6. 30. 14:45
반응형
import React, { useState, useEffect, useRef, } from "react";
import JoditEditor from "jodit-react";
import { withRouter } from "react-router-dom";
import { Form, Icon, Input, Button, Checkbox, Typography, Row, Col,PageHeader, Descriptions, Select, List, Pagination , message, notification, Steps, Tag, Drawer  } from 'antd';
import { useDispatch } from "react-redux";
import { intentInsertDB, intentInsertDF  } from "../../../_actions/admin_actions";

const {Step} = Steps;
const {Option} = Select;

const data = [
    {TrainingPhrase : []},
    {MessageText : []},
    {ActionAndParameters : []}
  ];

function ScenarioManage(props) {

  const dispatch = useDispatch();

  const [Intent, setIntent] = useState("");
  
  const [LibName, setLibName] = useState('한국고전목록시스템')
  const [RequestType, setRequestType] = useState('type1')
  const [ServiceType, setServiceType] = useState('html')
  
  const [TrainingPhraseData, setTrainingPhraseData]                 = useState(data[0].TrainingPhrase);
  const [MessageTextData, setMessageTextData]                       = useState(data[1].MessageText);
  const [ActionAndParametersData, setActionAndParametersData]       = useState(data[2].ActionAndParameters);
  const [TrainingPhrase, setTrainingPhrase]                         = useState("");
  const [MessageText, setMessageText]                               = useState("");

  const [Prompt, setPrompt] = useState("");
  const [ParamVal, setParamVal] = useState("");
  const [Entity, setEntity] = useState("");
  const [Val, setVal] = useState("");

  const [Content, setContent]                                       = useState("");
  const [Visible, setVisible]                                       = useState("");
  const [PromptYN, setPromptYN]                                     = useState(false);
  const [Hidden, setHidden]                                         = useState("hidden")
  const ref = useRef(null);


  const onPromptHandler = (event) => {

    setPrompt(event.currentTarget.value);
  }

  const onParamValHandler = (event) => {
    setParamVal(event.currentTarget.value);
  }

  const onEntityHandler = (event) => {
    setEntity(event.currentTarget.value);
  }

  const onValHandler = (event) => {

    setVal(event.currentTarget.value);

  }

  const onPromptYnHandler = (event) => {

    setPromptYN(event.target.checked);

    if(event.target.checked) {
      setHidden("");
    }else{
      setPrompt("");
      setHidden("hidden");
    }

  }


  const onSubmitHandler = (event) => {

    event.preventDefault();


    const dataToSubmitDB = {
      "intentName"  : Intent,
      "reqType"     : RequestType,
      "serviceType" : ServiceType,
      "libName"     : LibName,
      "floor"       : "1",
      "returnData"  : Content
    }


console.log('ActionAndParametersData' , ActionAndParametersData);
    const lastArr = [];
    for(var v of ActionAndParametersData) {
      const tempObj = {}
      const tempArr = v.split('/');

      if(tempArr[0]) {
        tempObj.mandatory = true
      } else {
        tempObj.mandatory = false
      }

      tempObj.prompts = [tempArr[0]];
      tempObj.displayName = tempArr[1];
      tempObj.entityTypeDisplayName =tempArr[2];
      tempObj.value = tempArr[3];

      
      lastArr.push(tempObj);
    }

    const parameters = lastArr;

    console.log('parameters', parameters);

    const dataToSubmitDF = {
      "sessionId"              : "ecoChatbot",
      "displayName"            : Intent,
      "trainingPhrasesParts"   : TrainingPhraseData,
      "messageTexts"           : MessageTextData,
      parameters
    }



    for ( let prop in dataToSubmitDB ) {
      if(!dataToSubmitDB[prop]) {
        return message.info(`${prop}을 입력해주세요.`)
      }
    }

    console.log('dataToSubmitDB', dataToSubmitDB);

    dispatch(intentInsertDB(dataToSubmitDB))
      .then(response => {
        console.log('response.payload.data.Reply' , response.payload.data.Reply);
        return message.success(`데이터베이스 - ${ response.payload.data.Reply.result.message }`);
      })

      dispatch(intentInsertDF(dataToSubmitDF))
      .then(response => {
        console.log('df', response);
        return message.success(`다이얼로그플로우 - ${ response.payload.Reply.result.message }`)
      })

    
  }


  const deleteListHandler = (index) => {
    alert('?????');
    // ActionAndParametersData.splice(index, 1);
  }

  const intentHandler = (event) => {
    const intent = event.currentTarget.value;
    setIntent(intent)
  }
 
  const onKeyEnterPress = (event) =>{

    if(event.key === 'Enter') {
      if(!event.currentTarget.value) return message.info('값을 입력해주세요');
        setTrainingPhraseData([...TrainingPhraseData, event.currentTarget.value]);
         if(event.currentTarget.value) {console.log('삭제'); setTrainingPhrase("")};
       
    }
    
  }

  const onKeyEnterPress2 = (event) =>{

    if(event.key === 'Enter') {
      if(!event.currentTarget.value) return message.info('값을 입력해주세요');
        setMessageTextData([...MessageTextData, event.currentTarget.value]);
         if(event.currentTarget.value) {console.log('삭제'); setMessageText("")};
    }
    
  }
  const onKeyEnterPress3 = (event) =>{

    
      // if(!event.currentTarget.value) return message.info('값을 입력해주세요');
      //   setActionAndParametersData([...ActionAndParametersData, event.currentTarget.value]);
      //    if(event.currentTarget.value) {console.log('삭제'); setActionAndParameters("")} ;
    
    
  }

  const onTrainingPhraseHandler = (event) => {
    setTrainingPhrase(event.currentTarget.value);
  }

  const onMessageTextHandler = (event) => {
    setMessageText(event.currentTarget.value);
  }

  const onActionAndParameterHandler = (event) =>{

    if(PromptYN) {
      if(!Prompt) return message.info('모든 값을 입력 해주세요.')  
    }

    if(!ParamVal || !Entity || !Val) return message.info('모든 값을 입력 해주세요.')

    setActionAndParametersData([...ActionAndParametersData, `${Prompt}/${ParamVal}/${Entity}/${Val}` ]);
    console.log('삭제'); 
    setPrompt("")
    setParamVal("")
    setEntity("")
    setVal("")
    
  }



  const openNotification = (event) => {

    notification.open({
        message:'인텐트 등록 화면입니다.',
        description : 
        '인텐트 등록을 위한 관련 내용을 입력해주세요.',
          onClick: () => {
              console.log('Notification Clicked!');
            }
    })
  }


  const RequestTypeMAP = [
    {key:1 , value:'type1'},
    {key:2 , value:'type2'},
    {key:3 , value:'type3'}
  ]
  const ServiceTypeMap = [
    {key:1 , value:'html'},
    {key:2 , value:'md'},
    {key:3 , value:'webLink'},
    {key:4 , value:'image'}
  ]
  const LibNameMap = [
    {key:1 , value:'순창군립도서관'},
    {key:2 , value:'정읍시립도서관'},
    {key:3 , value:'정읍신태인'},
    {key:4 , value:'정읍기적'},
    {key:5 , value:'한국고전목록시스템'},
    {key:6 , value:'상상도서관'}
  ]

const requestTypeHandler = (reqType) => {
  RequestTypeMAP.map(item => {

    if(item.key === reqType) {
      setRequestType(item.value);
    };

  });
  

}

const serviceTypeHandler = (serviceType) => {
  ServiceTypeMap.map(item => {

    if(item.key === serviceType) {
      setServiceType(item.value)
    };
    
  });

}

const libNameHandler = (libName) => {
  LibNameMap.map(item => {

    if(item.key === libName) {
      setLibName(item.value)
    };
    
  });

}

const showDrawerHandler = () => {
  setVisible(true);
}

const onCloseHandler = () => {
  setVisible(false);
};




  return (
    // <div style={{ backgroundColor: '#F5F5F5', padding: 24 }}>
    <div style={{ backgroundColor: '#fcffe6', padding: 70 }}>
    <div
            style={{
            backgroundColor: '#F5F5F5',
            padding: 24,
            }}
        >
        <Tag color="#2db7f5">진행 단계</Tag>

        <PageHeader
                ghost={false}
                subTitle="시나리오 등록 과정"
            >
        <Steps>
            <Step status="process" title="인텐트 명 등록" icon={<Icon type="check-circle" theme="twoTone"/>} />
            <Step status="wait" title="데이터베이스 타입 입력" icon={<Icon type="check-circle" theme="twoTone" />} />
            <Step status="wait" title="데이터베이스 내용 입력" icon={<Icon type="check-circle" theme="twoTone" />} />
            <Step status="wait" title="Dialogflow 문구 입력" icon={<Icon type="check-circle" theme="twoTone" />} />
        </Steps>
    </PageHeader>
        </div>
    <div
            style={{
            backgroundColor: '#F5F5F5',
            padding: 24,
            }}
        >
        <Tag color="#87d068">시나리오 작성</Tag>
              <PageHeader
                ghost={false}
                title="인텐트 등록"
                subTitle="시나리오 상에서 응답하기 원하는 Intent 등록"
                extra={[
                    <Button key="1" onClick={onSubmitHandler}>저장하기</Button>,
                ]}
            >
            <Input style={{width:750}} placeholder="등록할 인텐트명을 입력하세요" value={Intent} onChange={intentHandler}/>
            </PageHeader>

    <PageHeader
            ghost={false}
            title="관련 정보 입력"
            subTitle="DB  / Dialogflow"
        >

    <div style={{ margin: '24px 0' }} />
            <Row >
                <Col>
                    <PageHeader
                        ghost={false}
                        title="데이터베이스 입력란"
                        subTitle="CUBRID"
                    >
                          <Descriptions size="middle" column={3}>
                            <Descriptions.Item label="1. 요청타입">
                                    <Select style={{ width: 200 }} value={RequestType} onChange={requestTypeHandler}>
                                      {
                                      RequestTypeMAP.map(item => (
                                         <Option key={item.key} value={item.key}>{item.value}</Option>
                                      ))
                                      }
                                    </Select>
                            </Descriptions.Item>
                            <Descriptions.Item label="2. 서비스타입">
                                    <Select style={{ width:200 }} value={ServiceType} onChange={serviceTypeHandler}>
                                        {
                                          ServiceTypeMap.map(item => (
                                            <Option key={item.key} value={item.key}>{item.value}</Option>
                                          ))
                                        }
                                    </Select>
                            </Descriptions.Item>
                            <Descriptions.Item label="3. 도서관명">
                                    <Select style={{ width: 200 }} value={LibName} onChange={libNameHandler}>
                                        {
                                          LibNameMap.map(item => (
                                            <Option key={item.key} value={item.key}>{item.value}</Option>
                                          ))
                                        }
                                    </Select>
                            </Descriptions.Item>
                            
                    </Descriptions>
                    </PageHeader>

                    <PageHeader
                        ghost={false}
                        title="데이터베이스 내용 입력"
                        subTitle="CUBRID"
                    >
         
                            <JoditEditor
                                ref={ref}
                                value={Content}
                                config={{
                                    readonly: false, // all options from https://xdsoft.net/jodit/doc/
                                    // theme: "dark",
                                    language : "ko"
                                }}
                                tabIndex={1} // tabIndex of textarea
                                onBlur={newContent => setContent(newContent)} // preferred to use only this option to update the content for performance reasons
                                onChange={newContent => {}}
                             />
                
                    </PageHeader>
                    
                </Col>
                </Row>
                <Row >
                <Col>
                    <PageHeader
                        ghost={false}
                        title="Dialogflow 입력란"
                        subTitle="Google"
                    >
                          <Descriptions size="large" layout="vertical" column={3}>
                            <Descriptions.Item label="1. 훈련 문구(Training Phrase)" span={1} >
                                <Input style={{ width: 450 }}  placeholder="등록한 문구를 입력하세요." value={TrainingPhrase} onChange={onTrainingPhraseHandler} onKeyDown={onKeyEnterPress}/>
                            </Descriptions.Item>
                            <Descriptions.Item label="2. 응답 메시지 (Message Text)" span={1}>
                                <Input style={{ width: 450 }}  placeholder="등록한 문구를 입력하세요." value={MessageText} onChange={onMessageTextHandler} onKeyPress={onKeyEnterPress2} />
                            </Descriptions.Item>
                            <Descriptions.Item label="3. 액션 앤드 파라미터(Action and Parameters)" span={1}>
                                {/* <Input style={{ width: 450 }}  placeholder="등록한 문구를 입력하세요."  value={ActionAndParameters} onChange={onActionAndParameterHandler} onKeyPress={onKeyEnterPress3} /> */}
                                <Button type="primary" onClick={showDrawerHandler}><Icon type="plus" /> 액션 앤드 파라미터 추가 </Button>

                                <Drawer
                                  title="3. 액션 앤드 파라미터(Action and Parameters) 입력"
                                  placement={'top'}
                                  closable={true}
                                  onClose={onCloseHandler}
                                  visible={Visible}
                                  height={500}
                                >
                                  <p><Checkbox checked={PromptYN} onChange={onPromptYnHandler}>필수 값</Checkbox></p>
                                  <p><Input style={{ width: 450 }}  placeholder="프롬프터 입력" type={Hidden} value={Prompt} onChange={onPromptHandler} /></p>

                                  <p><Input style={{ width: 450 }}  placeholder="매개 변수 입력"  value={ParamVal} onChange={onParamValHandler} /></p>
                                  <p><Input style={{ width: 450 }}  placeholder="엔티티 입력"  value={Entity} onChange={onEntityHandler} /></p>
                                  <p><Input style={{ width: 450 }}  placeholder="값 입력"  value={Val} onChange={onValHandler} /></p>

                                  <Button onClick={onActionAndParameterHandler}>완료</Button>
                                </Drawer>

                            </Descriptions.Item>
                    </Descriptions>
                    </PageHeader>
                </Col>
            </Row>
    </PageHeader>



    </div>
    <div
        style={{
        backgroundColor: '#F5F5F5',
        padding: 24,
        }}
        >
        <Tag color="#108ee9">Dialogflow 입력란 결과</Tag>
                <PageHeader
                ghost={false}
                subTitle="입력한 Dialogflow 문구"
            >
    <Row gutter={16}>
    <Col span={8}>
   <h3 style={{ marginBottom: 16 }}>1. 훈련 문구(Training Phrase)</h3>
    <List
        
    //   header={<div>header</div>}
    //   footer={<div>Footer</div>}
      bordered
      
      dataSource={TrainingPhraseData}
      renderItem={item => (
        <List.Item>
            <Typography.Text mark>[training]</Typography.Text> {item}
        </List.Item>
      )}
    />
        </Col>
        <Col span={8}>
        <h3 style={{ marginBottom: 16 }}>2. 응답 메시지 (Message Text)</h3>
    <List
        
    //   header={<div>응답 메시지</div>}
    //   footer={<div>Footer</div>}
      bordered
      
      dataSource={MessageTextData}
      renderItem={item => (
        <List.Item>
            <Typography.Text mark>[Message Text]</Typography.Text> {item}
        </List.Item>
      )}
    />
        </Col>
        <Col span={8}>
        <h3 style={{ marginBottom: 16 }}>3. 액션 앤드 파라미터(Action and Parameters)</h3>
    <List
           itemLayout="horizontal"
    //   header={<div>액션 앤드 파라미터</div>}
    //   footer={<div>Footer</div>}
      bordered
      
      dataSource={ActionAndParametersData}
      renderItem={(item, index)=> (
        
        <List.Item  actions={[<a key="list-delete"><Icon    onClick={() => deleteListHandler(index)} type="delete" theme="twoTone" /></a>]} style={{ height : 120 }} >
            <Typography.Text mark>[{1+index}. PROMPTS]</Typography.Text> {item.split('/')[0] }<br/>
            <Typography.Text mark>[{1+index}. PARAMETERS]</Typography.Text> {item.split('/')[1]}<br/>
            <Typography.Text mark>[{1+index}. ENTITY]</Typography.Text> {item.split('/')[2]}<br/>
            <Typography.Text mark>[{1+index}. VALUE]</Typography.Text> {item.split('/')[3]}<br/>
        </List.Item>
        
      )}
    />
    
        </Col>
    </Row>
    <div style={{textAlign : 'center' , marginTop: 16}}>
    <Pagination defaultCurrent={1} total = {50} />
    </div>
    </PageHeader>
 </div>
</div>

    
  );
};

export default withRouter(ScenarioManage);



  <List.Item  actions={[<a key="list-delete"><Icon    onClick={() => deleteListHandler(index)} type="delete" theme="twoTone" /></a>]} style={{ height : 120 }} >

 

onClick에 클로저 함 수 형태는 문제없이 잘 동작

 

 

그러나

 

 

 

  <List.Item  actions={[<a key="list-delete"><Icon    onClick={deleteListHandler(index)} type="delete" theme="twoTone" /></a>]} style={{ height : 120 }} >

 

이 경우에 오류 발생

 

이는 

접근에 문제가 있음

 

 

 

 

클로저 함수의 경우에

내부 함수는 안에서 움직인다.

 

따라서 

 

 

  const deleteListHandler = (index) => {
    
    let newActionAndParametersData = [...ActionAndParametersData];

    newActionAndParametersData.splice(index, 1);
    
    // ActionAndParametersData.splice(index, 1);

    setActionAndParametersData(newActionAndParametersData)

    // props.refreshFunction(ActionAndParametersData);

  }

 

 

위가 아닌

 

 

  const deleteListHandler = (index) => {
    
    // let newActionAndParametersData = [...ActionAndParametersData];

    // newActionAndParametersData.splice(index, 1);
    
    ActionAndParametersData.splice(index, 1);

    setActionAndParametersData(newActionAndParametersData)

    // props.refreshFunction(ActionAndParametersData);

  }
반응형