ide-assi 0.353.0 → 0.354.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.
@@ -201852,329 +201852,54 @@ class IdeAssi extends HTMLElement
201852
201852
 
201853
201853
  this.shadowRoot.appendChild(document.createElement('ide-diff-popup'));
201854
201854
 
201855
- //setTimeout(() => {
201856
- const src1 = `
201857
- import React, { useRef, useEffect } from "react";
201858
- import { api, ai } from "ide-assi";
201859
- import ninegrid from "ninegrid2";
201860
-
201861
- const DocManager = () => {
201862
- const tabRef = useRef(null);
201863
- const gridRef = useRef(null);
201864
-
201865
- const selectList = async (params) => {
201866
- if (!gridRef.current) return;
201867
- gridRef.current.classList.add("loading");
201868
- api.post(\`/api/tmpl-a/doc-manager/selectList\`, params).then((res) => {
201869
- gridRef.current.data.source = res.list;
201870
- });
201871
- };
201872
-
201873
- const handleNaturalLanguageSearch = async () => {
201874
- const searchTextElement = ninegrid.querySelector("#searchText", tabRef.current);
201875
- const searchText = searchTextElement ? searchTextElement.value : "";
201876
-
201877
- if (!gridRef.current) return;
201878
- gridRef.current.classList.add("loading");
201879
-
201880
- let params = {};
201881
- if (searchText) {
201882
- params = {
201883
- _whereClause: await ai.generateWhereCause(
201884
- "tmpla/DocManagerMapper.xml",
201885
- "selectList",
201886
- searchText,
201887
- import.meta.env.VITE_GEMINI_API_KEY
201888
- ),
201889
- };
201890
- }
201891
- selectList(params);
201892
- };
201893
-
201894
- const handleClassicSearch = () => {
201895
- const form2Element = ninegrid.querySelector(".form2", tabRef.current);
201896
- const params = form2Element ? form2Element.getData() : {};
201897
- selectList(params);
201898
- };
201899
-
201900
- useEffect(() => {
201901
- selectList({});
201855
+ //this.shadowRoot.querySelector("ide-diff-popup").popup(src1, src2);
201902
201856
 
201903
- const searchTextElement = ninegrid.querySelector("#searchText", tabRef.current);
201904
- const searchButton = ninegrid.querySelector(".search", tabRef.current);
201905
-
201906
- const handleKeyDown = (e) => {
201907
- if (e.key === "Enter" && !e.isComposing) {
201908
- handleNaturalLanguageSearch();
201909
- }
201910
- };
201911
-
201912
- const handleClick = () => {
201913
- handleClassicSearch();
201914
- };
201915
-
201916
- if (searchTextElement) {
201917
- searchTextElement.addEventListener("keydown", handleKeyDown);
201918
- }
201919
- if (searchButton) {
201920
- searchButton.addEventListener("click", handleClick);
201921
- }
201922
-
201923
- return () => {
201924
- if (searchTextElement) {
201925
- searchTextElement.removeEventListener("keydown", handleKeyDown);
201926
- }
201927
- if (searchButton) {
201928
- searchButton.removeEventListener("click", handleClick);
201929
- }
201930
- };
201931
- }, []);
201932
-
201933
- return (
201934
- <div className="wrapper">
201935
- <nx-collapse target="nx-tab" className="search-collapse"></nx-collapse>
201936
- <div className="list-wrapper">
201937
- <nx-tab theme="theme-3" ref={tabRef}>
201938
- <nx-tab-page caption="자연어 검색">
201939
- <nx-form className="form1">
201940
- <input
201941
- type="text"
201942
- id="searchText"
201943
- name="searchText"
201944
- placeholder="자연어 검색어를 입력하세요 (ex: 작성자가 홍길동인 데이타를 찾아줘)"
201945
- />
201946
- </nx-form>
201947
- </nx-tab-page>
201948
- <nx-tab-page caption="클래식 검색">
201949
- <nx-form className="form2">
201950
- <label>문서명: <input type="text" name="docNm" /></label>
201951
- <label>매출액:
201952
- <input type="number" name="minAmt" placeholder="최소" /> ~
201953
- <input type="number" name="maxAmt" placeholder="최대" />
201954
- </label>
201955
- </nx-form>
201956
- <button className="search">검색</button>
201957
- </nx-tab-page>
201958
- </nx-tab>
201959
-
201960
- <div className="grid-wrapper">
201961
- <nine-grid
201962
- ref={gridRef}
201963
- caption="문서관리"
201964
- select-type="row"
201965
- show-title-bar="true"
201966
- show-menu-icon="true"
201967
- show-status-bar="true"
201968
- enable-fixed-col="true"
201969
- row-resizable="false"
201970
- col-movable="true"
201971
- >
201972
- <table>
201973
- <colgroup>
201974
- <col width="50" fixed="left" background-color="gray" />
201975
- <col width="100" />
201976
- <col width="100" />
201977
- <col width="200" />
201978
- <col width="120" />
201979
- <col width="100" />
201980
- <col width="150" />
201981
- <col width="150" />
201982
- </colgroup>
201983
- <thead>
201984
- <tr>
201985
- <th>No.</th>
201986
- <th>최종수정자</th>
201987
- <th>문서ID</th>
201988
- <th>문서명</th>
201989
- <th>매출액</th>
201990
- <th>최초등록자</th>
201991
- <th>최초등록일</th>
201992
- <th>최종수정일</th>
201993
- </tr>
201994
- </thead>
201995
- <tbody>
201996
- <tr>
201997
- <th><ng-row-indicator /></th>
201998
- <td data-bind="updateUser" text-align="center"></td>
201999
- <td data-bind="docId" text-align="center"></td>
202000
- <td data-bind="docNm" text-align="left"></td>
202001
- <td
202002
- data-bind="amt"
202003
- data-expr="data.amt.toLocaleString()"
202004
- text-align="right"
202005
- show-icon="true"
202006
- icon-type="sphere"
202007
- icon-color="data.amt >= 2000 ? 'red' : 'gray'"
202008
- ></td>
202009
- <td data-bind="insertUser" text-align="center"></td>
202010
- <td data-bind="insertDt" text-align="center"></td>
202011
- <td data-bind="updateDt" text-align="center"></td>
202012
- </tr>
202013
- </tbody>
202014
- </table>
202015
- </nine-grid>
202016
- </div>
202017
- </div>
202018
- </div>
202019
- );
202020
- };
202021
-
202022
- export default DocManager;
202023
- `;
202024
-
202025
- const src2 = `
202026
- import React, { useRef, useEffect } from 'react';
202027
- import { api, ai } from "ide-assi";
202028
- import ninegrid from "ninegrid2";
202029
-
202030
- const DocManager = () => {
202031
- const tabRef = useRef(null);
202032
- const gridRef = useRef(null);
202033
-
202034
- const toCamelCase = (s) => {
202035
- return s.toLowerCase().replace(/_([a-z])/g, (g) => g[1].toUpperCase());
202036
- };
202037
-
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;
202040
-
202041
- const selectList = async (formData = {}) => {
202042
- if (!gridRef.current) return;
202043
-
202044
- 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
-
202050
- const formData1 = {
202051
- "_whereClause": await getWhere(),
202052
- }
202053
- console.log(formData1);
202054
- */
201857
+ //return;
202055
201858
 
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
- });
202061
- };
202062
-
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);
202065
- };
201859
+ const apply = {
201860
+ mybatis: this.shadowRoot.querySelector("#mybatis").checked,
201861
+ service: this.shadowRoot.querySelector("#service").checked,
201862
+ controller: this.shadowRoot.querySelector("#controller").checked,
201863
+ javascript: this.shadowRoot.querySelector("#javascript").checked,
201864
+ };
202066
201865
 
202067
- useEffect(() => {
202068
- selectList();
201866
+ if (!apply.mybatis && !apply.service && !apply.controller && !apply.javascript) return;
202069
201867
 
202070
- const searchTextInput = ninegrid.querySelector("#searchText", tabRef.current);
202071
- const searchButton = ninegrid.querySelector(".search", tabRef.current);
201868
+ const userPrompt = e.target.value.trim();
201869
+ if (!userPrompt) return;
202072
201870
 
202073
- const handleSearchTextKeydown = (e) => {
202074
- if (e.key === 'Enter' && !e.isComposing) {
201871
+ if (this.#ing) return;
201872
+ this.#ing = true;
202075
201873
 
202076
- //getWhere();
202077
- getWhere().then(res => {
202078
- selectList({"_whereClause":res});
202079
- });
202080
- }
202081
- };
201874
+ /**
201875
+ * 옵션저장
201876
+ */
201877
+ this.#saveLocalSettings(apply);
202082
201878
 
202083
- const handleSearchButtonClick = () => {
202084
- selectList(ninegrid.querySelector(".form2", tabRef.current).getData());
202085
- };
202086
201879
 
202087
- if (searchTextInput) {
202088
- searchTextInput.addEventListener('keydown', handleSearchTextKeydown);
202089
- }
202090
- if (searchButton) {
202091
- searchButton.addEventListener('click', handleSearchButtonClick);
202092
- }
202093
201880
 
202094
- return () => {
202095
- if (searchTextInput) {
202096
- searchTextInput.removeEventListener('keydown', handleSearchTextKeydown);
202097
- }
202098
- if (searchButton) {
202099
- searchButton.removeEventListener('click', handleSearchButtonClick);
202100
- }
202101
- };
202102
- }, []);
201881
+ /**
201882
+ * setTimeout 없으면, 맥에서 한글 잔상이 남음
201883
+ * setTimeout 내에서 e.target이 nx-ai-container가 된다.
201884
+ */
201885
+ setTimeout(() => {
201886
+ this.shadowRoot.querySelector("textarea").value = "";
201887
+ });
202103
201888
 
202104
- return (
202105
- <div className="wrapper">
202106
- <nx-collapse target="nx-tab" className="search-collapse"></nx-collapse>
202107
- <div className="list-wrapper">
202108
- <nx-tab theme="theme-3" ref={tabRef}>
202109
- <nx-tab-page caption="자연어 검색">
202110
- <nx-form className="form1">
202111
- <input type="text" id="searchText" name="searchText"
202112
- placeholder="자연어 검색어를 입력하세요 (ex: 작성자가 홍길동인 데이타를 찾아줘)"/>
202113
- </nx-form>
202114
- </nx-tab-page>
202115
- <nx-tab-page caption="클래식 검색">
202116
- <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>
202124
- </nx-form>
202125
- <button className="search">검색</button>
202126
- </nx-tab-page>
202127
- </nx-tab>
202128
-
202129
- <div className="grid-wrapper">
202130
- <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
- >
202141
- <table>
202142
- <colgroup>
202143
- <col width="50" fixed="left" background-color="gray"/>
202144
- {mainTableColumns.map((col) => (
202145
- <col key={col.COLUMN_ID} width="150"/>
202146
- ))}
202147
- </colgroup>
202148
- <thead>
202149
- <tr>
202150
- <th>No.</th>
202151
- {mainTableColumns.map((col) => (
202152
- <th key={col.COLUMN_ID}>{col.COLUMN_COMMENT || col.COLUMN_NAME}</th>
202153
- ))}
202154
- </tr>
202155
- </thead>
202156
- <tbody>
202157
- <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
- ))}
202162
- </tr>
202163
- </tbody>
202164
- </table>
202165
- </nine-grid>
202166
- </div>
202167
- </div>
202168
- </div>
202169
- );
202170
- };
201889
+ const elAiChat = this.shadowRoot.querySelector("nx-ai-chat");
202171
201890
 
202172
- export default DocManager;
202173
- `;
201891
+ elAiChat.add("me", userPrompt);
201892
+ elAiChat.add("ing", "...");
202174
201893
 
202175
- this.shadowRoot.querySelector("ide-diff-popup").popup(src1, src2);
201894
+ try {
201895
+ const r = await this.#ai.generateSourceClient(userPrompt, apply);
201896
+ elAiChat.add("ai", r);
201897
+ } catch (error) {
201898
+ console.error(error);
201899
+ elAiChat.add("ai", String(error).replace("Error:", ""));
201900
+ }
202176
201901
 
202177
- return;
201902
+ this.#ing = false;
202178
201903
  }
202179
201904
 
202180
201905
  #toggleCollapseHandler = () => {
@@ -201848,329 +201848,54 @@ class IdeAssi extends HTMLElement
201848
201848
 
201849
201849
  this.shadowRoot.appendChild(document.createElement('ide-diff-popup'));
201850
201850
 
201851
- //setTimeout(() => {
201852
- const src1 = `
201853
- import React, { useRef, useEffect } from "react";
201854
- import { api, ai } from "ide-assi";
201855
- import ninegrid from "ninegrid2";
201856
-
201857
- const DocManager = () => {
201858
- const tabRef = useRef(null);
201859
- const gridRef = useRef(null);
201860
-
201861
- const selectList = async (params) => {
201862
- if (!gridRef.current) return;
201863
- gridRef.current.classList.add("loading");
201864
- api.post(\`/api/tmpl-a/doc-manager/selectList\`, params).then((res) => {
201865
- gridRef.current.data.source = res.list;
201866
- });
201867
- };
201868
-
201869
- const handleNaturalLanguageSearch = async () => {
201870
- const searchTextElement = ninegrid.querySelector("#searchText", tabRef.current);
201871
- const searchText = searchTextElement ? searchTextElement.value : "";
201872
-
201873
- if (!gridRef.current) return;
201874
- gridRef.current.classList.add("loading");
201875
-
201876
- let params = {};
201877
- if (searchText) {
201878
- params = {
201879
- _whereClause: await ai.generateWhereCause(
201880
- "tmpla/DocManagerMapper.xml",
201881
- "selectList",
201882
- searchText,
201883
- import.meta.env.VITE_GEMINI_API_KEY
201884
- ),
201885
- };
201886
- }
201887
- selectList(params);
201888
- };
201889
-
201890
- const handleClassicSearch = () => {
201891
- const form2Element = ninegrid.querySelector(".form2", tabRef.current);
201892
- const params = form2Element ? form2Element.getData() : {};
201893
- selectList(params);
201894
- };
201895
-
201896
- useEffect(() => {
201897
- selectList({});
201851
+ //this.shadowRoot.querySelector("ide-diff-popup").popup(src1, src2);
201898
201852
 
201899
- const searchTextElement = ninegrid.querySelector("#searchText", tabRef.current);
201900
- const searchButton = ninegrid.querySelector(".search", tabRef.current);
201901
-
201902
- const handleKeyDown = (e) => {
201903
- if (e.key === "Enter" && !e.isComposing) {
201904
- handleNaturalLanguageSearch();
201905
- }
201906
- };
201907
-
201908
- const handleClick = () => {
201909
- handleClassicSearch();
201910
- };
201911
-
201912
- if (searchTextElement) {
201913
- searchTextElement.addEventListener("keydown", handleKeyDown);
201914
- }
201915
- if (searchButton) {
201916
- searchButton.addEventListener("click", handleClick);
201917
- }
201918
-
201919
- return () => {
201920
- if (searchTextElement) {
201921
- searchTextElement.removeEventListener("keydown", handleKeyDown);
201922
- }
201923
- if (searchButton) {
201924
- searchButton.removeEventListener("click", handleClick);
201925
- }
201926
- };
201927
- }, []);
201928
-
201929
- return (
201930
- <div className="wrapper">
201931
- <nx-collapse target="nx-tab" className="search-collapse"></nx-collapse>
201932
- <div className="list-wrapper">
201933
- <nx-tab theme="theme-3" ref={tabRef}>
201934
- <nx-tab-page caption="자연어 검색">
201935
- <nx-form className="form1">
201936
- <input
201937
- type="text"
201938
- id="searchText"
201939
- name="searchText"
201940
- placeholder="자연어 검색어를 입력하세요 (ex: 작성자가 홍길동인 데이타를 찾아줘)"
201941
- />
201942
- </nx-form>
201943
- </nx-tab-page>
201944
- <nx-tab-page caption="클래식 검색">
201945
- <nx-form className="form2">
201946
- <label>문서명: <input type="text" name="docNm" /></label>
201947
- <label>매출액:
201948
- <input type="number" name="minAmt" placeholder="최소" /> ~
201949
- <input type="number" name="maxAmt" placeholder="최대" />
201950
- </label>
201951
- </nx-form>
201952
- <button className="search">검색</button>
201953
- </nx-tab-page>
201954
- </nx-tab>
201955
-
201956
- <div className="grid-wrapper">
201957
- <nine-grid
201958
- ref={gridRef}
201959
- caption="문서관리"
201960
- select-type="row"
201961
- show-title-bar="true"
201962
- show-menu-icon="true"
201963
- show-status-bar="true"
201964
- enable-fixed-col="true"
201965
- row-resizable="false"
201966
- col-movable="true"
201967
- >
201968
- <table>
201969
- <colgroup>
201970
- <col width="50" fixed="left" background-color="gray" />
201971
- <col width="100" />
201972
- <col width="100" />
201973
- <col width="200" />
201974
- <col width="120" />
201975
- <col width="100" />
201976
- <col width="150" />
201977
- <col width="150" />
201978
- </colgroup>
201979
- <thead>
201980
- <tr>
201981
- <th>No.</th>
201982
- <th>최종수정자</th>
201983
- <th>문서ID</th>
201984
- <th>문서명</th>
201985
- <th>매출액</th>
201986
- <th>최초등록자</th>
201987
- <th>최초등록일</th>
201988
- <th>최종수정일</th>
201989
- </tr>
201990
- </thead>
201991
- <tbody>
201992
- <tr>
201993
- <th><ng-row-indicator /></th>
201994
- <td data-bind="updateUser" text-align="center"></td>
201995
- <td data-bind="docId" text-align="center"></td>
201996
- <td data-bind="docNm" text-align="left"></td>
201997
- <td
201998
- data-bind="amt"
201999
- data-expr="data.amt.toLocaleString()"
202000
- text-align="right"
202001
- show-icon="true"
202002
- icon-type="sphere"
202003
- icon-color="data.amt >= 2000 ? 'red' : 'gray'"
202004
- ></td>
202005
- <td data-bind="insertUser" text-align="center"></td>
202006
- <td data-bind="insertDt" text-align="center"></td>
202007
- <td data-bind="updateDt" text-align="center"></td>
202008
- </tr>
202009
- </tbody>
202010
- </table>
202011
- </nine-grid>
202012
- </div>
202013
- </div>
202014
- </div>
202015
- );
202016
- };
202017
-
202018
- export default DocManager;
202019
- `;
202020
-
202021
- const src2 = `
202022
- import React, { useRef, useEffect } from 'react';
202023
- import { api, ai } from "ide-assi";
202024
- import ninegrid from "ninegrid2";
202025
-
202026
- const DocManager = () => {
202027
- const tabRef = useRef(null);
202028
- const gridRef = useRef(null);
202029
-
202030
- const toCamelCase = (s) => {
202031
- return s.toLowerCase().replace(/_([a-z])/g, (g) => g[1].toUpperCase());
202032
- };
202033
-
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;
202036
-
202037
- const selectList = async (formData = {}) => {
202038
- if (!gridRef.current) return;
202039
-
202040
- 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
-
202046
- const formData1 = {
202047
- "_whereClause": await getWhere(),
202048
- }
202049
- console.log(formData1);
202050
- */
201853
+ //return;
202051
201854
 
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
- });
202057
- };
202058
-
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);
202061
- };
201855
+ const apply = {
201856
+ mybatis: this.shadowRoot.querySelector("#mybatis").checked,
201857
+ service: this.shadowRoot.querySelector("#service").checked,
201858
+ controller: this.shadowRoot.querySelector("#controller").checked,
201859
+ javascript: this.shadowRoot.querySelector("#javascript").checked,
201860
+ };
202062
201861
 
202063
- useEffect(() => {
202064
- selectList();
201862
+ if (!apply.mybatis && !apply.service && !apply.controller && !apply.javascript) return;
202065
201863
 
202066
- const searchTextInput = ninegrid.querySelector("#searchText", tabRef.current);
202067
- const searchButton = ninegrid.querySelector(".search", tabRef.current);
201864
+ const userPrompt = e.target.value.trim();
201865
+ if (!userPrompt) return;
202068
201866
 
202069
- const handleSearchTextKeydown = (e) => {
202070
- if (e.key === 'Enter' && !e.isComposing) {
201867
+ if (this.#ing) return;
201868
+ this.#ing = true;
202071
201869
 
202072
- //getWhere();
202073
- getWhere().then(res => {
202074
- selectList({"_whereClause":res});
202075
- });
202076
- }
202077
- };
201870
+ /**
201871
+ * 옵션저장
201872
+ */
201873
+ this.#saveLocalSettings(apply);
202078
201874
 
202079
- const handleSearchButtonClick = () => {
202080
- selectList(ninegrid.querySelector(".form2", tabRef.current).getData());
202081
- };
202082
201875
 
202083
- if (searchTextInput) {
202084
- searchTextInput.addEventListener('keydown', handleSearchTextKeydown);
202085
- }
202086
- if (searchButton) {
202087
- searchButton.addEventListener('click', handleSearchButtonClick);
202088
- }
202089
201876
 
202090
- return () => {
202091
- if (searchTextInput) {
202092
- searchTextInput.removeEventListener('keydown', handleSearchTextKeydown);
202093
- }
202094
- if (searchButton) {
202095
- searchButton.removeEventListener('click', handleSearchButtonClick);
202096
- }
202097
- };
202098
- }, []);
201877
+ /**
201878
+ * setTimeout 없으면, 맥에서 한글 잔상이 남음
201879
+ * setTimeout 내에서 e.target이 nx-ai-container가 된다.
201880
+ */
201881
+ setTimeout(() => {
201882
+ this.shadowRoot.querySelector("textarea").value = "";
201883
+ });
202099
201884
 
202100
- return (
202101
- <div className="wrapper">
202102
- <nx-collapse target="nx-tab" className="search-collapse"></nx-collapse>
202103
- <div className="list-wrapper">
202104
- <nx-tab theme="theme-3" ref={tabRef}>
202105
- <nx-tab-page caption="자연어 검색">
202106
- <nx-form className="form1">
202107
- <input type="text" id="searchText" name="searchText"
202108
- placeholder="자연어 검색어를 입력하세요 (ex: 작성자가 홍길동인 데이타를 찾아줘)"/>
202109
- </nx-form>
202110
- </nx-tab-page>
202111
- <nx-tab-page caption="클래식 검색">
202112
- <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>
202120
- </nx-form>
202121
- <button className="search">검색</button>
202122
- </nx-tab-page>
202123
- </nx-tab>
202124
-
202125
- <div className="grid-wrapper">
202126
- <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
- >
202137
- <table>
202138
- <colgroup>
202139
- <col width="50" fixed="left" background-color="gray"/>
202140
- {mainTableColumns.map((col) => (
202141
- <col key={col.COLUMN_ID} width="150"/>
202142
- ))}
202143
- </colgroup>
202144
- <thead>
202145
- <tr>
202146
- <th>No.</th>
202147
- {mainTableColumns.map((col) => (
202148
- <th key={col.COLUMN_ID}>{col.COLUMN_COMMENT || col.COLUMN_NAME}</th>
202149
- ))}
202150
- </tr>
202151
- </thead>
202152
- <tbody>
202153
- <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
- ))}
202158
- </tr>
202159
- </tbody>
202160
- </table>
202161
- </nine-grid>
202162
- </div>
202163
- </div>
202164
- </div>
202165
- );
202166
- };
201885
+ const elAiChat = this.shadowRoot.querySelector("nx-ai-chat");
202167
201886
 
202168
- export default DocManager;
202169
- `;
201887
+ elAiChat.add("me", userPrompt);
201888
+ elAiChat.add("ing", "...");
202170
201889
 
202171
- this.shadowRoot.querySelector("ide-diff-popup").popup(src1, src2);
201890
+ try {
201891
+ const r = await this.#ai.generateSourceClient(userPrompt, apply);
201892
+ elAiChat.add("ai", r);
201893
+ } catch (error) {
201894
+ console.error(error);
201895
+ elAiChat.add("ai", String(error).replace("Error:", ""));
201896
+ }
202172
201897
 
202173
- return;
201898
+ this.#ing = false;
202174
201899
  }
202175
201900
 
202176
201901
  #toggleCollapseHandler = () => {
@@ -442,9 +442,9 @@ const DocManager = () => {
442
442
  export default DocManager;
443
443
  `;
444
444
 
445
- this.shadowRoot.querySelector("ide-diff-popup").popup(src1, src2);
445
+ //this.shadowRoot.querySelector("ide-diff-popup").popup(src1, src2);
446
446
 
447
- return;
447
+ //return;
448
448
 
449
449
  const apply = {
450
450
  mybatis: this.shadowRoot.querySelector("#mybatis").checked,
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.354.0",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "exports": {
@@ -442,9 +442,9 @@ const DocManager = () => {
442
442
  export default DocManager;
443
443
  `;
444
444
 
445
- this.shadowRoot.querySelector("ide-diff-popup").popup(src1, src2);
445
+ //this.shadowRoot.querySelector("ide-diff-popup").popup(src1, src2);
446
446
 
447
- return;
447
+ //return;
448
448
 
449
449
  const apply = {
450
450
  mybatis: this.shadowRoot.querySelector("#mybatis").checked,