NGMsoftware

NGMsoftware
로그인 회원가입
  • 매뉴얼
  • 학습
  • 매뉴얼

    학습


    JavaScript [React + Typescript + Antd] Common Filter Condition Component 소스.

    페이지 정보

    본문

    안녕하세요. 엔지엠소프트웨어입니다. 리액트, 타입스크립트, 앤트 디자인을 이용한 필터 컨디션 컴포넌트 소스입니다. 이 컴포넌트는 공용으로 사용할 수 있도록 만든건데요. Backend로부터 일부 정보는 가져와야 사용할 수 있습니다. Filter Condition Component는 공통된 디자인 및 검색 로직을 사용하기 위한 컴포넌트입니다. 반도체와 같은 제조 프로젝트 환경에서 Depth(일반적으로 Site, Line, Area...와 같은 Location 정보)를 Select(ComboBox, DropDownList) 컨트롤로 표시합니다. 또한, 기간을 선택할 수 있도록 useDateTime 속성이 존재합니다. 각각의 Chart 또는 View Component에서 아래 Syntax에 맞게 사용할 수 있습니다. UI에서 Depth 정보를 Filter Condition Component로 넘겨줘야 합니다. Depth 정보를 바탕으로 각각의 Select 컨트롤을 동적으로 생성하고, Option 아이템을 바인딩합니다.

    Design

    Location Filter Condition

    2023-04-11 13 55 14.png

     

     

    Parameter Filter Condition

    2023-04-20 07 49 04.png

     

     

    Syntax

    <ConditionComponent 
      conditionType={ConditionType.Location | ConditionType.Parameter}
      backendAPI="http://localhost:2023/api/v1/common/condition/search-condition"
      depths={depths | params} 
      selectLabelWidth={110} 
      useDateTime={false} 
      dateTimeText="Select Date (Default: 7days)"
      title="Condition" 
      isMultiple={true} 
      isShowTime={true} 
      useRefresh={true}
      useClear={true}
      useAll={true}
      useSelectAll={true}
      useCancelRestore={true}
      isMaskClosable={true}
      isDestroyOnClose={true}
      useDraggable={true}
      propFunction={propFunction}>
    </ConditionComponent>

     

    Filter Condition Component를 사용하는 경우 아래와 같은 기본 정보가 필요합니다. 이 정보는 같이 배포되는 Backend의 Application.yml 또는 PostgreSQL DB에서 Query하거나 Frontend의 Config나 ini와 같은 설정 정보를 저장하는 곳에 입력해야 합니다. 사이트마다 Location은 동적으로 변경될 수 있기 때문에 공통 컴포넌트를 사용하는쪽에서 데이타를 넘겨야 합니다.

      const depths = () => {
        return [
          { key: 0, value: 'SITE', alias: '사이트 (Site)' },
          { key: 1, value: 'LINE', alias: '라인 (Line)' },
          { key: 2, value: 'AREA', alias: '에어리어 (Area)' },
        ];
      };
    
      const params = () => {
        return [
          { key: 0, value: 'EQP01_PM1', alias: 'Parameters', type: '', limit: 100 }
        ];
      };

     

    Filter Condition Component Source

    ConditionComponent.tsx

    /**
     * Documentation
     * Filter Condition Component는 공통된 디자인 및 검색 로직을 사용하기 위한 컴포넌트입니다. 
     * 반도체와 같은 제조 프로젝트 환경에서 Depth(일반적으로 Site, Line, Area...와 같은 Location 정보)를 Select(ComboBox, DropDownList) 컨트롤로 표시합니다. 
     * 또한, 기간을 선택할 수 있도록 useDateTime 속성이 존재합니다. 
     * 각각의 Chart 또는 View Component에서 아래 Syntax에 맞게 사용할 수 있습니다. 
     * Frontend에서 Depth(Location) 정보를 Filter Condition Component로 넘겨줘야 합니다. 
     * Depth (Location) 정보를 바탕으로 각각의 Select 컨트롤을 동적으로 생성하고, Option 아이템을 바인딩합니다.
     */
    import { SettingOutlined, ReloadOutlined } from '@ant-design/icons';
    import { useCallback, useEffect, useRef, useState } from 'react';
    import { Modal, Form, Select, DatePicker, Tooltip, Space, Button } from 'antd';
    import classes from './ConditionComponent.module.css';
    import dayjs from 'dayjs';
    import 'dayjs/locale/ko';
    import moment from 'moment';
    import type { DraggableData, DraggableEvent } from 'react-draggable';
    import Draggable from 'react-draggable';
    import { lutimes } from 'fs';
    import { NavigationType } from 'react-router-dom';
    
    function ConditionComponent(props: any) {
      const { RangePicker } = DatePicker;
    
      /**
       * Default Depth 설정
       * 이 값은 View Component로부터 받아야 합니다.
       */
      const [depths, setDepths] = useState<any[]>([
        { key: 0, value: 'SITE', alias: '사이트', type: '', limit: -1 },
        { key: 1, value: 'LINE', alias: '라인', type: '', limit: -1 },
        { key: 2, value: 'AREA', alias: '에어리어', type: '', limit: -1 },
      ]);
    
      /**
       * Condition Result Items
       */
      const [conditionData, setConditionData] = useState<any>({});
    
      //#region Component state
    
      //#region Date Ragne Picker state
      const [isShowTime, setIsShowTime] = useState<Boolean>(props.isShowTime);
      const [selectTime, setConfigTime] = useState<any>([
        dayjs().add(-7, 'd'),
        dayjs(),
      ]);
      const [dateTimeFormat, setDateTimeFormat] = useState<String>(
        props.dateTimeFormat
      );
      const [start, setStart] = useState<any>(dayjs().add(-7, 'd'));
      const [end, setEnd] = useState<any>(dayjs());
      //#endregion
    
      //#region Select config state
      const [selectedOptionItems, setSelectedOptionItems] = useState<any>({});
      const [selectLabelWidth, setSelectLabelWidth] = useState<any>(
        props.selectLabelWidth
      );
      const [isMultiple, setIsMultiple] = useState<Boolean>(props.isMultiple);
      const [selectOptionItems, setSelectOptionItems] = useState<any>({});
      const [optionItems, setOptionItems] = useState<any>({});
      const [prevConditionData, setPrevConditionData] = useState<any>({});
      const [selectPlaceholder, setSelectPlaceholder] = useState<String>(
        props.selectPlaceholder
      );
      //#endregion
    
      //#region Component design state
      const [useDraggable, setUseDraggable] = useState<any>(props.useDraggable);
      const [disabled, setDisabled] = useState(true);
      const [bounds, setBounds] = useState({
        left: 0,
        top: 0,
        bottom: 0,
        right: 0,
      });
      const draggleRef = useRef<HTMLDivElement>(null);
    
      const [conditionTitle, setTitle] = useState<String>(props.title);
      const [isModalOpen, setIsModalOpen] = useState<any>(false);
    
      const [useAll, setUseAll] = useState<any>(props.useAll);
      const [useAllText, setUseAllText] = useState<String>(props.useAllText);
      const [useCancelRestore, setUseCancelRestore] = useState<any>(
        props.useCancelRestore
      );
      const [useClear, setUseClear] = useState<any>(props.useClear);
      const [useSelectAll, setUseSelectAll] = useState<any>(props.useSelectAll);
      const [useDateTime, setUseDateTime] = useState<any>(props.useDateTime);
      const [dateTimeText, setDateTimeText] = useState<any>(props.dateTimeText);
      const [useRefresh, setUseRefresh] = useState<any>(props.useRefresh);
      const [isMaskClosable, setIsMaskCloable] = useState<any>(
        props.isMaskClosable
      );
      const [isDestroyOnClose, setIsDestroyOnClose] = useState<any>(
        props.isDestroyOnClose
      );
      const [conditionType, setConditionType] = useState<ConditionType>(
        props.conditionType
      );
      const [restfulAPI, setRestfulAPI] = useState<String>(props.restfulAPI);
      //#endregion
    
      const fetchDepthDataHandler = useCallback(async (request: any) => {
        if (request.length == 0) {
          return;
        }
    
        let backendAPI = restfulAPI;
    
        try {
          if (request.paths != undefined && request.paths.length > 0) {
            if (!(typeof request.paths[0] === 'string')) {
              request.paths = request.paths.map(function (v: any) {
                return v.value;
              });
            }
          }
    
          const resquestOptions = {
            method: 'POST',
            headers: {
              'Content-Type': 'application.json',
            },
          };
    
          let params = '';
          switch (conditionType) {
            case ConditionType.Location:
              params = new URLSearchParams({
                conditionDesignData: JSON.stringify(request),
              }).toString();
              break;
            case ConditionType.Parameter:
              params = `assetID=${request.assetID}&type=${request.type}&limit=${request.limit}`;
              break;
          }
    
          const response = await fetch(`${backendAPI}?${params}`, resquestOptions);
    
          if (!response.ok) {
            throw new Error('Something went wrong!');
          }
    
          const data = await response.json();
    
          if (useSelectAll && isMultiple) {
            switch (conditionType) {
              case ConditionType.Location:
                if (data.result.items.length > 0) {
                  data.result.items.splice(0, 0, { key: -1, value: 'ALL' });
                }
                break;
              case ConditionType.Parameter:
                if (data.result.length > 0) {
                  data.result.splice(0, 0, { rawid: -1, name: 'ALL' });
                }
                break;
            }
          }
    
          switch (conditionType) {
            case ConditionType.Location:
              setSelectOptionItems((prevState: any) => {
                return { ...prevState, [request.depth]: data.result.items };
              });
              break;
            case ConditionType.Parameter:
              let params: any = [];
    
              data.result.forEach((item: any) => {
                params.push({ key: item.rawid, value: item.name });
              });
    
              setSelectOptionItems((prevState: any) => {
                return { ...prevState, [request.assetID]: params };
              });
              break;
          }
        } catch (error: any) {
          throw error;
        }
      }, []);
    
      //#region Events
    
      //#region Life-cycle events
      /**
       * WebPage 가 Loaded되면 최초 발생하는 이벤트입니다.
       */
      useEffect(() => {
        props.propFunction(conditionData);
    
        if (props.conditionType == undefined || props.conditionType == '') {
          setConditionType(ConditionType.Location);
        }
    
        if (props.dateTimeFormat == undefined || props.dateTimeFormat == '') {
          setDateTimeFormat('YYYY-MM-DD HH:mm:ss');
        }
    
        if (props.selectPlaceholder == undefined || props.selectPlaceholder == '') {
          setSelectPlaceholder('Please select');
        }
    
        if (props.useAllText == undefined || props.useAllText == '') {
          setUseAllText('Select ALL');
        }
    
        setDepths(props.depths);
        fetchDepthDataHandler(props.depths);
      }, [conditionData]);
      //#endregion
    
      //#region Component events
      /**
       * Condition Component에서 Cancel 버튼을 클릭할 때 이벤트가 발생합니다.
       */
      const onOk = () => {
        // 모달을 닫아줍니다.
        setIsModalOpen(false);
    
        let startTime = '';
        let endTime = '';
        selectTime.forEach((d: any, index = 0) => {
          const date = moment(d.$d).format(`${dateTimeFormat}`);
          if (index === 0) {
            startTime = date;
            index++;
          } else {
            endTime = date;
          }
        });
    
        depths.forEach((d: any) => {
          if (d.value in optionItems && d.value in selectOptionItems) {
            selectOptionItems[d.value].forEach((x: any) => {
              if (x.value == 'ALL') {
                return;
              }
    
              optionItems[d.value].forEach((y: any) => {
                const index = optionItems[d.value].indexOf(x.value);
                if (index > -1) {
                  optionItems[d.value].splice(index, 1, x);
                }
              });
            });
          }
        });
    
        if (useDateTime) {
          setConditionData({
            startTime: startTime,
            endTime: endTime,
            selectItems: optionItems,
          });
        } else {
          setConditionData({
            selectItems: optionItems,
          });
        }
    
        if (useCancelRestore) {
          setPrevConditionData([
            { ...optionItems },
            { ...selectOptionItems },
            { ...selectedOptionItems },
          ]);
        }
    
        if (isDestroyOnClose) {
          refreshClick();
        }
      };
    
      /**
       * Condition Component에서 Cancel 버튼을 클릭할 때 이벤트가 발생합니다.
       */
      const onCancel = () => {
        // 모달을 닫아줍니다.
        setIsModalOpen(false);
    
        if (useCancelRestore) {
          if (
            prevConditionData &&
            prevConditionData.length != undefined &&
            prevConditionData.length > 2
          ) {
            setOptionItems(prevConditionData[0]);
            setSelectOptionItems(prevConditionData[1]);
            setSelectedOptionItems(prevConditionData[2]);
          }
        }
    
        if (isDestroyOnClose) {
          refreshClick();
        }
      };
    
      /**
       * Select에서 항목을 선택할 때 이벤트가 발생합니다.
       * @param e Select에서 선택한 항목이 배열로 들어옵니다.
       * isMultiple 속성을 false로 설정하면 항목 이름만 들어옵니다.
       */
      const dateChange = (e: any) => {
        const timeList: any[] = [];
        setStart(e[0]);
        setEnd(e[1]);
        timeList.push(e[0], e[1]);
        setConfigTime(timeList);
      };
    
      /**
       * 새로고침 버튼을 클릭하면 이벤트가 발생합니다.
       * 모든 내용을 초기 상태로 만듭니다. (시간은 현재 시간으로 다시 설정됩니다.)
       */
      const refreshClick = () => {
        setStart(dayjs().add(-7, 'd'));
        setEnd(dayjs());
        setOptionItems({});
        setSelectOptionItems({});
        setSelectedOptionItems({});
    
        depths.forEach((d: any) => {
          optionItems[d.value] = [];
        });
    
        setOptionItems({ ...optionItems });
        setSelectOptionItems({ ...optionItems });
        setSelectedOptionItems({ ...optionItems });
      };
    
      /**
       * Select를 클릭하면 이벤트가 발생합니다.
       * Select의 Option(Item)을 채워주는 로직입니다.
       * @param value select control
       * @param index select index
       */
      const selectClick = (value: any, index: number) => {
        setSelectedOptionItems({});
    
        switch (conditionType) {
          case ConditionType.Location:
            if (!(value.target.className.toString().indexOf('option') > -1)) {
              if (index == 0) {
                fetchDepthDataHandler({
                  depth: depths[index].value,
                  depthIndex: index,
                });
              } else {
                if (
                  optionItems[depths[index - 1].value] != undefined &&
                  optionItems[depths[index - 1].value].length > 0
                ) {
                  fetchDepthDataHandler({
                    depth: depths[index].value,
                    depthIndex: index - 1,
                    paths: optionItems[depths[index - 1].value],
                  });
                } else {
                  selectOptionItems[depths[index].value] = [];
                  setSelectOptionItems(selectOptionItems);
                }
              }
            }
            break;
          case ConditionType.Parameter:
            fetchDepthDataHandler({
              assetID: depths[index].value,
              type: depths[index].type,
              limit: depths[index].limit,
            });
            break;
        }
    
        if (!isMultiple) {
          setTimeout(function () {
            cleanOptionItems(optionItems);
          }, 1);
        }
      };
    
      /**
       * Select 에서 항목(Option)을 선택한 값이 배열로 들어옵니다.
       * @param value selected options
       * @param index select index
       */
      const selectChange = (value: string[], index: number) => {
        if (isMultiple) {
          if (useSelectAll && Object.values(value).includes('ALL')) {
            selectOptionItems[depths[index].value].splice(0, 1);
            const items = selectOptionItems[depths[index].value].map(function (
              v: any
            ) {
              return v.value;
            });
    
            if (items.length == value.length - 1) {
              return;
            }
    
            optionItems[depths[index].value] = items;
          } else {
            optionItems[depths[index].value] = value;
          }
    
          if (value.length == 0) {
            depths.forEach((d: any, i: number) => {
              if (index <= i) {
                optionItems[d.value] = [];
              }
            });
          }
        } else {
          optionItems[depths[index].value] = [value];
    
          depths.forEach((d: any, i: number) => {
            if (index < i) {
              optionItems[d.value] = [];
            }
          });
        }
      };
    
      const deselectChange = (value: string[], index: number) => {
        if (isMultiple) {
          depths.forEach((d: any, i: number) => {
            if (index < i) {
              optionItems[d.value] = [];
            }
          });
    
          setSelectedOptionItems({ ...optionItems });
        }
      };
    
      const selectAll = async () => {
        try {
          var i = 0;
    
          const resquestOptions = {
            method: 'POST',
            headers: {
              'Content-Type': 'application.json',
            },
          };
    
          let params: any;
          let response: any;
          let data: any;
    
          for (const d of depths) {
            let request;
            optionItems[d.value] = [];
    
            switch (conditionType) {
              case ConditionType.Location:
                if (i == 0) {
                  request = { depth: d.value, depthIndex: i };
                } else {
                  var idx = 0;
                  if (i > 1) {
                    idx = 1;
                  }
    
                  request = {
                    depth: d.value,
                    depthIndex: idx,
                    paths: optionItems[depths[i - 1].value].map(function (v: any) {
                      return v.value;
                    }),
                  };
                }
    
                params = new URLSearchParams({
                  conditionDesignData: JSON.stringify(request),
                }).toString();
                response = await fetch(`${restfulAPI}?${params}`, resquestOptions);
    
                if (!response.ok) {
                  throw new Error('Something went wrong!');
                }
    
                data = await response.json();
    
                optionItems[d.value] = data.result.items;
                break;
              case ConditionType.Parameter:
                request = {
                  assetID: depths[i].value,
                  type: depths[i].type,
                  limit: depths[i].limit,
                };
    
                params = `assetID=${request.assetID}&type=${request.type}&limit=${request.limit}`;
                response = await fetch(`${restfulAPI}?${params}`, resquestOptions);
    
                if (!response.ok) {
                  throw new Error('Something went wrong!');
                }
    
                data = await response.json();
    
                params = [];
    
                data.result.forEach((item: any) => {
                  params.push({ key: item.rawid, value: item.name });
                });
    
                optionItems[d.value] = params;
                break;
            }
    
            i++;
          }
    
          setSelectedOptionItems(optionItems);
        } catch (error: any) {
          throw error;
        }
      };
    
      /**
       * Select 내부 이벤트(onChange, onSelect)에서 항목을 갱신할 수 없는 문제가 있어서,
       * 별도 함수에서 업데이트 하도록 처리하는 함수입니다.
       * @param items Select를 갱신할 옵션 아이템 목록입니다.
       */
      const cleanOptionItems = (items: any) => {
        setSelectedOptionItems(items);
      };
    
      const onStart = (_event: DraggableEvent, uiData: DraggableData) => {
        const { clientWidth, clientHeight } = window.document.documentElement;
        const targetRect = draggleRef.current?.getBoundingClientRect();
        if (!targetRect) {
          return;
        }
        setBounds({
          left: -targetRect.left + uiData.x,
          right: clientWidth - (targetRect.right - uiData.x),
          top: -targetRect.top + uiData.y,
          bottom: clientHeight - (targetRect.bottom - uiData.y),
        });
      };
      //#endregion
    
      //#endregion
    
      /**
       * Condition Component 실행 여부 상태를 저장합니다.
       */
      const showModal = () => {
        setIsModalOpen(true);
      };
    
      return (
        <div className={classes.btn}>
          <SettingOutlined onClick={showModal} />
          <Modal
            maskClosable={isMaskClosable}
            title={
              useDraggable ? (
                <div
                  style={{
                    width: '100%',
                    cursor: 'move',
                  }}
                  onMouseOver={() => {
                    if (disabled) {
                      setDisabled(false);
                    }
                  }}
                  onMouseOut={() => {
                    setDisabled(true);
                  }}
                  onFocus={() => {}}
                  onBlur={() => {}}
                >
                  {conditionTitle}
                </div>
              ) : (
                <div>{conditionTitle}</div>
              )
            }
            open={isModalOpen}
            onOk={onOk}
            onCancel={onCancel}
            footer={
              useAll
                ? [
                    <Button onClick={selectAll}>Select ALL</Button>,
                    <Button key="cancel" onClick={onCancel}>
                      Cancel
                    </Button>,
                    <Button key="submit" type="primary" onClick={onOk}>
                      OK
                    </Button>,
                  ]
                : [
                    <Button key="cancel" onClick={onCancel}>
                      Cancel
                    </Button>,
                    <Button key="submit" type="primary" onClick={onOk}>
                      OK
                    </Button>,
                  ]
            }
            modalRender={(modal) => (
              <Draggable
                disabled={disabled}
                bounds={bounds}
                onStart={(event, uiData) => onStart(event, uiData)}
              >
                <div ref={draggleRef}>{modal}</div>
              </Draggable>
            )}
          >
            <div
              style={{ display: useDateTime ? 'block' : 'none', marginBottom: 10 }}
            >
              {dateTimeText != undefined ? (
                <div style={{ marginBottom: 10 }} className={classes.title}>
                  {dateTimeText}
                </div>
              ) : (
                ''
              )}
              <div style={{ float: useRefresh ? 'left' : 'none', marginRight: 10 }}>
                <RangePicker
                  className={classes.date}
                  defaultValue={[dayjs().add(-7, 'd'), dayjs()]}
                  value={[start, end]}
                  onChange={(e) => dateChange(e)}
                  showTime={isShowTime ? true : false}
                />
              </div>
              <div style={{ display: useRefresh ? 'block' : 'none' }}>
                <Tooltip title="refresh">
                  <ReloadOutlined
                    className={classes.refresh}
                    onClick={refreshClick}
                  />
                </Tooltip>
              </div>
            </div>
            <br />
            {depths.map((d, i) => (
              <Form
                key={d.key}
                labelCol={{ span: 4 }}
                wrapperCol={{ span: 14 }}
                layout="horizontal"
                style={{ maxWidth: 600 }}
              >
                <Form.Item
                  label={d.alias}
                  labelCol={{
                    style: {
                      width: selectLabelWidth == undefined ? 100 : selectLabelWidth,
                    },
                  }}
                >
                  <Space wrap style={{ width: 600 }}>
                    <Select
                      allowClear={useClear}
                      style={{
                        width:
                          !useDateTime && useRefresh
                            ? 330 -
                              ((selectLabelWidth == undefined
                                ? 100
                                : selectLabelWidth) -
                                100)
                            : 370 -
                              ((selectLabelWidth == undefined
                                ? 100
                                : selectLabelWidth) -
                                100),
                      }}
                      mode={isMultiple ? 'multiple' : undefined}
                      placeholder={selectPlaceholder}
                      value={
                        d.value in selectedOptionItems
                          ? selectedOptionItems[d.value]
                          : optionItems[d.value]
                      }
                      onClick={(e) => selectClick(e, i)}
                      onChange={(e) => selectChange(e, i)}
                      onDeselect={(e) => deselectChange(e, i)}
                    >
                      {d.value in selectOptionItems
                        ? selectOptionItems[d.value].map((c: any) => (
                            <Select.Option key={c.key} value={c.value}>
                              {c.value}
                            </Select.Option>
                          ))
                        : ''}
                    </Select>
                    {i == 0 && !useDateTime && useRefresh ? (
                      <Tooltip title="refresh">
                        <ReloadOutlined
                          className={classes.refresh}
                          onClick={refreshClick}
                        />
                      </Tooltip>
                    ) : (
                      ''
                    )}
                  </Space>
                </Form.Item>
              </Form>
            ))}
          </Modal>
        </div>
      );
    }
    
    export default ConditionComponent;
    
    export enum ConditionType {
      Location = 0,
      Parameter = 1,
    }

     

    Properties

     1. depths (Required): 사이트(Site), 라인(Line), 에어리어(Area)로 표시되는 정보를 ConditionComponent로 넘겨줍니다. 이 값은 depth라고 부르며, location_mst 테이블에 code로 등록되어 있습니다. 

    • ex) depths 오브젝트
    • key: rawid
    • value: location_mst 테이블의 code 또는 assetID
    • alias: 사용자에게 보여지는 텍스트
    • type: 파라메터 타입
    • limit: 가져올 파라메터 수
      // 로케이션 필터 컨디션
      const depths = () => {
        return [
          { key: 0, value: 'SITE', alias: '사이트 (Site)' },
          { key: 1, value: 'LINE', alias: '라인 (Line)' },
          { key: 2, value: 'AREA', alias: '에어리어 (Area)' },
        ];
      };
    
      <ConditionComponent conditionType={ConditionType.Location} depths={depths} ...
    
      // 파라메터 필터 컨디션
      const params = () => {
        return [
          { key: 0, value: 'eqp01_pm1', alias: '파라메터', type: '', limit: 100 }
        ];
      };
    
      <ConditionComponent conditionType={ConditionType.Parameter} depths={params} ...

     

     2. selectLabelWidth (Optional): Select 콘트롤의 좌측에 표시되는 라벨의 넓이입니다. 크기를 200 또는 "100%"와 같이 입력할 수 있습니다.

    • selectLabelWidth={110} or selectLabelWidth="100%"

     3. useDateTime (Optional): 조회 조건 컨트롤에서 상단의 날짜 컨트롤 표시 여부를 true, false로 설정합니다.
     4. dateTimeText (Optional): 날짜 기간 조건의 설명 글을 추가할 수 있습니다.
     5. useRefresh (Optional): 조회 조건 초기화 버튼을 표시합니다.
     6. title (Optional): ConditionComponent의 제목입니다.
     7. isMultiple (Optional): Select 콘트롤에서 아이템을 멀티로 선택할지 여부를 true, false로 설정합니다.
     8. isShowTime (Optional): 날짜 선택 콘트롤에서 시간을 표시할지 여부를 true, false로 설정합니다.
     9. isDestroyOnClose (Optional): 모달 콘디션창을 닫을 때 모달의 모든 내용을 삭제합니다.
    10. propFunction (Required): ConditionComponent에서 사용자가 선택한 데이타를 받아올 함수를 연결합니다.
    11. useAll (Optional): Modal 상자에 All Select 버튼이 생성되고, 모든 Select 콘트롤의 모든 항목이 추가됩니다.
    12. useSelectAll (Optional): Select 콘트롤에서 ALL 옵션이 추가되고, 클릭하면 모든 항목이 추가됩니다.
    13. useClear (Optional): Select 콘트롤에서 전체 삭제 버튼을 표시합니다.
    14. isMaskClosable (Optional): 모달창의 외부를 클릭했을 때 창을 닫을지 여부를 설정합니다.
    15. useDraggable (Optional): 모달창을 드래그하여 위치를 이동할 수 있습니다.
    16. useCancelRestore (Optional): 모달창에서 Cancel 버튼을 클릭하는 경우 이전 OK 정보로 복구 해줍니다.
    17. dateTimeFormat (Optional): YYYY-MM-DD HH:mm:ss
    18. selectPlaceholder (Optional): Please select
    19. useAllText (Optional): Select ALL

    20. restfulAPI (Required): Backend API를 넘겨줍니다.

    • Location: http://localhost:2023/api/v1/common/condition/locations 
    • Parameter: http://localhost:2023/api/v1/common/condition/parameters

     

    Result

    endTime: string (useDateTime 속성이 true인 경우만 반환)
    startTime: string (useDateTime 속성이 true인 경우만 반환)
    selectItems: indexer

    {selectItems: 
      [SITE]: [
        { key: rawid, value: SITE1 },
        { key: rawid, value: SITE2 },
        { key: rawid, value: SITE3 },
      ],
      [LINE]: [
        { key: rawid, value: LINE1},
        { key: rawid, value: LINE2},
        { key: rawid, value: LINE3},
      ],
      [AREA]: [
        { key: rawid, value: AREA1 },
        { key: rawid, value: AREA2 },
        { key: rawid, value: AREA3 },
      ]
    }

     

    Examples

    기본 조건 컴포넌트로 단일 항목만 선택할 수 있습니다.

    <ConditionComponent depths={depths} propFunction={propFunction}></ConditionComponent>
    

    2023-04-18 13 57 19.png


     

    조건 컴포넌트에 날짜 조건을 추가하려면 아래와 같이 useDateTime을 true로 설정하세요.

    <ConditionComponent depths={depths} useDateTime={true} propFunction={propFunction}></ConditionComponent>
    

    2023-04-18 14 06 22.png


     

    시간까지 표시하려면 isShowTime을 true로 설정해야 합니다.

    <ConditionComponent depths={depths} useDateTime={true} isShowTime={true} propFunction={propFunction}></ConditionComponent>
    

    1.png


     

    날짜 콘트롤에 도움말을 표시하려면 아래와 같이 dateTimeText 속성에 텍스트를 추가할 수 있습니다.

    <ConditionComponent depths={depths} useDateTime={true} isShowTime={true} dateTimeText="Select Date ( Default : 7days)" propFunction={propFunction}></ConditionComponent>
    

    1.png


     

    모달창에 타이틀을 추가하려면 title 속성을 사용하세요.

    <ConditionComponent depths={depths} title="Common Condition" useDateTime={true} isShowTime={true} dateTimeText="Select Date ( Default : 7days)" propFunction={propFunction}></ConditionComponent>
    

    2.png


     

    useClear 속성을 true로 변경하면 Select 콘트롤에 전체 삭제 아이콘이 표시됩니다.

    <ConditionComponent depths={depths} useClear={true} isMultiple={true} title="Common Condition" useDateTime={true} isShowTime={true} dateTimeText="Select Date ( Default : 7days)" propFunction={propFunction}></ConditionComponent>
    

    3.png


     

    useAll 속성을 true로 설정하면 모달창 하단에 Select ALL 버튼이 추가되고, 모든 Select 컨트롤의 항목이 선택됩니다.

    <ConditionComponent depths={depths} useClear={true} isMultiple={true} title="Common Condition" useAll={true} useDateTime={true} isShowTime={true} dateTimeText="Select Date ( Default : 7days)" propFunction={propFunction}></ConditionComponent>
    

    4.png


     

    useSelectAll 속성을 true로 설정하면 Select 콘트롤에 ALL 항목이 추가되고, Select 컨트롤의 모든 항목이 선택됩니다.

    <ConditionComponent depths={depths} useClear={true} isMultiple={true} title="Common Condition" useAll={true} useSelectAll={true} useDateTime={true} isShowTime={true} dateTimeText="Select Date ( Default : 7days)" propFunction={propFunction}></ConditionComponent>
    

    5.png


     

    전체 속성을 사용하면 아래와 같이 표시됩니다.

    <ConditionComponent useClear={true} depths={depths} useAll={true} useSelectAll={true} isDestroyOnClose={true} dateTimeText="Select Date ( Default : 7days)" isMultiple={true} selectLabelWidth={110} useDateTime={true} useRefresh={true} title="Common Condition" isShowTime={true} propFunction={propFunction}></ConditionComponent>
    

    2023-04-18 14 17 22.png

     

     

    개발자에게 후원하기

    MGtdv7r.png

     

    추천, 구독, 홍보 꼭~ 부탁드립니다.

    여러분의 후원이 빠른 귀농을 가능하게 해줍니다~ 답답한 도시를 벗어나 귀농하고 싶은 개발자~

    감사합니다~

    • 네이버 공유하기
    • 페이스북 공유하기
    • 트위터 공유하기
    • 카카오스토리 공유하기
    추천0 비추천0

    댓글목록

    등록된 댓글이 없습니다.