@nine-lab/nine-mu 0.1.284 → 0.1.286
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.
- package/dist/nine-mu.js +35 -36
- package/dist/nine-mu.js.map +1 -1
- package/dist/nine-mu.umd.js +1 -1
- package/dist/nine-mu.umd.js.map +1 -1
- package/package.json +1 -1
- package/src/components/NineDiffPopup.js +41 -48
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@ import '@nine-lab/nine-util';
|
|
|
5
5
|
export class NineDiffPopup extends HTMLElement {
|
|
6
6
|
#dialog = null;
|
|
7
7
|
#tabContainer = null;
|
|
8
|
-
#
|
|
8
|
+
#fileList = []; // 최종 [모두 저장]을 위한 차분 명세 데이터 버퍼
|
|
9
9
|
#host;
|
|
10
10
|
|
|
11
11
|
constructor() {
|
|
@@ -19,7 +19,7 @@ export class NineDiffPopup extends HTMLElement {
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
|
-
* 💡 기본 다이얼로그
|
|
22
|
+
* 💡 기본 다이얼로그 외곽 프레임만 정적으로 선언 (탭 레이아웃은 비워둠)
|
|
23
23
|
*/
|
|
24
24
|
#renderScaffolding() {
|
|
25
25
|
const customImport = this.getAttribute("css-path") ? `@import "${this.getAttribute("css-path")}";` : "";
|
|
@@ -43,14 +43,13 @@ export class NineDiffPopup extends HTMLElement {
|
|
|
43
43
|
display: flex;
|
|
44
44
|
flex-direction: column;
|
|
45
45
|
}
|
|
46
|
-
/* 💡 nx-tab / nine-tab 프레임워크가 100% 자라나도록 높이 강제 배치 */
|
|
47
46
|
nine-tab {
|
|
48
47
|
flex: 1;
|
|
49
48
|
display: flex;
|
|
50
49
|
flex-direction: column;
|
|
51
50
|
height: 100%;
|
|
52
51
|
}
|
|
53
|
-
/* 💡
|
|
52
|
+
/* 💡 하얗게 안 보이는 현상을 방지하기 위해 동적 삽입될 에디터 영역의 높이를 확실히 보장 */
|
|
54
53
|
.diff-wrapper {
|
|
55
54
|
height: calc(80vh - 120px);
|
|
56
55
|
width: 100%;
|
|
@@ -96,18 +95,18 @@ export class NineDiffPopup extends HTMLElement {
|
|
|
96
95
|
}
|
|
97
96
|
|
|
98
97
|
/**
|
|
99
|
-
* 💡 [
|
|
100
|
-
*
|
|
98
|
+
* 💡 [100% 동적 빌딩 시스템]
|
|
99
|
+
* 들어온 데이터 개수에 정확히 맞추어 런타임에 탭 페이지와 에디터를 일대일 매핑으로 직접 조립합니다.
|
|
101
100
|
* @param {Array} fileList - [{ layer: "MyBatis", full_path: "...", asis_source: "...", source: "..." }]
|
|
102
101
|
*/
|
|
103
102
|
async data(fileList) {
|
|
104
103
|
if (!Array.isArray(fileList) || fileList.length === 0) return this;
|
|
104
|
+
this.#fileList = fileList;
|
|
105
105
|
|
|
106
|
-
// 1.
|
|
106
|
+
// 1. 🧼 이전 실행 흔적이 있다면 동적 컨텐츠 내부를 완전히 청소 (인덱스 리셋)
|
|
107
107
|
this.#tabContainer.innerHTML = "";
|
|
108
|
-
this.#filesMap.clear();
|
|
109
108
|
|
|
110
|
-
// 확장자 기반
|
|
109
|
+
// 확장자 기반 주석/언어 유추 헬퍼
|
|
111
110
|
const detectLanguage = (path) => {
|
|
112
111
|
const lower = (path || "").toLowerCase();
|
|
113
112
|
if (lower.endsWith('.xml')) return 'xml';
|
|
@@ -116,84 +115,79 @@ export class NineDiffPopup extends HTMLElement {
|
|
|
116
115
|
return 'javascript';
|
|
117
116
|
};
|
|
118
117
|
|
|
119
|
-
// 2. 수신된 파일
|
|
120
|
-
fileList.forEach((file
|
|
121
|
-
const { layer, full_path
|
|
118
|
+
// 2. ⚡ 수신된 파일 갯수만큼 루프를 돌며 필요한 요소만 정확히 DOM 생성(Injection)
|
|
119
|
+
fileList.forEach((file) => {
|
|
120
|
+
const { layer, full_path } = file;
|
|
122
121
|
const lang = detectLanguage(full_path);
|
|
123
|
-
|
|
124
|
-
// 파일명만 추출하여 보기 좋게 캡션 가공
|
|
125
122
|
const fileName = full_path.split('/').pop() || "Unknown";
|
|
126
|
-
const
|
|
123
|
+
const captionName = `${layer.toUpperCase()} (${fileName})`; // 예: MYBATIS (MemberUsersMapper.xml)
|
|
127
124
|
|
|
128
|
-
// A. <nine-tab-page>
|
|
125
|
+
// A. <nine-tab-page> 런타임 인스턴싱
|
|
129
126
|
const tabPage = document.createElement('nine-tab-page');
|
|
130
|
-
tabPage.setAttribute('caption',
|
|
127
|
+
tabPage.setAttribute('caption', captionName);
|
|
131
128
|
|
|
132
|
-
// B.
|
|
129
|
+
// B. 높이 유실 방어용 래퍼 생성
|
|
133
130
|
const diffWrapper = document.createElement('div');
|
|
134
131
|
diffWrapper.className = 'diff-wrapper';
|
|
135
132
|
|
|
136
|
-
// C. <nine-diff>
|
|
133
|
+
// C. <nine-diff> 에디터 장치 동적 생성 및 매칭용 레이어 클래스 주입
|
|
137
134
|
const diffView = document.createElement('nine-diff');
|
|
135
|
+
diffView.className = layer; // 예: class="MyBatis" 또는 class="JavaScript"
|
|
138
136
|
|
|
139
|
-
// D.
|
|
137
|
+
// D. 하위 트리 계층 결합 및 실제 탭 컨테이너 레이아웃에 안착
|
|
140
138
|
diffWrapper.appendChild(diffView);
|
|
141
139
|
tabPage.appendChild(diffWrapper);
|
|
142
140
|
this.#tabContainer.appendChild(tabPage);
|
|
143
|
-
|
|
144
|
-
// E. 추후 [모두 저장] 작동시 순회 타겟 명세 확보를 위한 고유 맵 바인딩
|
|
145
|
-
const fileKey = `file_tab_${index}`;
|
|
146
|
-
this.#filesMap.set(fileKey, {
|
|
147
|
-
layer,
|
|
148
|
-
fullPath: full_path,
|
|
149
|
-
asisSource: asis_source,
|
|
150
|
-
diffView: diffView
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
// F. 동적으로 추가된 에디터 가상 장치가 준비 완료(ready) 상태를 발행하면 소스 코드 로드 기동
|
|
154
|
-
diffView.addEventListener('ready', () => {
|
|
155
|
-
diffView.initialize(asis_source || "", source || "", lang);
|
|
156
|
-
}, { once: true });
|
|
157
141
|
});
|
|
158
142
|
|
|
159
|
-
// 3.
|
|
143
|
+
// 3. ⏰ 브라우저가 동적으로 추가된 태그들을 완벽하게 렌더트리에 마운트할 수 있도록 비동기 여유 마진 확보
|
|
160
144
|
setTimeout(() => {
|
|
161
|
-
|
|
145
|
+
fileList.forEach((file) => {
|
|
146
|
+
const { layer, asis_source, source } = file;
|
|
147
|
+
const diff = this.shadowRoot.querySelector(`nine-diff.${layer}`);
|
|
148
|
+
|
|
149
|
+
if (diff) {
|
|
150
|
+
const lang = detectLanguage(file.full_path);
|
|
151
|
+
// 확보된 실제 에디터 버퍼 장치에 소스코드 강제 바인딩 초기화
|
|
152
|
+
diff.initialize(asis_source || "", source || "", lang);
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
// E. 데이터 주입이 모두 완벽히 끝난 시점에 nine-tab 컴포넌트의 가상 빌더 엔진 트리거!
|
|
157
|
+
if (this.#tabContainer && typeof this.#tabContainer.initialize === 'function') {
|
|
162
158
|
this.#tabContainer.initialize();
|
|
163
159
|
}
|
|
164
|
-
},
|
|
160
|
+
}, 150); // 150ms의 마진 타임 적용
|
|
165
161
|
|
|
166
162
|
return this;
|
|
167
163
|
}
|
|
168
164
|
|
|
169
165
|
/**
|
|
170
|
-
* 💡 [일괄 물리
|
|
171
|
-
* 활성화된 모든 탭 영역의 우측 창(TO-BE) 최종 소스들을 취합하여 단 한 번의 일괄 요청으로 커밋
|
|
166
|
+
* 💡 [일괄 물리 저장]
|
|
172
167
|
*/
|
|
173
168
|
async #handleConfirmAll() {
|
|
174
169
|
const payloadList = [];
|
|
175
170
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
171
|
+
for (const file of this.#fileList) {
|
|
172
|
+
const { layer, full_path, asis_source } = file;
|
|
173
|
+
// 각 레이어 클래스로 지정해 둔 동적 에디터를 순회하며 텍스트 캡처
|
|
174
|
+
const diff = this.shadowRoot.querySelector(`nine-diff.${layer}`);
|
|
179
175
|
|
|
180
|
-
|
|
181
|
-
const currentContent = diffView ? diffView.getContents() : asisSource;
|
|
176
|
+
const currentContent = diff ? diff.getContents() : asis_source;
|
|
182
177
|
|
|
183
178
|
payloadList.push({
|
|
184
179
|
layer,
|
|
185
|
-
fullPath:
|
|
180
|
+
fullPath: full_path,
|
|
186
181
|
packageName: this.#host?.getAttribute('package-name') || "com.ninelab.ai",
|
|
187
182
|
contents: currentContent
|
|
188
183
|
});
|
|
189
184
|
}
|
|
190
185
|
|
|
191
186
|
try {
|
|
192
|
-
// 변경된 멀티 레이어 파일 묶음을 전송하는 일괄 일치 컨트롤러 API 최종 동기화
|
|
193
187
|
await api.post(`/nine-mu/source/generateJsonFileBatch`, { fileList: payloadList });
|
|
194
188
|
|
|
195
189
|
await nine.alert("요청하신 모든 파일의 소스 변경 사항이 성공적으로 반영되었습니다.");
|
|
196
|
-
this.#dialog.close();
|
|
190
|
+
this.#dialog.close();
|
|
197
191
|
} catch (error) {
|
|
198
192
|
trace.error("일괄 파일 저장 처리 중 실패:", error);
|
|
199
193
|
nine.alert("소스 일괄 저장 연동 중 치명적인 오류가 발생했습니다.");
|
|
@@ -205,7 +199,6 @@ export class NineDiffPopup extends HTMLElement {
|
|
|
205
199
|
}
|
|
206
200
|
}
|
|
207
201
|
|
|
208
|
-
// 중복 등록 충돌 방지 처리 포함 등록
|
|
209
202
|
if (!customElements.get("nine-diff-popup")) {
|
|
210
203
|
customElements.define("nine-diff-popup", NineDiffPopup);
|
|
211
204
|
}
|