ide-assi 0.353.0 → 0.355.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -201854,7 +201854,7 @@ class IdeAssi extends HTMLElement
201854
201854
 
201855
201855
  //setTimeout(() => {
201856
201856
  const src1 = `
201857
- import React, { useRef, useEffect } from "react";
201857
+ import React, { useRef, useEffect } from "react";
201858
201858
  import { api, ai } from "ide-assi";
201859
201859
  import ninegrid from "ninegrid2";
201860
201860
 
@@ -201892,6 +201892,9 @@ const DocManager = () => {
201892
201892
  };
201893
201893
 
201894
201894
  const handleClassicSearch = () => {
201895
+ if (!gridRef.current) return;
201896
+ gridRef.current.classList.add("loading");
201897
+
201895
201898
  const form2Element = ninegrid.querySelector(".form2", tabRef.current);
201896
201899
  const params = form2Element ? form2Element.getData() : {};
201897
201900
  selectList(params);
@@ -202023,7 +202026,7 @@ export default DocManager;
202023
202026
  `;
202024
202027
 
202025
202028
  const src2 = `
202026
- import React, { useRef, useEffect } from 'react';
202029
+ import React, { useRef, useEffect } from "react";
202027
202030
  import { api, ai } from "ide-assi";
202028
202031
  import ninegrid from "ninegrid2";
202029
202032
 
@@ -202031,72 +202034,73 @@ const DocManager = () => {
202031
202034
  const tabRef = useRef(null);
202032
202035
  const gridRef = useRef(null);
202033
202036
 
202034
- const toCamelCase = (s) => {
202035
- return s.toLowerCase().replace(/_([a-z])/g, (g) => g[1].toUpperCase());
202037
+ const selectList = async (params) => {
202038
+ if (!gridRef.current) return;
202039
+ gridRef.current.classList.add("loading");
202040
+ api.post(\`/api/tmpl-a/doc-manager/selectList\`, params).then((res) => {
202041
+ gridRef.current.data.source = res.list;
202042
+ });
202036
202043
  };
202037
202044
 
202038
- const tableDefinitions = JSON.parse(\`{"list":[{"columns":[{"COLUMN_NAME":"doc_id","COLUMN_ID":1,"COLUMN_COMMENT":"문서ID"},{"COLUMN_NAME":"doc_nm","COLUMN_ID":2,"COLUMN_COMMENT":"문서명"},{"COLUMN_NAME":"amt","COLUMN_ID":3,"COLUMN_COMMENT":"매출액"},{"COLUMN_NAME":"insert_user","COLUMN_ID":4,"COLUMN_COMMENT":"최초등록자"},{"COLUMN_NAME":"insert_dt","COLUMN_ID":5,"COLUMN_COMMENT":"최초등록일"},{"COLUMN_NAME":"update_user","COLUMN_ID":6,"COLUMN_COMMENT":"최종수정자"},{"COLUMN_NAME":"update_dt","COLUMN_ID":7,"COLUMN_COMMENT":"최종수정일"}],"table":"t_doc"},{"columns":[{"COLUMN_NAME":"file_id","COLUMN_ID":1,"COLUMN_COMMENT":""},{"COLUMN_NAME":"doc_id","COLUMN_ID":2,"COLUMN_COMMENT":""},{"COLUMN_NAME":"download_cnt","COLUMN_ID":3,"COLUMN_COMMENT":""},{"COLUMN_NAME":"file_nm","COLUMN_ID":4,"COLUMN_COMMENT":""},{"COLUMN_NAME":"file_size","COLUMN_ID":5,"COLUMN_COMMENT":""},{"COLUMN_NAME":"file_contents","COLUMN_ID":6,"COLUMN_COMMENT":""},{"COLUMN_NAME":"insert_user","COLUMN_ID":7,"COLUMN_COMMENT":""},{"COLUMN_NAME":"insert_dt","COLUMN_ID":8,"COLUMN_COMMENT":""}],"table":"t_doc_file"},{"columns":[{"COLUMN_NAME":"file_id","COLUMN_ID":1,"COLUMN_COMMENT":""},{"COLUMN_NAME":"page","COLUMN_ID":2,"COLUMN_COMMENT":""},{"COLUMN_NAME":"text","COLUMN_ID":3,"COLUMN_COMMENT":""},{"COLUMN_NAME":"image","COLUMN_ID":4,"COLUMN_COMMENT":""},{"COLUMN_NAME":"vector_text","COLUMN_ID":5,"COLUMN_COMMENT":""},{"COLUMN_NAME":"vector_image","COLUMN_ID":6,"COLUMN_COMMENT":""}],"table":"t_doc_file_page"}]}\`);
202039
- const mainTableColumns = tableDefinitions.list[0].columns;
202045
+ const handleNaturalLanguageSearch = async () => {
202046
+ const searchTextElement = ninegrid.querySelector("#searchText", tabRef.current);
202047
+ const searchText = searchTextElement ? searchTextElement.value : "";
202040
202048
 
202041
- const selectList = async (formData = {}) => {
202042
202049
  if (!gridRef.current) return;
202043
-
202044
202050
  gridRef.current.classList.add("loading");
202045
- /**
202046
- const form1Data = ninegrid.querySelector(".form1", tabRef.current).getData();
202047
- const form2Data = ninegrid.querySelector(".form2", tabRef.current).getData();
202048
- const formData = { ...form1Data, ...form2Data };
202049
202051
 
202050
- const formData1 = {
202051
- "_whereClause": await getWhere(),
202052
+ let params = {};
202053
+ if (searchText) {
202054
+ params = {
202055
+ _whereClause: await ai.generateWhereCause(
202056
+ "tmpla/DocManagerMapper.xml",
202057
+ "selectList",
202058
+ searchText,
202059
+ import.meta.env.VITE_GEMINI_API_KEY
202060
+ ),
202061
+ };
202052
202062
  }
202053
- console.log(formData1);
202054
- */
202055
-
202056
- console.log(formData);
202057
-
202058
- api.post(\`/api/tmpl-a/doc-manager/selectList\`, formData).then((res) => {
202059
- gridRef.current.data.source = res.list;
202060
- });
202063
+ selectList(params);
202061
202064
  };
202062
202065
 
202063
- const getWhere = async () => {
202064
- return await ai.generateWhereCause("tmpla/DocManagerMapper.xml", "selectList", ninegrid.querySelector("#searchText", tabRef.current).value, import.meta.env.VITE_GEMINI_API_KEY);
202066
+ const handleClassicSearch = () => {
202067
+ if (!gridRef.current) return;
202068
+ gridRef.current.classList.add("loading");
202069
+
202070
+ const form2Element = ninegrid.querySelector(".form2", tabRef.current);
202071
+ const params = form2Element ? form2Element.getData() : {};
202072
+ selectList(params);
202065
202073
  };
202066
202074
 
202067
202075
  useEffect(() => {
202068
- selectList();
202076
+ selectList({});
202069
202077
 
202070
- const searchTextInput = ninegrid.querySelector("#searchText", tabRef.current);
202078
+ const searchTextElement = ninegrid.querySelector("#searchText", tabRef.current);
202071
202079
  const searchButton = ninegrid.querySelector(".search", tabRef.current);
202072
202080
 
202073
- const handleSearchTextKeydown = (e) => {
202074
- if (e.key === 'Enter' && !e.isComposing) {
202075
-
202076
- //getWhere();
202077
- getWhere().then(res => {
202078
- selectList({"_whereClause":res});
202079
- });
202081
+ const handleKeyDown = (e) => {
202082
+ if (e.key === "Enter" && !e.isComposing) {
202083
+ handleNaturalLanguageSearch();
202080
202084
  }
202081
202085
  };
202082
202086
 
202083
- const handleSearchButtonClick = () => {
202084
- selectList(ninegrid.querySelector(".form2", tabRef.current).getData());
202087
+ const handleClick = () => {
202088
+ handleClassicSearch();
202085
202089
  };
202086
202090
 
202087
- if (searchTextInput) {
202088
- searchTextInput.addEventListener('keydown', handleSearchTextKeydown);
202091
+ if (searchTextElement) {
202092
+ searchTextElement.addEventListener("keydown", handleKeyDown);
202089
202093
  }
202090
202094
  if (searchButton) {
202091
- searchButton.addEventListener('click', handleSearchButtonClick);
202095
+ searchButton.addEventListener("click", handleClick);
202092
202096
  }
202093
202097
 
202094
202098
  return () => {
202095
- if (searchTextInput) {
202096
- searchTextInput.removeEventListener('keydown', handleSearchTextKeydown);
202099
+ if (searchTextElement) {
202100
+ searchTextElement.removeEventListener("keydown", handleKeyDown);
202097
202101
  }
202098
202102
  if (searchButton) {
202099
- searchButton.removeEventListener('click', handleSearchButtonClick);
202103
+ searchButton.removeEventListener("click", handleClick);
202100
202104
  }
202101
202105
  };
202102
202106
  }, []);
@@ -202108,19 +202112,21 @@ const DocManager = () => {
202108
202112
  <nx-tab theme="theme-3" ref={tabRef}>
202109
202113
  <nx-tab-page caption="자연어 검색">
202110
202114
  <nx-form className="form1">
202111
- <input type="text" id="searchText" name="searchText"
202112
- placeholder="자연어 검색어를 입력하세요 (ex: 작성자가 홍길동인 데이타를 찾아줘)"/>
202115
+ <input
202116
+ type="text"
202117
+ id="searchText"
202118
+ name="searchText"
202119
+ placeholder="자연어 검색어를 입력하세요 (ex: 작성자가 홍길동인 데이타를 찾아줘)"
202120
+ />
202113
202121
  </nx-form>
202114
202122
  </nx-tab-page>
202115
202123
  <nx-tab-page caption="클래식 검색">
202116
202124
  <nx-form className="form2">
202117
- <label>문서ID: <input type="text" name="docId"/></label>
202118
- <label>문서명: <input type="text" name="docNm"/></label>
202119
- <label>매출액: <input type="number" name="amt"/></label>
202120
- <label>최초등록자: <input type="text" name="insertUser"/></label>
202121
- <label>최초등록일: <input type="text" name="insertDt"/></label>
202122
- <label>최종수정자: <input type="text" name="updateUser"/></label>
202123
- <label>최종수정일: <input type="text" name="updateDt"/></label>
202125
+ <label>문서명: <input type="text" name="docNm" /></label>
202126
+ <label>매출액:
202127
+ <input type="number" name="minAmt" placeholder="최소" /> ~
202128
+ <input type="number" name="maxAmt" placeholder="최대" />
202129
+ </label>
202124
202130
  </nx-form>
202125
202131
  <button className="search">검색</button>
202126
202132
  </nx-tab-page>
@@ -202128,37 +202134,56 @@ const DocManager = () => {
202128
202134
 
202129
202135
  <div className="grid-wrapper">
202130
202136
  <nine-grid
202131
- ref={gridRef}
202132
- caption="문서관리"
202133
- select-type="row"
202134
- show-title-bar="true"
202135
- show-menu-icon="true"
202136
- show-status-bar="true"
202137
- enable-fixed-col="true"
202138
- row-resizable="false"
202139
- col-movable="true"
202140
- >
202137
+ ref={gridRef}
202138
+ caption="매출 문서 관리"
202139
+ select-type="row"
202140
+ show-title-bar="true"
202141
+ show-menu-icon="true"
202142
+ show-status-bar="true"
202143
+ enable-fixed-col="true"
202144
+ row-resizable="false"
202145
+ col-movable="true"
202146
+ >
202141
202147
  <table>
202142
202148
  <colgroup>
202143
- <col width="50" fixed="left" background-color="gray"/>
202144
- {mainTableColumns.map((col) => (
202145
- <col key={col.COLUMN_ID} width="150"/>
202146
- ))}
202149
+ <col width="50" fixed="left" background-color="gray" />
202150
+ <col width="100" />
202151
+ <col width="120" />
202152
+ <col width="100" />
202153
+ <col width="200" />
202154
+ <col width="100" />
202155
+ <col width="150" />
202156
+ <col width="150" />
202147
202157
  </colgroup>
202148
202158
  <thead>
202149
202159
  <tr>
202150
202160
  <th>No.</th>
202151
- {mainTableColumns.map((col) => (
202152
- <th key={col.COLUMN_ID}>{col.COLUMN_COMMENT || col.COLUMN_NAME}</th>
202153
- ))}
202161
+ <th>문서ID</th>
202162
+ <th>매출액</th>
202163
+ <th>최종수정자</th>
202164
+ <th>문서명</th>
202165
+ <th>최초등록자</th>
202166
+ <th>최초등록일</th>
202167
+ <th>최종수정일</th>
202154
202168
  </tr>
202155
202169
  </thead>
202156
202170
  <tbody>
202157
202171
  <tr>
202158
- <th><ng-row-indicator/></th>
202159
- {mainTableColumns.map((col) => (
202160
- <td key={col.COLUMN_ID} data-bind={toCamelCase(col.COLUMN_NAME)}></td>
202161
- ))}
202172
+ <th><ng-row-indicator /></th>
202173
+ <td data-bind="docId" text-align="center"></td>
202174
+ <td
202175
+ data-bind="amt"
202176
+ data-expr="data.amt.toLocaleString()"
202177
+ text-align="right"
202178
+ show-icon="true"
202179
+ icon-type="sphere"
202180
+ icon-color="data.amt >= 2000 ? 'red' : 'gray'"
202181
+ ></td>
202182
+ <td data-bind="updateUser" text-align="center"></td>
202183
+ <td data-bind="docNm" text-align="left"></td>
202184
+ <td data-bind="insertUser" text-align="center"></td>
202185
+ <td data-bind="insertDt" text-align="center"></td>
202186
+ <td data-bind="updateDt" text-align="center"></td>
202162
202187
  </tr>
202163
202188
  </tbody>
202164
202189
  </table>
@@ -201850,7 +201850,7 @@ class IdeAssi extends HTMLElement
201850
201850
 
201851
201851
  //setTimeout(() => {
201852
201852
  const src1 = `
201853
- import React, { useRef, useEffect } from "react";
201853
+ import React, { useRef, useEffect } from "react";
201854
201854
  import { api, ai } from "ide-assi";
201855
201855
  import ninegrid from "ninegrid2";
201856
201856
 
@@ -201888,6 +201888,9 @@ const DocManager = () => {
201888
201888
  };
201889
201889
 
201890
201890
  const handleClassicSearch = () => {
201891
+ if (!gridRef.current) return;
201892
+ gridRef.current.classList.add("loading");
201893
+
201891
201894
  const form2Element = ninegrid.querySelector(".form2", tabRef.current);
201892
201895
  const params = form2Element ? form2Element.getData() : {};
201893
201896
  selectList(params);
@@ -202019,7 +202022,7 @@ export default DocManager;
202019
202022
  `;
202020
202023
 
202021
202024
  const src2 = `
202022
- import React, { useRef, useEffect } from 'react';
202025
+ import React, { useRef, useEffect } from "react";
202023
202026
  import { api, ai } from "ide-assi";
202024
202027
  import ninegrid from "ninegrid2";
202025
202028
 
@@ -202027,72 +202030,73 @@ const DocManager = () => {
202027
202030
  const tabRef = useRef(null);
202028
202031
  const gridRef = useRef(null);
202029
202032
 
202030
- const toCamelCase = (s) => {
202031
- return s.toLowerCase().replace(/_([a-z])/g, (g) => g[1].toUpperCase());
202033
+ const selectList = async (params) => {
202034
+ if (!gridRef.current) return;
202035
+ gridRef.current.classList.add("loading");
202036
+ api.post(\`/api/tmpl-a/doc-manager/selectList\`, params).then((res) => {
202037
+ gridRef.current.data.source = res.list;
202038
+ });
202032
202039
  };
202033
202040
 
202034
- const tableDefinitions = JSON.parse(\`{"list":[{"columns":[{"COLUMN_NAME":"doc_id","COLUMN_ID":1,"COLUMN_COMMENT":"문서ID"},{"COLUMN_NAME":"doc_nm","COLUMN_ID":2,"COLUMN_COMMENT":"문서명"},{"COLUMN_NAME":"amt","COLUMN_ID":3,"COLUMN_COMMENT":"매출액"},{"COLUMN_NAME":"insert_user","COLUMN_ID":4,"COLUMN_COMMENT":"최초등록자"},{"COLUMN_NAME":"insert_dt","COLUMN_ID":5,"COLUMN_COMMENT":"최초등록일"},{"COLUMN_NAME":"update_user","COLUMN_ID":6,"COLUMN_COMMENT":"최종수정자"},{"COLUMN_NAME":"update_dt","COLUMN_ID":7,"COLUMN_COMMENT":"최종수정일"}],"table":"t_doc"},{"columns":[{"COLUMN_NAME":"file_id","COLUMN_ID":1,"COLUMN_COMMENT":""},{"COLUMN_NAME":"doc_id","COLUMN_ID":2,"COLUMN_COMMENT":""},{"COLUMN_NAME":"download_cnt","COLUMN_ID":3,"COLUMN_COMMENT":""},{"COLUMN_NAME":"file_nm","COLUMN_ID":4,"COLUMN_COMMENT":""},{"COLUMN_NAME":"file_size","COLUMN_ID":5,"COLUMN_COMMENT":""},{"COLUMN_NAME":"file_contents","COLUMN_ID":6,"COLUMN_COMMENT":""},{"COLUMN_NAME":"insert_user","COLUMN_ID":7,"COLUMN_COMMENT":""},{"COLUMN_NAME":"insert_dt","COLUMN_ID":8,"COLUMN_COMMENT":""}],"table":"t_doc_file"},{"columns":[{"COLUMN_NAME":"file_id","COLUMN_ID":1,"COLUMN_COMMENT":""},{"COLUMN_NAME":"page","COLUMN_ID":2,"COLUMN_COMMENT":""},{"COLUMN_NAME":"text","COLUMN_ID":3,"COLUMN_COMMENT":""},{"COLUMN_NAME":"image","COLUMN_ID":4,"COLUMN_COMMENT":""},{"COLUMN_NAME":"vector_text","COLUMN_ID":5,"COLUMN_COMMENT":""},{"COLUMN_NAME":"vector_image","COLUMN_ID":6,"COLUMN_COMMENT":""}],"table":"t_doc_file_page"}]}\`);
202035
- const mainTableColumns = tableDefinitions.list[0].columns;
202041
+ const handleNaturalLanguageSearch = async () => {
202042
+ const searchTextElement = ninegrid.querySelector("#searchText", tabRef.current);
202043
+ const searchText = searchTextElement ? searchTextElement.value : "";
202036
202044
 
202037
- const selectList = async (formData = {}) => {
202038
202045
  if (!gridRef.current) return;
202039
-
202040
202046
  gridRef.current.classList.add("loading");
202041
- /**
202042
- const form1Data = ninegrid.querySelector(".form1", tabRef.current).getData();
202043
- const form2Data = ninegrid.querySelector(".form2", tabRef.current).getData();
202044
- const formData = { ...form1Data, ...form2Data };
202045
202047
 
202046
- const formData1 = {
202047
- "_whereClause": await getWhere(),
202048
+ let params = {};
202049
+ if (searchText) {
202050
+ params = {
202051
+ _whereClause: await ai.generateWhereCause(
202052
+ "tmpla/DocManagerMapper.xml",
202053
+ "selectList",
202054
+ searchText,
202055
+ import.meta.env.VITE_GEMINI_API_KEY
202056
+ ),
202057
+ };
202048
202058
  }
202049
- console.log(formData1);
202050
- */
202051
-
202052
- console.log(formData);
202053
-
202054
- api.post(\`/api/tmpl-a/doc-manager/selectList\`, formData).then((res) => {
202055
- gridRef.current.data.source = res.list;
202056
- });
202059
+ selectList(params);
202057
202060
  };
202058
202061
 
202059
- const getWhere = async () => {
202060
- return await ai.generateWhereCause("tmpla/DocManagerMapper.xml", "selectList", ninegrid.querySelector("#searchText", tabRef.current).value, import.meta.env.VITE_GEMINI_API_KEY);
202062
+ const handleClassicSearch = () => {
202063
+ if (!gridRef.current) return;
202064
+ gridRef.current.classList.add("loading");
202065
+
202066
+ const form2Element = ninegrid.querySelector(".form2", tabRef.current);
202067
+ const params = form2Element ? form2Element.getData() : {};
202068
+ selectList(params);
202061
202069
  };
202062
202070
 
202063
202071
  useEffect(() => {
202064
- selectList();
202072
+ selectList({});
202065
202073
 
202066
- const searchTextInput = ninegrid.querySelector("#searchText", tabRef.current);
202074
+ const searchTextElement = ninegrid.querySelector("#searchText", tabRef.current);
202067
202075
  const searchButton = ninegrid.querySelector(".search", tabRef.current);
202068
202076
 
202069
- const handleSearchTextKeydown = (e) => {
202070
- if (e.key === 'Enter' && !e.isComposing) {
202071
-
202072
- //getWhere();
202073
- getWhere().then(res => {
202074
- selectList({"_whereClause":res});
202075
- });
202077
+ const handleKeyDown = (e) => {
202078
+ if (e.key === "Enter" && !e.isComposing) {
202079
+ handleNaturalLanguageSearch();
202076
202080
  }
202077
202081
  };
202078
202082
 
202079
- const handleSearchButtonClick = () => {
202080
- selectList(ninegrid.querySelector(".form2", tabRef.current).getData());
202083
+ const handleClick = () => {
202084
+ handleClassicSearch();
202081
202085
  };
202082
202086
 
202083
- if (searchTextInput) {
202084
- searchTextInput.addEventListener('keydown', handleSearchTextKeydown);
202087
+ if (searchTextElement) {
202088
+ searchTextElement.addEventListener("keydown", handleKeyDown);
202085
202089
  }
202086
202090
  if (searchButton) {
202087
- searchButton.addEventListener('click', handleSearchButtonClick);
202091
+ searchButton.addEventListener("click", handleClick);
202088
202092
  }
202089
202093
 
202090
202094
  return () => {
202091
- if (searchTextInput) {
202092
- searchTextInput.removeEventListener('keydown', handleSearchTextKeydown);
202095
+ if (searchTextElement) {
202096
+ searchTextElement.removeEventListener("keydown", handleKeyDown);
202093
202097
  }
202094
202098
  if (searchButton) {
202095
- searchButton.removeEventListener('click', handleSearchButtonClick);
202099
+ searchButton.removeEventListener("click", handleClick);
202096
202100
  }
202097
202101
  };
202098
202102
  }, []);
@@ -202104,19 +202108,21 @@ const DocManager = () => {
202104
202108
  <nx-tab theme="theme-3" ref={tabRef}>
202105
202109
  <nx-tab-page caption="자연어 검색">
202106
202110
  <nx-form className="form1">
202107
- <input type="text" id="searchText" name="searchText"
202108
- placeholder="자연어 검색어를 입력하세요 (ex: 작성자가 홍길동인 데이타를 찾아줘)"/>
202111
+ <input
202112
+ type="text"
202113
+ id="searchText"
202114
+ name="searchText"
202115
+ placeholder="자연어 검색어를 입력하세요 (ex: 작성자가 홍길동인 데이타를 찾아줘)"
202116
+ />
202109
202117
  </nx-form>
202110
202118
  </nx-tab-page>
202111
202119
  <nx-tab-page caption="클래식 검색">
202112
202120
  <nx-form className="form2">
202113
- <label>문서ID: <input type="text" name="docId"/></label>
202114
- <label>문서명: <input type="text" name="docNm"/></label>
202115
- <label>매출액: <input type="number" name="amt"/></label>
202116
- <label>최초등록자: <input type="text" name="insertUser"/></label>
202117
- <label>최초등록일: <input type="text" name="insertDt"/></label>
202118
- <label>최종수정자: <input type="text" name="updateUser"/></label>
202119
- <label>최종수정일: <input type="text" name="updateDt"/></label>
202121
+ <label>문서명: <input type="text" name="docNm" /></label>
202122
+ <label>매출액:
202123
+ <input type="number" name="minAmt" placeholder="최소" /> ~
202124
+ <input type="number" name="maxAmt" placeholder="최대" />
202125
+ </label>
202120
202126
  </nx-form>
202121
202127
  <button className="search">검색</button>
202122
202128
  </nx-tab-page>
@@ -202124,37 +202130,56 @@ const DocManager = () => {
202124
202130
 
202125
202131
  <div className="grid-wrapper">
202126
202132
  <nine-grid
202127
- ref={gridRef}
202128
- caption="문서관리"
202129
- select-type="row"
202130
- show-title-bar="true"
202131
- show-menu-icon="true"
202132
- show-status-bar="true"
202133
- enable-fixed-col="true"
202134
- row-resizable="false"
202135
- col-movable="true"
202136
- >
202133
+ ref={gridRef}
202134
+ caption="매출 문서 관리"
202135
+ select-type="row"
202136
+ show-title-bar="true"
202137
+ show-menu-icon="true"
202138
+ show-status-bar="true"
202139
+ enable-fixed-col="true"
202140
+ row-resizable="false"
202141
+ col-movable="true"
202142
+ >
202137
202143
  <table>
202138
202144
  <colgroup>
202139
- <col width="50" fixed="left" background-color="gray"/>
202140
- {mainTableColumns.map((col) => (
202141
- <col key={col.COLUMN_ID} width="150"/>
202142
- ))}
202145
+ <col width="50" fixed="left" background-color="gray" />
202146
+ <col width="100" />
202147
+ <col width="120" />
202148
+ <col width="100" />
202149
+ <col width="200" />
202150
+ <col width="100" />
202151
+ <col width="150" />
202152
+ <col width="150" />
202143
202153
  </colgroup>
202144
202154
  <thead>
202145
202155
  <tr>
202146
202156
  <th>No.</th>
202147
- {mainTableColumns.map((col) => (
202148
- <th key={col.COLUMN_ID}>{col.COLUMN_COMMENT || col.COLUMN_NAME}</th>
202149
- ))}
202157
+ <th>문서ID</th>
202158
+ <th>매출액</th>
202159
+ <th>최종수정자</th>
202160
+ <th>문서명</th>
202161
+ <th>최초등록자</th>
202162
+ <th>최초등록일</th>
202163
+ <th>최종수정일</th>
202150
202164
  </tr>
202151
202165
  </thead>
202152
202166
  <tbody>
202153
202167
  <tr>
202154
- <th><ng-row-indicator/></th>
202155
- {mainTableColumns.map((col) => (
202156
- <td key={col.COLUMN_ID} data-bind={toCamelCase(col.COLUMN_NAME)}></td>
202157
- ))}
202168
+ <th><ng-row-indicator /></th>
202169
+ <td data-bind="docId" text-align="center"></td>
202170
+ <td
202171
+ data-bind="amt"
202172
+ data-expr="data.amt.toLocaleString()"
202173
+ text-align="right"
202174
+ show-icon="true"
202175
+ icon-type="sphere"
202176
+ icon-color="data.amt >= 2000 ? 'red' : 'gray'"
202177
+ ></td>
202178
+ <td data-bind="updateUser" text-align="center"></td>
202179
+ <td data-bind="docNm" text-align="left"></td>
202180
+ <td data-bind="insertUser" text-align="center"></td>
202181
+ <td data-bind="insertDt" text-align="center"></td>
202182
+ <td data-bind="updateDt" text-align="center"></td>
202158
202183
  </tr>
202159
202184
  </tbody>
202160
202185
  </table>
@@ -124,7 +124,7 @@ export class IdeAssi extends HTMLElement
124
124
 
125
125
  //setTimeout(() => {
126
126
  const src1 = `
127
- import React, { useRef, useEffect } from "react";
127
+ import React, { useRef, useEffect } from "react";
128
128
  import { api, ai } from "ide-assi";
129
129
  import ninegrid from "ninegrid2";
130
130
 
@@ -162,6 +162,9 @@ const DocManager = () => {
162
162
  };
163
163
 
164
164
  const handleClassicSearch = () => {
165
+ if (!gridRef.current) return;
166
+ gridRef.current.classList.add("loading");
167
+
165
168
  const form2Element = ninegrid.querySelector(".form2", tabRef.current);
166
169
  const params = form2Element ? form2Element.getData() : {};
167
170
  selectList(params);
@@ -293,7 +296,7 @@ export default DocManager;
293
296
  `;
294
297
 
295
298
  const src2 = `
296
- import React, { useRef, useEffect } from 'react';
299
+ import React, { useRef, useEffect } from "react";
297
300
  import { api, ai } from "ide-assi";
298
301
  import ninegrid from "ninegrid2";
299
302
 
@@ -301,72 +304,73 @@ const DocManager = () => {
301
304
  const tabRef = useRef(null);
302
305
  const gridRef = useRef(null);
303
306
 
304
- const toCamelCase = (s) => {
305
- return s.toLowerCase().replace(/_([a-z])/g, (g) => g[1].toUpperCase());
307
+ const selectList = async (params) => {
308
+ if (!gridRef.current) return;
309
+ gridRef.current.classList.add("loading");
310
+ api.post(\`/api/tmpl-a/doc-manager/selectList\`, params).then((res) => {
311
+ gridRef.current.data.source = res.list;
312
+ });
306
313
  };
307
314
 
308
- const tableDefinitions = JSON.parse(\`{"list":[{"columns":[{"COLUMN_NAME":"doc_id","COLUMN_ID":1,"COLUMN_COMMENT":"문서ID"},{"COLUMN_NAME":"doc_nm","COLUMN_ID":2,"COLUMN_COMMENT":"문서명"},{"COLUMN_NAME":"amt","COLUMN_ID":3,"COLUMN_COMMENT":"매출액"},{"COLUMN_NAME":"insert_user","COLUMN_ID":4,"COLUMN_COMMENT":"최초등록자"},{"COLUMN_NAME":"insert_dt","COLUMN_ID":5,"COLUMN_COMMENT":"최초등록일"},{"COLUMN_NAME":"update_user","COLUMN_ID":6,"COLUMN_COMMENT":"최종수정자"},{"COLUMN_NAME":"update_dt","COLUMN_ID":7,"COLUMN_COMMENT":"최종수정일"}],"table":"t_doc"},{"columns":[{"COLUMN_NAME":"file_id","COLUMN_ID":1,"COLUMN_COMMENT":""},{"COLUMN_NAME":"doc_id","COLUMN_ID":2,"COLUMN_COMMENT":""},{"COLUMN_NAME":"download_cnt","COLUMN_ID":3,"COLUMN_COMMENT":""},{"COLUMN_NAME":"file_nm","COLUMN_ID":4,"COLUMN_COMMENT":""},{"COLUMN_NAME":"file_size","COLUMN_ID":5,"COLUMN_COMMENT":""},{"COLUMN_NAME":"file_contents","COLUMN_ID":6,"COLUMN_COMMENT":""},{"COLUMN_NAME":"insert_user","COLUMN_ID":7,"COLUMN_COMMENT":""},{"COLUMN_NAME":"insert_dt","COLUMN_ID":8,"COLUMN_COMMENT":""}],"table":"t_doc_file"},{"columns":[{"COLUMN_NAME":"file_id","COLUMN_ID":1,"COLUMN_COMMENT":""},{"COLUMN_NAME":"page","COLUMN_ID":2,"COLUMN_COMMENT":""},{"COLUMN_NAME":"text","COLUMN_ID":3,"COLUMN_COMMENT":""},{"COLUMN_NAME":"image","COLUMN_ID":4,"COLUMN_COMMENT":""},{"COLUMN_NAME":"vector_text","COLUMN_ID":5,"COLUMN_COMMENT":""},{"COLUMN_NAME":"vector_image","COLUMN_ID":6,"COLUMN_COMMENT":""}],"table":"t_doc_file_page"}]}\`);
309
- const mainTableColumns = tableDefinitions.list[0].columns;
315
+ const handleNaturalLanguageSearch = async () => {
316
+ const searchTextElement = ninegrid.querySelector("#searchText", tabRef.current);
317
+ const searchText = searchTextElement ? searchTextElement.value : "";
310
318
 
311
- const selectList = async (formData = {}) => {
312
319
  if (!gridRef.current) return;
313
-
314
320
  gridRef.current.classList.add("loading");
315
- /**
316
- const form1Data = ninegrid.querySelector(".form1", tabRef.current).getData();
317
- const form2Data = ninegrid.querySelector(".form2", tabRef.current).getData();
318
- const formData = { ...form1Data, ...form2Data };
319
321
 
320
- const formData1 = {
321
- "_whereClause": await getWhere(),
322
+ let params = {};
323
+ if (searchText) {
324
+ params = {
325
+ _whereClause: await ai.generateWhereCause(
326
+ "tmpla/DocManagerMapper.xml",
327
+ "selectList",
328
+ searchText,
329
+ import.meta.env.VITE_GEMINI_API_KEY
330
+ ),
331
+ };
322
332
  }
323
- console.log(formData1);
324
- */
325
-
326
- console.log(formData);
327
-
328
- api.post(\`/api/tmpl-a/doc-manager/selectList\`, formData).then((res) => {
329
- gridRef.current.data.source = res.list;
330
- });
333
+ selectList(params);
331
334
  };
332
335
 
333
- const getWhere = async () => {
334
- return await ai.generateWhereCause("tmpla/DocManagerMapper.xml", "selectList", ninegrid.querySelector("#searchText", tabRef.current).value, import.meta.env.VITE_GEMINI_API_KEY);
336
+ const handleClassicSearch = () => {
337
+ if (!gridRef.current) return;
338
+ gridRef.current.classList.add("loading");
339
+
340
+ const form2Element = ninegrid.querySelector(".form2", tabRef.current);
341
+ const params = form2Element ? form2Element.getData() : {};
342
+ selectList(params);
335
343
  };
336
344
 
337
345
  useEffect(() => {
338
- selectList();
346
+ selectList({});
339
347
 
340
- const searchTextInput = ninegrid.querySelector("#searchText", tabRef.current);
348
+ const searchTextElement = ninegrid.querySelector("#searchText", tabRef.current);
341
349
  const searchButton = ninegrid.querySelector(".search", tabRef.current);
342
350
 
343
- const handleSearchTextKeydown = (e) => {
344
- if (e.key === 'Enter' && !e.isComposing) {
345
-
346
- //getWhere();
347
- getWhere().then(res => {
348
- selectList({"_whereClause":res});
349
- });
351
+ const handleKeyDown = (e) => {
352
+ if (e.key === "Enter" && !e.isComposing) {
353
+ handleNaturalLanguageSearch();
350
354
  }
351
355
  };
352
356
 
353
- const handleSearchButtonClick = () => {
354
- selectList(ninegrid.querySelector(".form2", tabRef.current).getData());
357
+ const handleClick = () => {
358
+ handleClassicSearch();
355
359
  };
356
360
 
357
- if (searchTextInput) {
358
- searchTextInput.addEventListener('keydown', handleSearchTextKeydown);
361
+ if (searchTextElement) {
362
+ searchTextElement.addEventListener("keydown", handleKeyDown);
359
363
  }
360
364
  if (searchButton) {
361
- searchButton.addEventListener('click', handleSearchButtonClick);
365
+ searchButton.addEventListener("click", handleClick);
362
366
  }
363
367
 
364
368
  return () => {
365
- if (searchTextInput) {
366
- searchTextInput.removeEventListener('keydown', handleSearchTextKeydown);
369
+ if (searchTextElement) {
370
+ searchTextElement.removeEventListener("keydown", handleKeyDown);
367
371
  }
368
372
  if (searchButton) {
369
- searchButton.removeEventListener('click', handleSearchButtonClick);
373
+ searchButton.removeEventListener("click", handleClick);
370
374
  }
371
375
  };
372
376
  }, []);
@@ -378,19 +382,21 @@ const DocManager = () => {
378
382
  <nx-tab theme="theme-3" ref={tabRef}>
379
383
  <nx-tab-page caption="자연어 검색">
380
384
  <nx-form className="form1">
381
- <input type="text" id="searchText" name="searchText"
382
- placeholder="자연어 검색어를 입력하세요 (ex: 작성자가 홍길동인 데이타를 찾아줘)"/>
385
+ <input
386
+ type="text"
387
+ id="searchText"
388
+ name="searchText"
389
+ placeholder="자연어 검색어를 입력하세요 (ex: 작성자가 홍길동인 데이타를 찾아줘)"
390
+ />
383
391
  </nx-form>
384
392
  </nx-tab-page>
385
393
  <nx-tab-page caption="클래식 검색">
386
394
  <nx-form className="form2">
387
- <label>문서ID: <input type="text" name="docId"/></label>
388
- <label>문서명: <input type="text" name="docNm"/></label>
389
- <label>매출액: <input type="number" name="amt"/></label>
390
- <label>최초등록자: <input type="text" name="insertUser"/></label>
391
- <label>최초등록일: <input type="text" name="insertDt"/></label>
392
- <label>최종수정자: <input type="text" name="updateUser"/></label>
393
- <label>최종수정일: <input type="text" name="updateDt"/></label>
395
+ <label>문서명: <input type="text" name="docNm" /></label>
396
+ <label>매출액:
397
+ <input type="number" name="minAmt" placeholder="최소" /> ~
398
+ <input type="number" name="maxAmt" placeholder="최대" />
399
+ </label>
394
400
  </nx-form>
395
401
  <button className="search">검색</button>
396
402
  </nx-tab-page>
@@ -398,37 +404,56 @@ const DocManager = () => {
398
404
 
399
405
  <div className="grid-wrapper">
400
406
  <nine-grid
401
- ref={gridRef}
402
- caption="문서관리"
403
- select-type="row"
404
- show-title-bar="true"
405
- show-menu-icon="true"
406
- show-status-bar="true"
407
- enable-fixed-col="true"
408
- row-resizable="false"
409
- col-movable="true"
410
- >
407
+ ref={gridRef}
408
+ caption="매출 문서 관리"
409
+ select-type="row"
410
+ show-title-bar="true"
411
+ show-menu-icon="true"
412
+ show-status-bar="true"
413
+ enable-fixed-col="true"
414
+ row-resizable="false"
415
+ col-movable="true"
416
+ >
411
417
  <table>
412
418
  <colgroup>
413
- <col width="50" fixed="left" background-color="gray"/>
414
- {mainTableColumns.map((col) => (
415
- <col key={col.COLUMN_ID} width="150"/>
416
- ))}
419
+ <col width="50" fixed="left" background-color="gray" />
420
+ <col width="100" />
421
+ <col width="120" />
422
+ <col width="100" />
423
+ <col width="200" />
424
+ <col width="100" />
425
+ <col width="150" />
426
+ <col width="150" />
417
427
  </colgroup>
418
428
  <thead>
419
429
  <tr>
420
430
  <th>No.</th>
421
- {mainTableColumns.map((col) => (
422
- <th key={col.COLUMN_ID}>{col.COLUMN_COMMENT || col.COLUMN_NAME}</th>
423
- ))}
431
+ <th>문서ID</th>
432
+ <th>매출액</th>
433
+ <th>최종수정자</th>
434
+ <th>문서명</th>
435
+ <th>최초등록자</th>
436
+ <th>최초등록일</th>
437
+ <th>최종수정일</th>
424
438
  </tr>
425
439
  </thead>
426
440
  <tbody>
427
441
  <tr>
428
- <th><ng-row-indicator/></th>
429
- {mainTableColumns.map((col) => (
430
- <td key={col.COLUMN_ID} data-bind={toCamelCase(col.COLUMN_NAME)}></td>
431
- ))}
442
+ <th><ng-row-indicator /></th>
443
+ <td data-bind="docId" text-align="center"></td>
444
+ <td
445
+ data-bind="amt"
446
+ data-expr="data.amt.toLocaleString()"
447
+ text-align="right"
448
+ show-icon="true"
449
+ icon-type="sphere"
450
+ icon-color="data.amt >= 2000 ? 'red' : 'gray'"
451
+ ></td>
452
+ <td data-bind="updateUser" text-align="center"></td>
453
+ <td data-bind="docNm" text-align="left"></td>
454
+ <td data-bind="insertUser" text-align="center"></td>
455
+ <td data-bind="insertDt" text-align="center"></td>
456
+ <td data-bind="updateDt" text-align="center"></td>
432
457
  </tr>
433
458
  </tbody>
434
459
  </table>
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ide-assi",
3
3
  "type": "module",
4
- "version": "0.353.0",
4
+ "version": "0.355.0",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "exports": {
@@ -124,7 +124,7 @@ export class IdeAssi extends HTMLElement
124
124
 
125
125
  //setTimeout(() => {
126
126
  const src1 = `
127
- import React, { useRef, useEffect } from "react";
127
+ import React, { useRef, useEffect } from "react";
128
128
  import { api, ai } from "ide-assi";
129
129
  import ninegrid from "ninegrid2";
130
130
 
@@ -162,6 +162,9 @@ const DocManager = () => {
162
162
  };
163
163
 
164
164
  const handleClassicSearch = () => {
165
+ if (!gridRef.current) return;
166
+ gridRef.current.classList.add("loading");
167
+
165
168
  const form2Element = ninegrid.querySelector(".form2", tabRef.current);
166
169
  const params = form2Element ? form2Element.getData() : {};
167
170
  selectList(params);
@@ -293,7 +296,7 @@ export default DocManager;
293
296
  `;
294
297
 
295
298
  const src2 = `
296
- import React, { useRef, useEffect } from 'react';
299
+ import React, { useRef, useEffect } from "react";
297
300
  import { api, ai } from "ide-assi";
298
301
  import ninegrid from "ninegrid2";
299
302
 
@@ -301,72 +304,73 @@ const DocManager = () => {
301
304
  const tabRef = useRef(null);
302
305
  const gridRef = useRef(null);
303
306
 
304
- const toCamelCase = (s) => {
305
- return s.toLowerCase().replace(/_([a-z])/g, (g) => g[1].toUpperCase());
307
+ const selectList = async (params) => {
308
+ if (!gridRef.current) return;
309
+ gridRef.current.classList.add("loading");
310
+ api.post(\`/api/tmpl-a/doc-manager/selectList\`, params).then((res) => {
311
+ gridRef.current.data.source = res.list;
312
+ });
306
313
  };
307
314
 
308
- const tableDefinitions = JSON.parse(\`{"list":[{"columns":[{"COLUMN_NAME":"doc_id","COLUMN_ID":1,"COLUMN_COMMENT":"문서ID"},{"COLUMN_NAME":"doc_nm","COLUMN_ID":2,"COLUMN_COMMENT":"문서명"},{"COLUMN_NAME":"amt","COLUMN_ID":3,"COLUMN_COMMENT":"매출액"},{"COLUMN_NAME":"insert_user","COLUMN_ID":4,"COLUMN_COMMENT":"최초등록자"},{"COLUMN_NAME":"insert_dt","COLUMN_ID":5,"COLUMN_COMMENT":"최초등록일"},{"COLUMN_NAME":"update_user","COLUMN_ID":6,"COLUMN_COMMENT":"최종수정자"},{"COLUMN_NAME":"update_dt","COLUMN_ID":7,"COLUMN_COMMENT":"최종수정일"}],"table":"t_doc"},{"columns":[{"COLUMN_NAME":"file_id","COLUMN_ID":1,"COLUMN_COMMENT":""},{"COLUMN_NAME":"doc_id","COLUMN_ID":2,"COLUMN_COMMENT":""},{"COLUMN_NAME":"download_cnt","COLUMN_ID":3,"COLUMN_COMMENT":""},{"COLUMN_NAME":"file_nm","COLUMN_ID":4,"COLUMN_COMMENT":""},{"COLUMN_NAME":"file_size","COLUMN_ID":5,"COLUMN_COMMENT":""},{"COLUMN_NAME":"file_contents","COLUMN_ID":6,"COLUMN_COMMENT":""},{"COLUMN_NAME":"insert_user","COLUMN_ID":7,"COLUMN_COMMENT":""},{"COLUMN_NAME":"insert_dt","COLUMN_ID":8,"COLUMN_COMMENT":""}],"table":"t_doc_file"},{"columns":[{"COLUMN_NAME":"file_id","COLUMN_ID":1,"COLUMN_COMMENT":""},{"COLUMN_NAME":"page","COLUMN_ID":2,"COLUMN_COMMENT":""},{"COLUMN_NAME":"text","COLUMN_ID":3,"COLUMN_COMMENT":""},{"COLUMN_NAME":"image","COLUMN_ID":4,"COLUMN_COMMENT":""},{"COLUMN_NAME":"vector_text","COLUMN_ID":5,"COLUMN_COMMENT":""},{"COLUMN_NAME":"vector_image","COLUMN_ID":6,"COLUMN_COMMENT":""}],"table":"t_doc_file_page"}]}\`);
309
- const mainTableColumns = tableDefinitions.list[0].columns;
315
+ const handleNaturalLanguageSearch = async () => {
316
+ const searchTextElement = ninegrid.querySelector("#searchText", tabRef.current);
317
+ const searchText = searchTextElement ? searchTextElement.value : "";
310
318
 
311
- const selectList = async (formData = {}) => {
312
319
  if (!gridRef.current) return;
313
-
314
320
  gridRef.current.classList.add("loading");
315
- /**
316
- const form1Data = ninegrid.querySelector(".form1", tabRef.current).getData();
317
- const form2Data = ninegrid.querySelector(".form2", tabRef.current).getData();
318
- const formData = { ...form1Data, ...form2Data };
319
321
 
320
- const formData1 = {
321
- "_whereClause": await getWhere(),
322
+ let params = {};
323
+ if (searchText) {
324
+ params = {
325
+ _whereClause: await ai.generateWhereCause(
326
+ "tmpla/DocManagerMapper.xml",
327
+ "selectList",
328
+ searchText,
329
+ import.meta.env.VITE_GEMINI_API_KEY
330
+ ),
331
+ };
322
332
  }
323
- console.log(formData1);
324
- */
325
-
326
- console.log(formData);
327
-
328
- api.post(\`/api/tmpl-a/doc-manager/selectList\`, formData).then((res) => {
329
- gridRef.current.data.source = res.list;
330
- });
333
+ selectList(params);
331
334
  };
332
335
 
333
- const getWhere = async () => {
334
- return await ai.generateWhereCause("tmpla/DocManagerMapper.xml", "selectList", ninegrid.querySelector("#searchText", tabRef.current).value, import.meta.env.VITE_GEMINI_API_KEY);
336
+ const handleClassicSearch = () => {
337
+ if (!gridRef.current) return;
338
+ gridRef.current.classList.add("loading");
339
+
340
+ const form2Element = ninegrid.querySelector(".form2", tabRef.current);
341
+ const params = form2Element ? form2Element.getData() : {};
342
+ selectList(params);
335
343
  };
336
344
 
337
345
  useEffect(() => {
338
- selectList();
346
+ selectList({});
339
347
 
340
- const searchTextInput = ninegrid.querySelector("#searchText", tabRef.current);
348
+ const searchTextElement = ninegrid.querySelector("#searchText", tabRef.current);
341
349
  const searchButton = ninegrid.querySelector(".search", tabRef.current);
342
350
 
343
- const handleSearchTextKeydown = (e) => {
344
- if (e.key === 'Enter' && !e.isComposing) {
345
-
346
- //getWhere();
347
- getWhere().then(res => {
348
- selectList({"_whereClause":res});
349
- });
351
+ const handleKeyDown = (e) => {
352
+ if (e.key === "Enter" && !e.isComposing) {
353
+ handleNaturalLanguageSearch();
350
354
  }
351
355
  };
352
356
 
353
- const handleSearchButtonClick = () => {
354
- selectList(ninegrid.querySelector(".form2", tabRef.current).getData());
357
+ const handleClick = () => {
358
+ handleClassicSearch();
355
359
  };
356
360
 
357
- if (searchTextInput) {
358
- searchTextInput.addEventListener('keydown', handleSearchTextKeydown);
361
+ if (searchTextElement) {
362
+ searchTextElement.addEventListener("keydown", handleKeyDown);
359
363
  }
360
364
  if (searchButton) {
361
- searchButton.addEventListener('click', handleSearchButtonClick);
365
+ searchButton.addEventListener("click", handleClick);
362
366
  }
363
367
 
364
368
  return () => {
365
- if (searchTextInput) {
366
- searchTextInput.removeEventListener('keydown', handleSearchTextKeydown);
369
+ if (searchTextElement) {
370
+ searchTextElement.removeEventListener("keydown", handleKeyDown);
367
371
  }
368
372
  if (searchButton) {
369
- searchButton.removeEventListener('click', handleSearchButtonClick);
373
+ searchButton.removeEventListener("click", handleClick);
370
374
  }
371
375
  };
372
376
  }, []);
@@ -378,19 +382,21 @@ const DocManager = () => {
378
382
  <nx-tab theme="theme-3" ref={tabRef}>
379
383
  <nx-tab-page caption="자연어 검색">
380
384
  <nx-form className="form1">
381
- <input type="text" id="searchText" name="searchText"
382
- placeholder="자연어 검색어를 입력하세요 (ex: 작성자가 홍길동인 데이타를 찾아줘)"/>
385
+ <input
386
+ type="text"
387
+ id="searchText"
388
+ name="searchText"
389
+ placeholder="자연어 검색어를 입력하세요 (ex: 작성자가 홍길동인 데이타를 찾아줘)"
390
+ />
383
391
  </nx-form>
384
392
  </nx-tab-page>
385
393
  <nx-tab-page caption="클래식 검색">
386
394
  <nx-form className="form2">
387
- <label>문서ID: <input type="text" name="docId"/></label>
388
- <label>문서명: <input type="text" name="docNm"/></label>
389
- <label>매출액: <input type="number" name="amt"/></label>
390
- <label>최초등록자: <input type="text" name="insertUser"/></label>
391
- <label>최초등록일: <input type="text" name="insertDt"/></label>
392
- <label>최종수정자: <input type="text" name="updateUser"/></label>
393
- <label>최종수정일: <input type="text" name="updateDt"/></label>
395
+ <label>문서명: <input type="text" name="docNm" /></label>
396
+ <label>매출액:
397
+ <input type="number" name="minAmt" placeholder="최소" /> ~
398
+ <input type="number" name="maxAmt" placeholder="최대" />
399
+ </label>
394
400
  </nx-form>
395
401
  <button className="search">검색</button>
396
402
  </nx-tab-page>
@@ -398,37 +404,56 @@ const DocManager = () => {
398
404
 
399
405
  <div className="grid-wrapper">
400
406
  <nine-grid
401
- ref={gridRef}
402
- caption="문서관리"
403
- select-type="row"
404
- show-title-bar="true"
405
- show-menu-icon="true"
406
- show-status-bar="true"
407
- enable-fixed-col="true"
408
- row-resizable="false"
409
- col-movable="true"
410
- >
407
+ ref={gridRef}
408
+ caption="매출 문서 관리"
409
+ select-type="row"
410
+ show-title-bar="true"
411
+ show-menu-icon="true"
412
+ show-status-bar="true"
413
+ enable-fixed-col="true"
414
+ row-resizable="false"
415
+ col-movable="true"
416
+ >
411
417
  <table>
412
418
  <colgroup>
413
- <col width="50" fixed="left" background-color="gray"/>
414
- {mainTableColumns.map((col) => (
415
- <col key={col.COLUMN_ID} width="150"/>
416
- ))}
419
+ <col width="50" fixed="left" background-color="gray" />
420
+ <col width="100" />
421
+ <col width="120" />
422
+ <col width="100" />
423
+ <col width="200" />
424
+ <col width="100" />
425
+ <col width="150" />
426
+ <col width="150" />
417
427
  </colgroup>
418
428
  <thead>
419
429
  <tr>
420
430
  <th>No.</th>
421
- {mainTableColumns.map((col) => (
422
- <th key={col.COLUMN_ID}>{col.COLUMN_COMMENT || col.COLUMN_NAME}</th>
423
- ))}
431
+ <th>문서ID</th>
432
+ <th>매출액</th>
433
+ <th>최종수정자</th>
434
+ <th>문서명</th>
435
+ <th>최초등록자</th>
436
+ <th>최초등록일</th>
437
+ <th>최종수정일</th>
424
438
  </tr>
425
439
  </thead>
426
440
  <tbody>
427
441
  <tr>
428
- <th><ng-row-indicator/></th>
429
- {mainTableColumns.map((col) => (
430
- <td key={col.COLUMN_ID} data-bind={toCamelCase(col.COLUMN_NAME)}></td>
431
- ))}
442
+ <th><ng-row-indicator /></th>
443
+ <td data-bind="docId" text-align="center"></td>
444
+ <td
445
+ data-bind="amt"
446
+ data-expr="data.amt.toLocaleString()"
447
+ text-align="right"
448
+ show-icon="true"
449
+ icon-type="sphere"
450
+ icon-color="data.amt >= 2000 ? 'red' : 'gray'"
451
+ ></td>
452
+ <td data-bind="updateUser" text-align="center"></td>
453
+ <td data-bind="docNm" text-align="left"></td>
454
+ <td data-bind="insertUser" text-align="center"></td>
455
+ <td data-bind="insertDt" text-align="center"></td>
456
+ <td data-bind="updateDt" text-align="center"></td>
432
457
  </tr>
433
458
  </tbody>
434
459
  </table>