[수습일지] - 52
오늘도 밤 사이에 외국인에게 제보를 받았기 때문에
어제 포기했던 다중 wire params 문제를 해결해보기로 했다.
wire는 외국인이 제시한 방식대로 해도 제대로 전달되지 않았지만
문득 새로운 방식이 떠올라서 적용하니 코드가 정상적으로 전달되는 것을 볼 수 있었다
@wire(getProducts, {strObj : '$object'})
wiredRecord(result) {
this.wiredData = result;
if (result.data) {
this.productList = JSON.parse(result.data);
} else if (result.error) {
console.log(result.error);
this.accounts = undefined;
}
}
get object(){
return {family : this.showTemplate, searchKey : this.searchKey, order : this.order, sort:this.sort}
}
constructor() {
super();
this.showTemplate = 'leather';
this.searchKey = '';
this.order = 'ASC';
this.sort = 'Name';
}
하지만 apex는 죽어라 말을 듣지 않는 녀석이기 때문에
js에서처럼 쉽게 obj.xx나 obj[’xx’]형태로 접근할 수 없었고
이게 object 내부에 String이 들어있는 형태라고 반복해서 알려줘야만 했다.
간신히 아래와 같이 Object에 있는 값을 사용할 수 있었지만
이번에는 PMD 복잡도가 메서드와 클래스에 터져서
4개의 파라미터를 보내서 1개의 경고를 받았는데
5시간 걸려서 해결하니 3개의 경고가 추가된 상황이 되어버렸다.
if (strObj instanceof Map<Object, Object>) {
Map<Object, Object> tempMap = (Map<Object, Object>) a;
Map<String, Object> dataSet = new Map<String, Object>();
for (Object key : tempMap.keySet()) {
dataSet.put(String.valueOf(key), tempMap.get(key));
}
}
갑작스럽게 10시 45분쯤 자체 리뷰를 하자는 이야기가 나와서
11시에 클라우디에서 리뷰를 진행하기로 했다.
복잡도로 인한 경고 3개를 제외하고 현재 pmd, test가 완료된 상황이기 때문에
조금 편하게 참여했지만 LWC로 기능을 이것저것 만들어서 그런지
오히려 개선할 부분을 더 많이 들었고 아래와 같은 피드백을 받았다.
1.필드에 스톡을 넣어서 조금 편하게 수정하기
2.변동사항이 없을 때는 초록색이 아니고 회색으로 보여주기
3.정렬 버튼이 있으면 좋겠다
4.전체 상품 볼 수 있는 페이지가 있으면 좋겠다.
5.동기화 버튼 이름 바꾸기
6.선택된 org 버튼 brand? 부분 바꾸기
7.상품을 눌렀을 때 상품 레코드 페이지로 가면 좋겠다
8.No.제품 번호로 바꾸면 좋겠다.
9.테이블 바닥 안된 부분
10.페이지 수정한 날짜를 보고 최신 데이터인지 궁금할 것 같다
피드백보다 일단 복잡도 문제를 해결하기 위해
열심히 코드들을 살펴보며 어디를 쪼개야 하나 고민했지만
문득 ‘이 데이터 처리도 wrapper로 감싸주면 복잡도를 떠넘길 수 있지 않나?’라는 생각이 들었고
아래와 같은 메서드를 작성해 추가 테스트코드 작성과 메서드, 클래스 분리를 피할 수 있었다.
public class ParamsWrap {
public String family;
public String searchKey;
public String ordering;
public String sortKey;
/**
* @description : 복잡도 감소용 wrapper
* @author Yohan | 2023.05.17
* @param a
**/
public ParamsWrap(Object a) {
if (a instanceof Map<Object, Object>) {
Map<Object, Object> tempMap = (Map<Object, Object>) a;
Map<String, Object> dataSet = new Map<String, Object>();
for (Object key : tempMap.keySet()) {
dataSet.put(String.valueOf(key), tempMap.get(key));
}
this.family = (String) dataSet.get('family');
this.searchKey = (String) dataSet.get('searchKey');
this.ordering = (String) dataSet.get('order');
this.sortKey = (String) dataSet.get('sort');
}
}
}
급한 불(메서드 작성 및 테스트코드 작성 완료)은 모두 껐기 때문에
다시 피드백 진압을 시작했다.
10개의 피드백을 보니 아래와 같은 내용이었고
1.프로덕트 일반 필드에 스톡 넣어서 편하게 수정
2.변동사항 없음 초록색이 아닌 회색 띄우기
3.정렬 버튼 추가
4.전체 상품 페이지 추가(중요 내부 포함)
5.동기화 버튼 이름 변경(중요 내부 포함)
6.선택된 org 버튼 brand? 부분 바꾸기(중요 내부 포함)
7.상품을 눌렀을 때 상품 레코드 페이지로 가면 좋겠다
8.No.제품 번호로 바꾸면 좋겠다.
9.테이블 바닥 안된 부분
#10.페이지 수정한 날짜를 보고 최신 데이터인지 궁금할 것 같다.(궁금하게 두기)
정리해보면 일반 6개와 페이지 세부 변경에 포함되는 나머지로 구분할 수 있었다.
1.프로덕트 일반 필드에 스톡 넣어서 편하게 수정
2.변동사항 없음 초록색이 아닌 회색 띄우기
3.정렬 버튼 추가
7.상품을 눌렀을 때 상품 레코드 페이지로 가면 좋겠다
8.No.제품 번호로 바꾸면 좋겠다.
9.테이블 바닥 안된 부분
추가.하이퍼링크 추가로 상품 확인하기
(하이퍼 링크용 주소 https://mindful-otter-qmf3eu-dev-ed.trailblaze.lightning.force.com/lightning/r/Product2/{ProductId}/view)
@중요 5개 페이지 세부사항
-페이지별 버튼 이름 바꾸기
-페이지별 버튼 브랜드 변경
-전체 동기화 이름 변경
-전체상품조회 동기화 함수 추가
-전체상품조회 선택 상품 동기화 함수 추가
-각 css파일 적용
여기에 org3개 생성 및 연동, 상품추가 등의 작업과
ppt작성, ppt 내부에 이전 과제 피드백 작성 등을 추가해야 하는데
ppr 관련은 내일 처리한다고 잡고 오늘의 작업 순서를 정해보면
org 3개 생성 → 연결 → 상품생성(product code 추가)
피드백 7개 먼저 적용
각 페이지별 적용사항 6개 적용
일정은 다음과 같다
~16:00 작업 순서 정리 완료 16:17 (과제 일지 정리로 인한 지연)
~16:40 로즈마리글라스 연결, 상품생성
~17:10 덕은철강 연결, 상품생성
~17:30 아낌없이주는나무 연결, 상품생성
~17:50 정렬 버튼 추가로 인한 시각화
~18:00 변동사항 없을 경우 toast 색 회색으로 변경
~18:20 No. index 대신 상품코드로 변경
~18:30 테이블 바닥 사이즈 고정
~19:00 상품을 누를 경우 상품 레코드 페이지로 이동 희망(상품명 A태그)
~20:00 저녁식사(먹는 사람 없으면 대충 먹기)
~20:10 페이지별 버튼 이름 바꾸기(xx동기화) 및 브랜드 변경
~20:20 전체 동기화 페이지 조정
~20:50 전체 동기화 함수 추가 및 적용
~21:20 전체 페이지 선택 동기화 함수 추가 및 적용
~21:30 각 페이지별 css파일 적용으로 인한 hovering 적용하기
첫 연결을 진행하는데 이번에도full - full 설정으로는 제대로 진행되지 않았기 때문에
모든 항목을 다 선택하니 정상적으로 넘어가는 모습을 볼 수 있었다.
연결 후 모든 상품을 제대로 넣었지만 되지 않아서 로그만 계속 찍고 있었는데
양쪽에서 디버그는 찍히지만 제대로 소통하지 않아서 뭔가 했는데
10분이 걸린다는 경고가 아마 이것과 관련있을지도 모르겠다.
어쨌건 동기화 및 내용이 제대로 들어간 것을 확인했지만
예시로 남겨둔 leather01부분이 마음에 안들어서 그 부분 먼저 처리하기로 했다.
leather01부분을 제거하기 위해서는 A, C org에서 주는 데이터에 ProductCode를 보내야 했고
각자 디플로이 후 받아온 데이터에서도 입력하게 해야 했는데
wrapper도 수정해야 했고 전반적으로 관여하는 느낌이었다.
productCode로도 정렬을 했으면 좋겠지만 불가능한데 이건 나중에 js로 처리하던지 버려야곘다.
세번째 org는 생각보다 빨리 처리할 수 있었지만
10분 가까이 인증이 진행되지 않는 대기시간이 있었다.
아무래도 초반에 막혀서 포기했던 부분들이 10분 기다려야 한다는 사실을 잘 모르고
이런저런 수정만 하다가 다른 방법을 찾아 떠났던 것 같다.
다시 네번째 org를 생성하가 아래의 메세지를 보게 됐는데
"error=invalid_client_id&error_description=client%20identifier%20invalid"이번에는 당황하지 않고 wood에 넣을 상품들을 확인하고 api code deploy를 진행했다.
정렬 버튼을 진행하는데 조건문을 넣을 수 없어서 수제로 비교하는 함수를 만들어서 각자 넣어줬는데
생각처럼 잘 작동하지 않고 자꾸 오름차순 정렬에 고정되어버렸다.
한참 원인을 찾으면서 로직을 변경하던 도중 웃긴 포인트를 발견했는데
아래와 같이 상품명↑로 값이 변했기 때문에 인식하지 못했고
현재 선택되지 않은 목록은 이름이 정상적이기 때문에 변화가 가능했던 것이었다.
아래와 같은 코드를 통해 문제를 해결했다.
if(sortTargetObj[this.sort] === sortTarget || sortTargetObj[this.sort] + '↑' === sortTarget || sortTargetObj[this.sort] + '↓' === sortTarget)
toast 색 변경은 간단하게 해결할 수 있었고
상품 코드로 변경은 기존 제품들의 상품 코드만 추가해야 하는 것이 아니라
업데이트를 진행해줘야 했지만
업데이트 진행 기준이 stock을 바탕으로 하기 때문에
결과적으로 모든 제품의 stock을 바꾸고 업데이트를 한 다음에 정상 작동이 되는 것을 볼 수 있었다.
테이블 바닥 사이즈는 height로는 변경이 되지 않았는데
자기만의 height 기준이 따로 있는 것 같았고
max-height으로 최대치 제한이 먹히고 min-height로 최소치 제한이 먹히는 것을 보면
여기서 적용한 css가 먼저 들어간 다음 라이트닝 클래스에서 css를 최후에 먹이는 느낌이었다.
다행히 max, min으로 두개를 다 섞어서 특정 수치로 고정할 수 있었기 때문에 높이 변경을 할 수 있었는데
이전에 vh, %로 해도 될 때가 있고 안될 때가 있던 것도 아마 이런 문제 때문이었던 것 같다.
상품을 누를 때 해당 레코드 페이지로 이동은
직접 주소값에 변수와 +연산자를 통해 id를 할당하지 못해서 생각보다 많이 귀찮았는데
wrapper를 한번 만든 덕을 봐서 url을 새로 추가해준 다음 url을 href에 할당할 수 있었다.
저녁식사는 사람이 거의 없어서 어쩔 수 없이 혼자 먹었는데
저번에 먹고 남은 피자와 컵라면 그리고 반숙란 하나를 먹었더니 든든했다.
페이지 버튼 바꾸기를 진행하려고 했는데 실수로 전체 페이지를 끄는 단축키(??)를 눌러버려서
다시 Access Restricted for API Only Users가 떠버렸다.
vscode에서 인증한 다음 SFDX:Open Default Browser를 사용하면 들어올 수 있다는 것을 알아서
바로 재로그인을 할 수 있었지만 혹시 이 키워드가 필요해지거나
도움이 필요한 사람이 이 키워드로 검색을 해서 볼 수 있도록 다시 적었다.
버튼의 브랜드가 아니고 variant를 바꾸는 것이었고
기존의 natural에서 success로 변경해서 괜찮은 모양을 볼 수 있었다.
전체 동기화 페이지에서 다른 버튼과는 다르게 전체 family 업데이트 함수를 만들어야 했기 때문에
일단 이름부터 부여한 다음 버튼의 onclick에 매칭해줬고
기능을 구현하는데 기존에 했던 코드에서 각자 family만 넣어주니 간단하게 해결할 수 있었다.
사실 진짜 어렵다고 생각되는 부분은 선택 동기화였는데
선택 동기화에서 어렵게 진행될 예정이었던 분할 자체를 family로 생각보다 편하게 할 수 있었고
아래와 같은 방식으로 에러핸들링 없이 빠르게 마무리할 수 있었다.
getTotalSelecteProducts() {
const leatherList = []
const glassList = []
const steelList = []
const woodList = []
let done = 0
let deleted = 0
let updated = 0
for (let i = 0; i < this.productList.length; i++) {
if (this.productList[i].isSelected) {
if(this.productList[i].family === 'leather'){
leatherList.push(this.productList[i].parentId);
}
else if(this.productList[i].family === 'glass'){
glassList.push(this.productList[i].parentId);
}
else if(this.productList[i].family === 'steel'){
steelList.push(this.productList[i].parentId);
}
else if(this.productList[i].family === 'wood'){
woodList.push(this.productList[i].parentId);
}
}
}
if(leatherList.length === 0 && glassList.length === 0 && steelList.length === 0 && woodList.length === 0){
this.dispatchEvent(
new ShowToastEvent({
title: "선택된 데이터 없음",
message: '업데이트 하고 싶은 상품을 선택해주세요',
variant: "error"
})
);
return
}
productUpdateWithParams({idLists:leatherList, family : 'leather'})
productUpdateWithParams({idLists:glassList, family : 'glass'})
productUpdateWithParams({idLists:steelList, family : 'steel'})
productUpdateWithParams({idLists:woodList, family : 'wood'})
}
css파일은 기존 내용과 동일하기 때문에
이 부분 때문에도 1시간 이상 검색을 했지만 제대로 된 내용은 없는 것 같았고
결국 5개의 css파일로 5개의 페이지에 적용하는 것으로 마무리했다.
사실 5개의 페이지로 spa를 만드는 것이 아니라
하나의 페이지에 만들 수도 있을 것 같았지만
lwc의 한계 때문에 여기서 10시간쯤 더 투자해야 하지만
당장 내일 발표기 때문에 여기서 마무리하기로 했다.
(1).백준 11367번 Report Card Time은 여러개의 테스트케이스가 주어지고
각 케이스에서는 이름과 점수가 있을 때 각 이름과 등급을 줄바꿈으로 출력하는 문제였다.
if문으로 분기처리를 해 각 등급을 구별해주고
마무리는 템플릿 리터럴로 두 값을 붙여줬지만
a + ' ' + b 형태로 진행해도 문제는 없었을 것 같다.
const input = `5
Bilbo 13
Sam 90
Pippin 78
Frodo 97
Merry 70`.split('\n')
const result = []
for(let i = 1 ; i < input.length ; i++){
let [name, nums] = input[i].split(' ')
nums = Number(nums)
let grade = 'F'
if(nums > 96){
grade = 'A+'
}
else if(nums > 89){
grade = 'A'
}
else if(nums > 86){
grade = 'B+'
}
else if(nums > 79){
grade = 'B'
}
else if(nums > 76){
grade = 'C+'
}
else if(nums > 69){
grade = 'C'
}
else if(nums > 66){
grade = 'D+'
}
else if(nums > 59){
grade = 'D'
}
result.push(`${name} ${grade}`)
}
console.log(result.join('\n'))