ide-assi 0.496.0 → 0.498.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.
@@ -202370,10 +202370,22 @@ class IdeAi
202370
202370
  const returnSrc = [];
202371
202371
 
202372
202372
  const mapping = {
202373
- mybatis: mybatisXmlSource,
202374
- service: serviceSrc,
202375
- controller: controllerSrc,
202376
- javascript: jsSrc
202373
+ mybatis: {
202374
+ path: srcPath.mybatisPullPath,
202375
+ src: mybatisXmlSource,
202376
+ },
202377
+ service: {
202378
+ path: srcPath.servicePullPath,
202379
+ src: serviceSrc,
202380
+ },
202381
+ controller: {
202382
+ path: srcPath.controllerPullPath,
202383
+ src: controllerSrc,
202384
+ },
202385
+ javascript: {
202386
+ path: srcPath.javascriptPullPath,
202387
+ src: jsSrc,
202388
+ }
202377
202389
  };
202378
202390
 
202379
202391
  for (const key in apply) {
@@ -202381,7 +202393,8 @@ class IdeAi
202381
202393
  returnSrc.push({
202382
202394
  [key]: {
202383
202395
  asis: src[key],
202384
- tobe: mapping[key]
202396
+ tobe: mapping[key].src,
202397
+ tobePath: mapping[key].path,
202385
202398
  }
202386
202399
  });
202387
202400
  }
@@ -202624,351 +202637,6 @@ class IdeAssi extends HTMLElement
202624
202637
  //this.shadowRoot.querySelector('ide-diff-popup').remove();
202625
202638
 
202626
202639
  this.shadowRoot.appendChild(document.createElement('ide-diff-popup'));
202627
-
202628
- //setTimeout(() => {
202629
- let src1 = `
202630
- import React, { useRef, useEffect } from "react" adfa;
202631
- import { api, ai } from "ide-assi";
202632
- import ninegrid from "ninegrid2";
202633
-
202634
- const DocManager = () => {
202635
- const tabRef = useRef(null);
202636
- const gridRef = useRef(null);
202637
-
202638
- const selectList = async (params) => {
202639
- if (!gridRef.current) return;
202640
- gridRef.current.classList.add("loading");
202641
- api.post(\`/api/tmpl-a/doc-manager/selectList\`, params).then((res) => {
202642
- gridRef.current.data.source = res.list;
202643
- });
202644
- };
202645
-
202646
- const handleNaturalLanguageSearch = async () => {
202647
- const searchTextElement = ninegrid.querySelector("#searchText", tabRef.current);
202648
- const searchText = searchTextElement ? searchTextElement.value : "";
202649
-
202650
- if (!gridRef.current) return;
202651
- gridRef.current.classList.add("loading");
202652
-
202653
- let params = {};
202654
- if (searchText) {
202655
- params = {
202656
- _whereClause: await ai.generateWhereCause(
202657
- "tmpla/DocManagerMapper.xml",
202658
- "selectList",
202659
- searchText,
202660
- import.meta.env.VITE_GEMINI_API_KEY
202661
- ),
202662
- };
202663
- }
202664
- selectList(params);
202665
- };
202666
-
202667
- const handleClassicSearch = () => {
202668
- if (!gridRef.current) return;
202669
- gridRef.current.classList.add("loading");
202670
-
202671
- const form2Element = ninegrid.querySelector(".form2", tabRef.current);
202672
- const params = form2Element ? form2Element.getData() : {};
202673
- selectList(params);
202674
- };
202675
-
202676
- useEffect(() => {
202677
- selectList({});
202678
-
202679
- const searchTextElement = ninegrid.querySelector("#searchText", tabRef.current);
202680
- const searchButton = ninegrid.querySelector(".search", tabRef.current);
202681
-
202682
- const handleKeyDown = (e) => {
202683
- if (e.key === "Enter" && !e.isComposing) {
202684
- handleNaturalLanguageSearch();
202685
- }
202686
- };
202687
-
202688
- const handleClick = () => {
202689
- handleClassicSearch();
202690
- };
202691
-
202692
- if (searchTextElement) {
202693
- searchTextElement.addEventListener("keydown", handleKeyDown);
202694
- }
202695
- if (searchButton) {
202696
- searchButton.addEventListener("click", handleClick);
202697
- }
202698
-
202699
- return () => {
202700
- if (searchTextElement) {
202701
- searchTextElement.removeEventListener("keydown", handleKeyDown);
202702
- }
202703
- if (searchButton) {
202704
- searchButton.removeEventListener("click", handleClick);
202705
- }
202706
- };
202707
- }, []);
202708
-
202709
- return (
202710
- <div className="wrapper">
202711
- <nx-collapse target="nx-tab" className="search-collapse"></nx-collapse>
202712
- <div className="list-wrapper">
202713
- <nx-tab theme="theme-3" ref={tabRef}>
202714
- <nx-tab-page caption="자연어 검색">
202715
- <nx-form className="form1">
202716
- <input
202717
- type="text"
202718
- id="searchText"
202719
- name="searchText"
202720
- placeholder="자연어 검색어를 입력하세요 (ex: 작성자가 홍길동인 데이타를 찾아줘)"
202721
- />
202722
- </nx-form>
202723
- </nx-tab-page>
202724
- <nx-tab-page caption="클래식 검색">
202725
- <nx-form className="form2">
202726
- <label>문서명: <input type="text" name="docNm" /></label>
202727
- <label>매출액:
202728
- <input type="number" name="minAmt" placeholder="최소" /> ~
202729
- <input type="number" name="maxAmt" placeholder="최대" />
202730
- </label>
202731
- </nx-form>
202732
- <button className="search">검색</button>
202733
- </nx-tab-page>
202734
- </nx-tab>
202735
-
202736
- <div className="grid-wrapper">
202737
- <nine-grid
202738
- ref={gridRef}
202739
- caption="문서관리"
202740
- select-type="row"
202741
- show-title-bar="true"
202742
- show-menu-icon="true"
202743
- show-status-bar="true"
202744
- enable-fixed-col="true"
202745
- row-resizable="false"
202746
- col-movable="true"
202747
- >
202748
- <table>
202749
- <colgroup>
202750
- <col width="50" fixed="left" background-color="gray" />
202751
- <col width="100" />
202752
- <col width="100" />
202753
- <col width="200" />
202754
- <col width="120" />
202755
- <col width="100" />
202756
- <col width="150" />
202757
- <col width="150" />
202758
- </colgroup>
202759
- <thead>
202760
- <tr>
202761
- <th>No.</th>
202762
- <th>최종수정자</th>
202763
- <th>문서ID</th>
202764
- <th>문서명</th>
202765
- <th>매출액</th>
202766
- <th>최초등록자</th>
202767
- <th>최초등록일</th>
202768
- <th>최종수정일</th>
202769
- </tr>
202770
- </thead>
202771
- <tbody>
202772
- <tr>
202773
- <th><ng-row-indicator /></th>
202774
- <td data-bind="updateUser" text-align="center"></td>
202775
- <td data-bind="docId" text-align="center"></td>
202776
- <td data-bind="docNm" text-align="left"></td>
202777
- <td
202778
- data-bind="amt"
202779
- data-expr="data.amt.toLocaleString()"
202780
- text-align="right"
202781
- show-icon="true"
202782
- icon-type="sphere"
202783
- icon-color="data.amt >= 2000 ? 'red' : 'gray'"
202784
- ></td>
202785
- <td data-bind="insertUser" text-align="center"></td>
202786
- <td data-bind="insertDt" text-align="center"></td>
202787
- <td data-bind="updateDt" text-align="center"></td>
202788
- </tr>
202789
- </tbody>
202790
- </table>
202791
- </nine-grid>
202792
- </div>
202793
- </div>
202794
- </div>
202795
- );
202796
- };
202797
-
202798
- export default DocManager;
202799
- `;
202800
-
202801
- let src2 = `
202802
- import React, { useRef, useEffect } from "react";
202803
- import { api, ai } from "ide-assi";
202804
- import ninegrid from "ninegrid2";
202805
-
202806
- const DocManager = () => {
202807
- const tabRef = useRef(null);
202808
- const gridRef = useRef(null);
202809
-
202810
- const selectList = async (params) => {
202811
- if (!gridRef.current) return;
202812
- gridRef.current.classList.add("loading");
202813
- api.post(\`/api/tmpl-a/doc-manager/selectList\`, params).then((res) => {
202814
- gridRef.current.data.source = res.list;
202815
- });
202816
- };
202817
-
202818
- const handleNaturalLanguageSearch = async () => {
202819
- const searchTextElement = ninegrid.querySelector("#searchText", tabRef.current);
202820
- const searchText = searchTextElement ? searchTextElement.value : "";
202821
-
202822
- if (!gridRef.current) return;
202823
- gridRef.current.classList.add("loading");
202824
-
202825
- let params = {};
202826
- if (searchText) {
202827
- params = {
202828
- _whereClause: await ai.generateWhereCause(
202829
- "tmpla/DocManagerMapper.xml",
202830
- "selectList",
202831
- searchText,
202832
- import.meta.env.VITE_GEMINI_API_KEY
202833
- ),
202834
- };
202835
- }
202836
- selectList(params);
202837
- };
202838
-
202839
- const handleClassicSearch = () => {
202840
- if (!gridRef.current) return;
202841
- gridRef.current.classList.add("loading");
202842
-
202843
- const form2Element = ninegrid.querySelector(".form2", tabRef.current);
202844
- const params = form2Element ? form2Element.getData() : {};
202845
- selectList(params);
202846
- };
202847
-
202848
- useEffect(() => {
202849
- selectList({});
202850
-
202851
- const searchTextElement = ninegrid.querySelector("#searchText", tabRef.current);
202852
- const searchButton = ninegrid.querySelector(".search", tabRef.current);
202853
-
202854
- const handleKeyDown = (e) => {
202855
- if (e.key === "Enter" && !e.isComposing) {
202856
- handleNaturalLanguageSearch();
202857
- }
202858
- };
202859
-
202860
- const handleClick = () => {
202861
- handleClassicSearch();
202862
- };
202863
-
202864
- if (searchTextElement) {
202865
- searchTextElement.addEventListener("keydown", handleKeyDown);
202866
- }
202867
- if (searchButton) {
202868
- searchButton.addEventListener("click", handleClick);
202869
- }
202870
-
202871
- return () => {
202872
- if (searchTextElement) {
202873
- searchTextElement.removeEventListener("keydown", handleKeyDown);
202874
- }
202875
- if (searchButton) {
202876
- searchButton.removeEventListener("click", handleClick);
202877
- }
202878
- };
202879
- }, []);
202880
-
202881
- return (
202882
- <div className="wrapper">
202883
- <nx-collapse target="nx-tab" className="search-collapse"></nx-collapse>
202884
- <div className="list-wrapper">
202885
- <nx-tab theme="theme-3" ref={tabRef}>
202886
- <nx-tab-page caption="자연어 검색">
202887
- <nx-form className="form1">
202888
- <input
202889
- type="text"
202890
- id="searchText"
202891
- name="searchText"
202892
- placeholder="자연어 검색어를 입력하세요 (ex: 작성자가 홍길동인 데이타를 찾아줘)"
202893
- />
202894
- </nx-form>
202895
- </nx-tab-page>
202896
- <nx-tab-page caption="클래식 검색">
202897
- <nx-form className="form2">
202898
- <label>문서명: <input type="text" name="docNm" /></label>
202899
- <label>매출액:
202900
- <input type="number" name="minAmt" placeholder="최소" /> ~
202901
- <input type="number" name="maxAmt" placeholder="최대" />
202902
- </label>
202903
- </nx-form>
202904
- <button className="search">검색</button>
202905
- </nx-tab-page>
202906
- </nx-tab>
202907
-
202908
- <div className="grid-wrapper">
202909
- <nine-grid
202910
- ref={gridRef}
202911
- caption="매출 문서 관리"
202912
- select-type="row"
202913
- show-title-bar="true"
202914
- show-menu-icon="true"
202915
- show-status-bar="true"
202916
- enable-fixed-col="true"
202917
- row-resizable="false"
202918
- col-movable="true"
202919
- >
202920
- <table>
202921
- <colgroup>
202922
- <col width="50" fixed="left" background-color="gray" />
202923
- <col width="100" />
202924
- <col width="120" />
202925
- <col width="100" />
202926
- <col width="200" />
202927
- <col width="100" />
202928
- <col width="150" />
202929
- <col width="150" />
202930
- </colgroup>
202931
- <thead>
202932
- <tr>
202933
- <th>No.</th>
202934
- <th>문서ID</th>
202935
- <th>매출액</th>
202936
- <th>최종수정자</th>
202937
- <th>문서명</th>
202938
- <th>최초등록자</th>
202939
- <th>최초등록일</th>
202940
- <th>최종수정일</th>
202941
- </tr>
202942
- </thead>
202943
- <tbody>
202944
- <tr>
202945
- <th><ng-row-indicator /></th>
202946
- <td data-bind="docId" text-align="center"></td>
202947
- <td
202948
- data-bind="amt"
202949
- data-expr="data.amt.toLocaleString()"
202950
- text-align="right"
202951
- show-icon="true"
202952
- icon-type="sphere"
202953
- icon-color="data.amt >= 2000 ? 'red' : 'gray'"
202954
- ></td>
202955
- <td data-bind="updateUser" text-align="center"></td>
202956
- <td data-bind="docNm" text-align="left"></td>
202957
- <td data-bind="insertUser" text-align="center"></td>
202958
- <td data-bind="insertDt" text-align="center"></td>
202959
- <td data-bind="updateDt" text-align="center"></td>
202960
- </tr>
202961
- </tbody>
202962
- </table>
202963
- </nine-grid>
202964
- </div>
202965
- </div>
202966
- </div>
202967
- );
202968
- };
202969
-
202970
- export default DocManager;
202971
- `;
202972
202640
  /**
202973
202641
  src1 = `
202974
202642
  <tr>
@@ -202994,6 +202662,7 @@ export default DocManager;
202994
202662
  <th>최종수정일</th>
202995
202663
  </tr>
202996
202664
  `; */
202665
+ /**
202997
202666
  this.shadowRoot.querySelector("ide-diff-popup").popup([{
202998
202667
  javascript: {
202999
202668
  asis: src1,
@@ -203002,6 +202671,59 @@ export default DocManager;
203002
202671
  }]);
203003
202672
 
203004
202673
  return;
202674
+ */
202675
+
202676
+
202677
+
202678
+
202679
+ const apply = {
202680
+ mybatis: this.shadowRoot.querySelector("#mybatis").checked,
202681
+ service: this.shadowRoot.querySelector("#service").checked,
202682
+ controller: this.shadowRoot.querySelector("#controller").checked,
202683
+ javascript: this.shadowRoot.querySelector("#javascript").checked,
202684
+ };
202685
+
202686
+ if (!apply.mybatis && !apply.service && !apply.controller && !apply.javascript) return;
202687
+
202688
+ const userPrompt = e.target.value.trim();
202689
+ if (!userPrompt) return;
202690
+
202691
+ if (this.#ing) return;
202692
+ this.#ing = true;
202693
+
202694
+ /**
202695
+ * 옵션저장
202696
+ */
202697
+ this.#saveLocalSettings(apply);
202698
+
202699
+
202700
+
202701
+ /**
202702
+ * setTimeout 없으면, 맥에서 한글 잔상이 남음
202703
+ * setTimeout 내에서 e.target이 nx-ai-container가 된다.
202704
+ */
202705
+ setTimeout(() => {
202706
+ this.shadowRoot.querySelector("textarea").value = "";
202707
+ });
202708
+
202709
+ const elAiChat = this.shadowRoot.querySelector("nx-ai-chat");
202710
+
202711
+
202712
+ elAiChat.add("me", userPrompt);
202713
+ elAiChat.add("ing", "...");
202714
+
202715
+
202716
+ try {
202717
+ const changedSource = await this.#ai.generateSourceClient(userPrompt, apply);
202718
+ if (changedSource) {
202719
+ this.shadowRoot.querySelector("ide-diff-popup").popup(changedSource);
202720
+ }
202721
+ } catch (error) {
202722
+ console.error(error);
202723
+ elAiChat.add("ai", String(error).replace("Error:", ""));
202724
+ }
202725
+
202726
+ this.#ing = false;
203005
202727
  }
203006
202728
 
203007
202729
  #toggleCollapseHandler = () => {
@@ -203181,6 +202903,8 @@ customElements.define("ide-assi-settings", ideAssiSettings);
203181
202903
 
203182
202904
  class IdeDiffPopup extends HTMLElement
203183
202905
  {
202906
+ #changedSource;
202907
+
203184
202908
  constructor() {
203185
202909
 
203186
202910
  super();
@@ -203194,8 +202918,13 @@ class IdeDiffPopup extends HTMLElement
203194
202918
 
203195
202919
  this.shadowRoot.innerHTML = `
203196
202920
  <style>
202921
+
203197
202922
  </style>
203198
202923
 
202924
+ <div>
202925
+ <button onclick="this.#apply()">소스 적용</button>
202926
+ </div>
202927
+
203199
202928
  <nx-dialog>
203200
202929
  <nx-tab theme="theme-4">
203201
202930
  <nx-tab-page caption="mybatis">
@@ -203214,9 +202943,34 @@ class IdeDiffPopup extends HTMLElement
203214
202943
  </nx-dialog>
203215
202944
  `;
203216
202945
  }
202946
+
202947
+ #apply = () => {
202948
+ let params = [];
202949
+
202950
+ for (const o of this.#changedSource) {
202951
+ console.log(o);
202952
+ const type = Object.keys(o)[0];
202953
+
202954
+ const diff = ninegrid.querySelector(`ide-diff.${type}`, this.shadowRoot);
202955
+
202956
+ console.log(diff);
202957
+
202958
+ params.push({
202959
+ path: o.tobePath,
202960
+ contents: diff.getContents(),
202961
+ });
202962
+ }
202963
+
202964
+ console.log(params);
202965
+
202966
+ api.post(`/api/source/generateRealFile`, { list: params });
202967
+ }
202968
+
203217
202969
 
203218
202970
  popup = (changedSource) => {
203219
202971
 
202972
+ this.#changedSource = changedSource;
202973
+
203220
202974
  const tab = this.shadowRoot.querySelector('nx-tab');
203221
202975
 
203222
202976
  setTimeout(() => {
@@ -235833,6 +235587,10 @@ class IdeDiff extends HTMLElement {
235833
235587
  }
235834
235588
  }
235835
235589
 
235590
+ getContents = () => {
235591
+ return (this.#tobeEditorView) ? this.#tobeEditorView.state.doc.toString() : "";
235592
+ };
235593
+
235836
235594
  #initCodeMirror = () => {
235837
235595
  this.#asisEditorEl = this.shadowRoot.querySelector('.panel.asis');
235838
235596
  this.#tobeEditorEl = this.shadowRoot.querySelector('.panel.tobe');
@@ -202366,10 +202366,22 @@ class IdeAi
202366
202366
  const returnSrc = [];
202367
202367
 
202368
202368
  const mapping = {
202369
- mybatis: mybatisXmlSource,
202370
- service: serviceSrc,
202371
- controller: controllerSrc,
202372
- javascript: jsSrc
202369
+ mybatis: {
202370
+ path: srcPath.mybatisPullPath,
202371
+ src: mybatisXmlSource,
202372
+ },
202373
+ service: {
202374
+ path: srcPath.servicePullPath,
202375
+ src: serviceSrc,
202376
+ },
202377
+ controller: {
202378
+ path: srcPath.controllerPullPath,
202379
+ src: controllerSrc,
202380
+ },
202381
+ javascript: {
202382
+ path: srcPath.javascriptPullPath,
202383
+ src: jsSrc,
202384
+ }
202373
202385
  };
202374
202386
 
202375
202387
  for (const key in apply) {
@@ -202377,7 +202389,8 @@ class IdeAi
202377
202389
  returnSrc.push({
202378
202390
  [key]: {
202379
202391
  asis: src[key],
202380
- tobe: mapping[key]
202392
+ tobe: mapping[key].src,
202393
+ tobePath: mapping[key].path,
202381
202394
  }
202382
202395
  });
202383
202396
  }
@@ -202620,351 +202633,6 @@ class IdeAssi extends HTMLElement
202620
202633
  //this.shadowRoot.querySelector('ide-diff-popup').remove();
202621
202634
 
202622
202635
  this.shadowRoot.appendChild(document.createElement('ide-diff-popup'));
202623
-
202624
- //setTimeout(() => {
202625
- let src1 = `
202626
- import React, { useRef, useEffect } from "react" adfa;
202627
- import { api, ai } from "ide-assi";
202628
- import ninegrid from "ninegrid2";
202629
-
202630
- const DocManager = () => {
202631
- const tabRef = useRef(null);
202632
- const gridRef = useRef(null);
202633
-
202634
- const selectList = async (params) => {
202635
- if (!gridRef.current) return;
202636
- gridRef.current.classList.add("loading");
202637
- api.post(\`/api/tmpl-a/doc-manager/selectList\`, params).then((res) => {
202638
- gridRef.current.data.source = res.list;
202639
- });
202640
- };
202641
-
202642
- const handleNaturalLanguageSearch = async () => {
202643
- const searchTextElement = ninegrid.querySelector("#searchText", tabRef.current);
202644
- const searchText = searchTextElement ? searchTextElement.value : "";
202645
-
202646
- if (!gridRef.current) return;
202647
- gridRef.current.classList.add("loading");
202648
-
202649
- let params = {};
202650
- if (searchText) {
202651
- params = {
202652
- _whereClause: await ai.generateWhereCause(
202653
- "tmpla/DocManagerMapper.xml",
202654
- "selectList",
202655
- searchText,
202656
- import.meta.env.VITE_GEMINI_API_KEY
202657
- ),
202658
- };
202659
- }
202660
- selectList(params);
202661
- };
202662
-
202663
- const handleClassicSearch = () => {
202664
- if (!gridRef.current) return;
202665
- gridRef.current.classList.add("loading");
202666
-
202667
- const form2Element = ninegrid.querySelector(".form2", tabRef.current);
202668
- const params = form2Element ? form2Element.getData() : {};
202669
- selectList(params);
202670
- };
202671
-
202672
- useEffect(() => {
202673
- selectList({});
202674
-
202675
- const searchTextElement = ninegrid.querySelector("#searchText", tabRef.current);
202676
- const searchButton = ninegrid.querySelector(".search", tabRef.current);
202677
-
202678
- const handleKeyDown = (e) => {
202679
- if (e.key === "Enter" && !e.isComposing) {
202680
- handleNaturalLanguageSearch();
202681
- }
202682
- };
202683
-
202684
- const handleClick = () => {
202685
- handleClassicSearch();
202686
- };
202687
-
202688
- if (searchTextElement) {
202689
- searchTextElement.addEventListener("keydown", handleKeyDown);
202690
- }
202691
- if (searchButton) {
202692
- searchButton.addEventListener("click", handleClick);
202693
- }
202694
-
202695
- return () => {
202696
- if (searchTextElement) {
202697
- searchTextElement.removeEventListener("keydown", handleKeyDown);
202698
- }
202699
- if (searchButton) {
202700
- searchButton.removeEventListener("click", handleClick);
202701
- }
202702
- };
202703
- }, []);
202704
-
202705
- return (
202706
- <div className="wrapper">
202707
- <nx-collapse target="nx-tab" className="search-collapse"></nx-collapse>
202708
- <div className="list-wrapper">
202709
- <nx-tab theme="theme-3" ref={tabRef}>
202710
- <nx-tab-page caption="자연어 검색">
202711
- <nx-form className="form1">
202712
- <input
202713
- type="text"
202714
- id="searchText"
202715
- name="searchText"
202716
- placeholder="자연어 검색어를 입력하세요 (ex: 작성자가 홍길동인 데이타를 찾아줘)"
202717
- />
202718
- </nx-form>
202719
- </nx-tab-page>
202720
- <nx-tab-page caption="클래식 검색">
202721
- <nx-form className="form2">
202722
- <label>문서명: <input type="text" name="docNm" /></label>
202723
- <label>매출액:
202724
- <input type="number" name="minAmt" placeholder="최소" /> ~
202725
- <input type="number" name="maxAmt" placeholder="최대" />
202726
- </label>
202727
- </nx-form>
202728
- <button className="search">검색</button>
202729
- </nx-tab-page>
202730
- </nx-tab>
202731
-
202732
- <div className="grid-wrapper">
202733
- <nine-grid
202734
- ref={gridRef}
202735
- caption="문서관리"
202736
- select-type="row"
202737
- show-title-bar="true"
202738
- show-menu-icon="true"
202739
- show-status-bar="true"
202740
- enable-fixed-col="true"
202741
- row-resizable="false"
202742
- col-movable="true"
202743
- >
202744
- <table>
202745
- <colgroup>
202746
- <col width="50" fixed="left" background-color="gray" />
202747
- <col width="100" />
202748
- <col width="100" />
202749
- <col width="200" />
202750
- <col width="120" />
202751
- <col width="100" />
202752
- <col width="150" />
202753
- <col width="150" />
202754
- </colgroup>
202755
- <thead>
202756
- <tr>
202757
- <th>No.</th>
202758
- <th>최종수정자</th>
202759
- <th>문서ID</th>
202760
- <th>문서명</th>
202761
- <th>매출액</th>
202762
- <th>최초등록자</th>
202763
- <th>최초등록일</th>
202764
- <th>최종수정일</th>
202765
- </tr>
202766
- </thead>
202767
- <tbody>
202768
- <tr>
202769
- <th><ng-row-indicator /></th>
202770
- <td data-bind="updateUser" text-align="center"></td>
202771
- <td data-bind="docId" text-align="center"></td>
202772
- <td data-bind="docNm" text-align="left"></td>
202773
- <td
202774
- data-bind="amt"
202775
- data-expr="data.amt.toLocaleString()"
202776
- text-align="right"
202777
- show-icon="true"
202778
- icon-type="sphere"
202779
- icon-color="data.amt >= 2000 ? 'red' : 'gray'"
202780
- ></td>
202781
- <td data-bind="insertUser" text-align="center"></td>
202782
- <td data-bind="insertDt" text-align="center"></td>
202783
- <td data-bind="updateDt" text-align="center"></td>
202784
- </tr>
202785
- </tbody>
202786
- </table>
202787
- </nine-grid>
202788
- </div>
202789
- </div>
202790
- </div>
202791
- );
202792
- };
202793
-
202794
- export default DocManager;
202795
- `;
202796
-
202797
- let src2 = `
202798
- import React, { useRef, useEffect } from "react";
202799
- import { api, ai } from "ide-assi";
202800
- import ninegrid from "ninegrid2";
202801
-
202802
- const DocManager = () => {
202803
- const tabRef = useRef(null);
202804
- const gridRef = useRef(null);
202805
-
202806
- const selectList = async (params) => {
202807
- if (!gridRef.current) return;
202808
- gridRef.current.classList.add("loading");
202809
- api.post(\`/api/tmpl-a/doc-manager/selectList\`, params).then((res) => {
202810
- gridRef.current.data.source = res.list;
202811
- });
202812
- };
202813
-
202814
- const handleNaturalLanguageSearch = async () => {
202815
- const searchTextElement = ninegrid.querySelector("#searchText", tabRef.current);
202816
- const searchText = searchTextElement ? searchTextElement.value : "";
202817
-
202818
- if (!gridRef.current) return;
202819
- gridRef.current.classList.add("loading");
202820
-
202821
- let params = {};
202822
- if (searchText) {
202823
- params = {
202824
- _whereClause: await ai.generateWhereCause(
202825
- "tmpla/DocManagerMapper.xml",
202826
- "selectList",
202827
- searchText,
202828
- import.meta.env.VITE_GEMINI_API_KEY
202829
- ),
202830
- };
202831
- }
202832
- selectList(params);
202833
- };
202834
-
202835
- const handleClassicSearch = () => {
202836
- if (!gridRef.current) return;
202837
- gridRef.current.classList.add("loading");
202838
-
202839
- const form2Element = ninegrid.querySelector(".form2", tabRef.current);
202840
- const params = form2Element ? form2Element.getData() : {};
202841
- selectList(params);
202842
- };
202843
-
202844
- useEffect(() => {
202845
- selectList({});
202846
-
202847
- const searchTextElement = ninegrid.querySelector("#searchText", tabRef.current);
202848
- const searchButton = ninegrid.querySelector(".search", tabRef.current);
202849
-
202850
- const handleKeyDown = (e) => {
202851
- if (e.key === "Enter" && !e.isComposing) {
202852
- handleNaturalLanguageSearch();
202853
- }
202854
- };
202855
-
202856
- const handleClick = () => {
202857
- handleClassicSearch();
202858
- };
202859
-
202860
- if (searchTextElement) {
202861
- searchTextElement.addEventListener("keydown", handleKeyDown);
202862
- }
202863
- if (searchButton) {
202864
- searchButton.addEventListener("click", handleClick);
202865
- }
202866
-
202867
- return () => {
202868
- if (searchTextElement) {
202869
- searchTextElement.removeEventListener("keydown", handleKeyDown);
202870
- }
202871
- if (searchButton) {
202872
- searchButton.removeEventListener("click", handleClick);
202873
- }
202874
- };
202875
- }, []);
202876
-
202877
- return (
202878
- <div className="wrapper">
202879
- <nx-collapse target="nx-tab" className="search-collapse"></nx-collapse>
202880
- <div className="list-wrapper">
202881
- <nx-tab theme="theme-3" ref={tabRef}>
202882
- <nx-tab-page caption="자연어 검색">
202883
- <nx-form className="form1">
202884
- <input
202885
- type="text"
202886
- id="searchText"
202887
- name="searchText"
202888
- placeholder="자연어 검색어를 입력하세요 (ex: 작성자가 홍길동인 데이타를 찾아줘)"
202889
- />
202890
- </nx-form>
202891
- </nx-tab-page>
202892
- <nx-tab-page caption="클래식 검색">
202893
- <nx-form className="form2">
202894
- <label>문서명: <input type="text" name="docNm" /></label>
202895
- <label>매출액:
202896
- <input type="number" name="minAmt" placeholder="최소" /> ~
202897
- <input type="number" name="maxAmt" placeholder="최대" />
202898
- </label>
202899
- </nx-form>
202900
- <button className="search">검색</button>
202901
- </nx-tab-page>
202902
- </nx-tab>
202903
-
202904
- <div className="grid-wrapper">
202905
- <nine-grid
202906
- ref={gridRef}
202907
- caption="매출 문서 관리"
202908
- select-type="row"
202909
- show-title-bar="true"
202910
- show-menu-icon="true"
202911
- show-status-bar="true"
202912
- enable-fixed-col="true"
202913
- row-resizable="false"
202914
- col-movable="true"
202915
- >
202916
- <table>
202917
- <colgroup>
202918
- <col width="50" fixed="left" background-color="gray" />
202919
- <col width="100" />
202920
- <col width="120" />
202921
- <col width="100" />
202922
- <col width="200" />
202923
- <col width="100" />
202924
- <col width="150" />
202925
- <col width="150" />
202926
- </colgroup>
202927
- <thead>
202928
- <tr>
202929
- <th>No.</th>
202930
- <th>문서ID</th>
202931
- <th>매출액</th>
202932
- <th>최종수정자</th>
202933
- <th>문서명</th>
202934
- <th>최초등록자</th>
202935
- <th>최초등록일</th>
202936
- <th>최종수정일</th>
202937
- </tr>
202938
- </thead>
202939
- <tbody>
202940
- <tr>
202941
- <th><ng-row-indicator /></th>
202942
- <td data-bind="docId" text-align="center"></td>
202943
- <td
202944
- data-bind="amt"
202945
- data-expr="data.amt.toLocaleString()"
202946
- text-align="right"
202947
- show-icon="true"
202948
- icon-type="sphere"
202949
- icon-color="data.amt >= 2000 ? 'red' : 'gray'"
202950
- ></td>
202951
- <td data-bind="updateUser" text-align="center"></td>
202952
- <td data-bind="docNm" text-align="left"></td>
202953
- <td data-bind="insertUser" text-align="center"></td>
202954
- <td data-bind="insertDt" text-align="center"></td>
202955
- <td data-bind="updateDt" text-align="center"></td>
202956
- </tr>
202957
- </tbody>
202958
- </table>
202959
- </nine-grid>
202960
- </div>
202961
- </div>
202962
- </div>
202963
- );
202964
- };
202965
-
202966
- export default DocManager;
202967
- `;
202968
202636
  /**
202969
202637
  src1 = `
202970
202638
  <tr>
@@ -202990,6 +202658,7 @@ export default DocManager;
202990
202658
  <th>최종수정일</th>
202991
202659
  </tr>
202992
202660
  `; */
202661
+ /**
202993
202662
  this.shadowRoot.querySelector("ide-diff-popup").popup([{
202994
202663
  javascript: {
202995
202664
  asis: src1,
@@ -202998,6 +202667,59 @@ export default DocManager;
202998
202667
  }]);
202999
202668
 
203000
202669
  return;
202670
+ */
202671
+
202672
+
202673
+
202674
+
202675
+ const apply = {
202676
+ mybatis: this.shadowRoot.querySelector("#mybatis").checked,
202677
+ service: this.shadowRoot.querySelector("#service").checked,
202678
+ controller: this.shadowRoot.querySelector("#controller").checked,
202679
+ javascript: this.shadowRoot.querySelector("#javascript").checked,
202680
+ };
202681
+
202682
+ if (!apply.mybatis && !apply.service && !apply.controller && !apply.javascript) return;
202683
+
202684
+ const userPrompt = e.target.value.trim();
202685
+ if (!userPrompt) return;
202686
+
202687
+ if (this.#ing) return;
202688
+ this.#ing = true;
202689
+
202690
+ /**
202691
+ * 옵션저장
202692
+ */
202693
+ this.#saveLocalSettings(apply);
202694
+
202695
+
202696
+
202697
+ /**
202698
+ * setTimeout 없으면, 맥에서 한글 잔상이 남음
202699
+ * setTimeout 내에서 e.target이 nx-ai-container가 된다.
202700
+ */
202701
+ setTimeout(() => {
202702
+ this.shadowRoot.querySelector("textarea").value = "";
202703
+ });
202704
+
202705
+ const elAiChat = this.shadowRoot.querySelector("nx-ai-chat");
202706
+
202707
+
202708
+ elAiChat.add("me", userPrompt);
202709
+ elAiChat.add("ing", "...");
202710
+
202711
+
202712
+ try {
202713
+ const changedSource = await this.#ai.generateSourceClient(userPrompt, apply);
202714
+ if (changedSource) {
202715
+ this.shadowRoot.querySelector("ide-diff-popup").popup(changedSource);
202716
+ }
202717
+ } catch (error) {
202718
+ console.error(error);
202719
+ elAiChat.add("ai", String(error).replace("Error:", ""));
202720
+ }
202721
+
202722
+ this.#ing = false;
203001
202723
  }
203002
202724
 
203003
202725
  #toggleCollapseHandler = () => {
@@ -203177,6 +202899,8 @@ customElements.define("ide-assi-settings", ideAssiSettings);
203177
202899
 
203178
202900
  class IdeDiffPopup extends HTMLElement
203179
202901
  {
202902
+ #changedSource;
202903
+
203180
202904
  constructor() {
203181
202905
 
203182
202906
  super();
@@ -203190,8 +202914,13 @@ class IdeDiffPopup extends HTMLElement
203190
202914
 
203191
202915
  this.shadowRoot.innerHTML = `
203192
202916
  <style>
202917
+
203193
202918
  </style>
203194
202919
 
202920
+ <div>
202921
+ <button onclick="this.#apply()">소스 적용</button>
202922
+ </div>
202923
+
203195
202924
  <nx-dialog>
203196
202925
  <nx-tab theme="theme-4">
203197
202926
  <nx-tab-page caption="mybatis">
@@ -203210,9 +202939,34 @@ class IdeDiffPopup extends HTMLElement
203210
202939
  </nx-dialog>
203211
202940
  `;
203212
202941
  }
202942
+
202943
+ #apply = () => {
202944
+ let params = [];
202945
+
202946
+ for (const o of this.#changedSource) {
202947
+ console.log(o);
202948
+ const type = Object.keys(o)[0];
202949
+
202950
+ const diff = ninegrid.querySelector(`ide-diff.${type}`, this.shadowRoot);
202951
+
202952
+ console.log(diff);
202953
+
202954
+ params.push({
202955
+ path: o.tobePath,
202956
+ contents: diff.getContents(),
202957
+ });
202958
+ }
202959
+
202960
+ console.log(params);
202961
+
202962
+ api.post(`/api/source/generateRealFile`, { list: params });
202963
+ }
202964
+
203213
202965
 
203214
202966
  popup = (changedSource) => {
203215
202967
 
202968
+ this.#changedSource = changedSource;
202969
+
203216
202970
  const tab = this.shadowRoot.querySelector('nx-tab');
203217
202971
 
203218
202972
  setTimeout(() => {
@@ -235829,6 +235583,10 @@ class IdeDiff extends HTMLElement {
235829
235583
  }
235830
235584
  }
235831
235585
 
235586
+ getContents = () => {
235587
+ return (this.#tobeEditorView) ? this.#tobeEditorView.state.doc.toString() : "";
235588
+ };
235589
+
235832
235590
  #initCodeMirror = () => {
235833
235591
  this.#asisEditorEl = this.shadowRoot.querySelector('.panel.asis');
235834
235592
  this.#tobeEditorEl = this.shadowRoot.querySelector('.panel.tobe');
@@ -522,10 +522,22 @@ export class IdeAi
522
522
  const returnSrc = [];
523
523
 
524
524
  const mapping = {
525
- mybatis: mybatisXmlSource,
526
- service: serviceSrc,
527
- controller: controllerSrc,
528
- javascript: jsSrc
525
+ mybatis: {
526
+ path: srcPath.mybatisPullPath,
527
+ src: mybatisXmlSource,
528
+ },
529
+ service: {
530
+ path: srcPath.servicePullPath,
531
+ src: serviceSrc,
532
+ },
533
+ controller: {
534
+ path: srcPath.controllerPullPath,
535
+ src: controllerSrc,
536
+ },
537
+ javascript: {
538
+ path: srcPath.javascriptPullPath,
539
+ src: jsSrc,
540
+ }
529
541
  };
530
542
 
531
543
  for (const key in apply) {
@@ -533,7 +545,8 @@ export class IdeAi
533
545
  returnSrc.push({
534
546
  [key]: {
535
547
  asis: src[key],
536
- tobe: mapping[key]
548
+ tobe: mapping[key].src,
549
+ tobePath: mapping[key].path,
537
550
  }
538
551
  });
539
552
  }
@@ -491,6 +491,7 @@ export default DocManager;
491
491
  <th>최종수정일</th>
492
492
  </tr>
493
493
  `; */
494
+ /**
494
495
  this.shadowRoot.querySelector("ide-diff-popup").popup([{
495
496
  javascript: {
496
497
  asis: src1,
@@ -499,7 +500,7 @@ export default DocManager;
499
500
  }]);
500
501
 
501
502
  return;
502
-
503
+ */
503
504
 
504
505
 
505
506
 
@@ -222,6 +222,10 @@ export class IdeDiff extends HTMLElement {
222
222
  }
223
223
  }
224
224
 
225
+ getContents = () => {
226
+ return (this.#tobeEditorView) ? this.#tobeEditorView.state.doc.toString() : "";
227
+ };
228
+
225
229
  #initCodeMirror = () => {
226
230
  this.#asisEditorEl = this.shadowRoot.querySelector('.panel.asis');
227
231
  this.#tobeEditorEl = this.shadowRoot.querySelector('.panel.tobe');
@@ -1,7 +1,10 @@
1
1
  import ninegrid from "ninegrid2";
2
+ import {api} from "./ideFetch.js";
2
3
 
3
4
  class IdeDiffPopup extends HTMLElement
4
5
  {
6
+ #changedSource;
7
+
5
8
  constructor() {
6
9
 
7
10
  super();
@@ -15,8 +18,13 @@ class IdeDiffPopup extends HTMLElement
15
18
 
16
19
  this.shadowRoot.innerHTML = `
17
20
  <style>
21
+
18
22
  </style>
19
23
 
24
+ <div>
25
+ <button onclick="this.#apply()">소스 적용</button>
26
+ </div>
27
+
20
28
  <nx-dialog>
21
29
  <nx-tab theme="theme-4">
22
30
  <nx-tab-page caption="mybatis">
@@ -35,9 +43,34 @@ class IdeDiffPopup extends HTMLElement
35
43
  </nx-dialog>
36
44
  `;
37
45
  }
46
+
47
+ #apply = () => {
48
+ let params = [];
49
+
50
+ for (const o of this.#changedSource) {
51
+ console.log(o);
52
+ const type = Object.keys(o)[0];
53
+
54
+ const diff = ninegrid.querySelector(`ide-diff.${type}`, this.shadowRoot);
55
+
56
+ console.log(diff);
57
+
58
+ params.push({
59
+ path: o.tobePath,
60
+ contents: diff.getContents(),
61
+ })
62
+ }
63
+
64
+ console.log(params);
65
+
66
+ api.post(`/api/source/generateRealFile`, { list: params });
67
+ }
68
+
38
69
 
39
70
  popup = (changedSource) => {
40
71
 
72
+ this.#changedSource = changedSource;
73
+
41
74
  const tab = this.shadowRoot.querySelector('nx-tab');
42
75
 
43
76
  setTimeout(() => {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ide-assi",
3
3
  "type": "module",
4
- "version": "0.496.0",
4
+ "version": "0.498.0",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "exports": {
@@ -522,10 +522,22 @@ export class IdeAi
522
522
  const returnSrc = [];
523
523
 
524
524
  const mapping = {
525
- mybatis: mybatisXmlSource,
526
- service: serviceSrc,
527
- controller: controllerSrc,
528
- javascript: jsSrc
525
+ mybatis: {
526
+ path: srcPath.mybatisPullPath,
527
+ src: mybatisXmlSource,
528
+ },
529
+ service: {
530
+ path: srcPath.servicePullPath,
531
+ src: serviceSrc,
532
+ },
533
+ controller: {
534
+ path: srcPath.controllerPullPath,
535
+ src: controllerSrc,
536
+ },
537
+ javascript: {
538
+ path: srcPath.javascriptPullPath,
539
+ src: jsSrc,
540
+ }
529
541
  };
530
542
 
531
543
  for (const key in apply) {
@@ -533,7 +545,8 @@ export class IdeAi
533
545
  returnSrc.push({
534
546
  [key]: {
535
547
  asis: src[key],
536
- tobe: mapping[key]
548
+ tobe: mapping[key].src,
549
+ tobePath: mapping[key].path,
537
550
  }
538
551
  });
539
552
  }
@@ -491,6 +491,7 @@ export default DocManager;
491
491
  <th>최종수정일</th>
492
492
  </tr>
493
493
  `; */
494
+ /**
494
495
  this.shadowRoot.querySelector("ide-diff-popup").popup([{
495
496
  javascript: {
496
497
  asis: src1,
@@ -499,7 +500,7 @@ export default DocManager;
499
500
  }]);
500
501
 
501
502
  return;
502
-
503
+ */
503
504
 
504
505
 
505
506
 
@@ -222,6 +222,10 @@ export class IdeDiff extends HTMLElement {
222
222
  }
223
223
  }
224
224
 
225
+ getContents = () => {
226
+ return (this.#tobeEditorView) ? this.#tobeEditorView.state.doc.toString() : "";
227
+ };
228
+
225
229
  #initCodeMirror = () => {
226
230
  this.#asisEditorEl = this.shadowRoot.querySelector('.panel.asis');
227
231
  this.#tobeEditorEl = this.shadowRoot.querySelector('.panel.tobe');
@@ -1,7 +1,10 @@
1
1
  import ninegrid from "ninegrid2";
2
+ import {api} from "./ideFetch.js";
2
3
 
3
4
  class IdeDiffPopup extends HTMLElement
4
5
  {
6
+ #changedSource;
7
+
5
8
  constructor() {
6
9
 
7
10
  super();
@@ -15,8 +18,13 @@ class IdeDiffPopup extends HTMLElement
15
18
 
16
19
  this.shadowRoot.innerHTML = `
17
20
  <style>
21
+
18
22
  </style>
19
23
 
24
+ <div>
25
+ <button onclick="this.#apply()">소스 적용</button>
26
+ </div>
27
+
20
28
  <nx-dialog>
21
29
  <nx-tab theme="theme-4">
22
30
  <nx-tab-page caption="mybatis">
@@ -35,9 +43,34 @@ class IdeDiffPopup extends HTMLElement
35
43
  </nx-dialog>
36
44
  `;
37
45
  }
46
+
47
+ #apply = () => {
48
+ let params = [];
49
+
50
+ for (const o of this.#changedSource) {
51
+ console.log(o);
52
+ const type = Object.keys(o)[0];
53
+
54
+ const diff = ninegrid.querySelector(`ide-diff.${type}`, this.shadowRoot);
55
+
56
+ console.log(diff);
57
+
58
+ params.push({
59
+ path: o.tobePath,
60
+ contents: diff.getContents(),
61
+ })
62
+ }
63
+
64
+ console.log(params);
65
+
66
+ api.post(`/api/source/generateRealFile`, { list: params });
67
+ }
68
+
38
69
 
39
70
  popup = (changedSource) => {
40
71
 
72
+ this.#changedSource = changedSource;
73
+
41
74
  const tab = this.shadowRoot.querySelector('nx-tab');
42
75
 
43
76
  setTimeout(() => {