@dssp/project 1.0.0-y.0 → 1.0.1

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.
Files changed (92) hide show
  1. package/dist-client/pages/project/popup/checklist/task-checklist-attachment-list-popup.js +1 -2
  2. package/dist-client/pages/project/popup/checklist/task-checklist-attachment-list-popup.js.map +1 -1
  3. package/dist-client/pages/project/popup/checklist/task-checklist-comment-list-popup.js +1 -2
  4. package/dist-client/pages/project/popup/checklist/task-checklist-comment-list-popup.js.map +1 -1
  5. package/dist-client/pages/project/popup/checklist/task-checklist-create-popup.js +5 -4
  6. package/dist-client/pages/project/popup/checklist/task-checklist-create-popup.js.map +1 -1
  7. package/dist-client/pages/project/popup/checklist/task-checklist-view.d.ts +1 -0
  8. package/dist-client/pages/project/popup/checklist/task-checklist-view.js +65 -10
  9. package/dist-client/pages/project/popup/checklist/task-checklist-view.js.map +1 -1
  10. package/dist-client/pages/project/project-detail.d.ts +6 -0
  11. package/dist-client/pages/project/project-detail.js +188 -82
  12. package/dist-client/pages/project/project-detail.js.map +1 -1
  13. package/dist-client/pages/project/project-list.d.ts +16 -0
  14. package/dist-client/pages/project/project-list.js +14 -6
  15. package/dist-client/pages/project/project-list.js.map +1 -1
  16. package/dist-client/pages/project/project-plan-management.js +6 -1
  17. package/dist-client/pages/project/project-plan-management.js.map +1 -1
  18. package/dist-client/pages/project/project-setting-list.d.ts +2 -0
  19. package/dist-client/pages/project/project-setting-list.js +29 -4
  20. package/dist-client/pages/project/project-setting-list.js.map +1 -1
  21. package/dist-client/pages/project/project-task.js +8 -2
  22. package/dist-client/pages/project/project-task.js.map +1 -1
  23. package/dist-client/pages/project/project-update.d.ts +34 -0
  24. package/dist-client/pages/project/project-update.js +288 -8
  25. package/dist-client/pages/project/project-update.js.map +1 -1
  26. package/dist-client/pages/resource/construction-type-management.js +14 -0
  27. package/dist-client/pages/resource/construction-type-management.js.map +1 -1
  28. package/dist-client/pages/resource/resource-list-page.d.ts +1 -2
  29. package/dist-client/pages/resource/resource-list-page.js +1 -2
  30. package/dist-client/pages/resource/resource-list-page.js.map +1 -1
  31. package/dist-client/pages/task/task-list-page.d.ts +1 -2
  32. package/dist-client/pages/task/task-list-page.js +1 -2
  33. package/dist-client/pages/task/task-list-page.js.map +1 -1
  34. package/dist-client/pages/task-resource/task-resource-list-page.d.ts +1 -2
  35. package/dist-client/pages/task-resource/task-resource-list-page.js +1 -2
  36. package/dist-client/pages/task-resource/task-resource-list-page.js.map +1 -1
  37. package/dist-client/shared/domain-context.d.ts +18 -0
  38. package/dist-client/shared/domain-context.js +28 -0
  39. package/dist-client/shared/domain-context.js.map +1 -0
  40. package/dist-client/tsconfig.tsbuildinfo +1 -1
  41. package/dist-client/viewparts/domain-switch.d.ts +19 -0
  42. package/dist-client/viewparts/domain-switch.js +274 -0
  43. package/dist-client/viewparts/domain-switch.js.map +1 -0
  44. package/dist-server/migrations/1723861466414-seed-codes.js +1 -1
  45. package/dist-server/migrations/1723861466414-seed-codes.js.map +1 -1
  46. package/dist-server/service/construction-type/construction-type-query.d.ts +2 -2
  47. package/dist-server/service/construction-type/construction-type-query.js +5 -10
  48. package/dist-server/service/construction-type/construction-type-query.js.map +1 -1
  49. package/dist-server/service/construction-type/construction-type-type.d.ts +1 -0
  50. package/dist-server/service/construction-type/construction-type-type.js +4 -0
  51. package/dist-server/service/construction-type/construction-type-type.js.map +1 -1
  52. package/dist-server/service/construction-type/construction-type.d.ts +1 -0
  53. package/dist-server/service/construction-type/construction-type.js +5 -0
  54. package/dist-server/service/construction-type/construction-type.js.map +1 -1
  55. package/dist-server/service/inspection-drawing-type/inspection-drawing-type-query.d.ts +2 -2
  56. package/dist-server/service/inspection-drawing-type/inspection-drawing-type-query.js +5 -10
  57. package/dist-server/service/inspection-drawing-type/inspection-drawing-type-query.js.map +1 -1
  58. package/dist-server/service/manager/manager-query.d.ts +1 -1
  59. package/dist-server/service/manager/manager-query.js +2 -6
  60. package/dist-server/service/manager/manager-query.js.map +1 -1
  61. package/dist-server/service/project/issue-project-code.d.ts +7 -0
  62. package/dist-server/service/project/issue-project-code.js +27 -0
  63. package/dist-server/service/project/issue-project-code.js.map +1 -0
  64. package/dist-server/service/project/project-mutation.d.ts +2 -0
  65. package/dist-server/service/project/project-mutation.js +119 -10
  66. package/dist-server/service/project/project-mutation.js.map +1 -1
  67. package/dist-server/service/project/project-query.d.ts +11 -3
  68. package/dist-server/service/project/project-query.js +118 -26
  69. package/dist-server/service/project/project-query.js.map +1 -1
  70. package/dist-server/service/project/project-type.d.ts +8 -2
  71. package/dist-server/service/project/project-type.js +25 -1
  72. package/dist-server/service/project/project-type.js.map +1 -1
  73. package/dist-server/service/project/project.d.ts +14 -0
  74. package/dist-server/service/project/project.js +59 -2
  75. package/dist-server/service/project/project.js.map +1 -1
  76. package/dist-server/service/resource/resource-mutation.js +5 -6
  77. package/dist-server/service/resource/resource-mutation.js.map +1 -1
  78. package/dist-server/service/resource/resource-query.d.ts +2 -2
  79. package/dist-server/service/resource/resource-query.js +5 -10
  80. package/dist-server/service/resource/resource-query.js.map +1 -1
  81. package/dist-server/service/task-checklist-binding/task-checklist-binding-mutation.js +2 -0
  82. package/dist-server/service/task-checklist-binding/task-checklist-binding-mutation.js.map +1 -1
  83. package/dist-server/service/task-checklist-binding/task-checklist-binding.js +1 -1
  84. package/dist-server/service/task-checklist-binding/task-checklist-binding.js.map +1 -1
  85. package/dist-server/service/task-resource/task-resource-query.d.ts +2 -2
  86. package/dist-server/service/task-resource/task-resource-query.js +4 -9
  87. package/dist-server/service/task-resource/task-resource-query.js.map +1 -1
  88. package/dist-server/service/worker-type/worker-type-query.d.ts +2 -2
  89. package/dist-server/service/worker-type/worker-type-query.js +5 -10
  90. package/dist-server/service/worker-type/worker-type-query.js.map +1 -1
  91. package/dist-server/tsconfig.tsbuildinfo +1 -1
  92. package/package.json +15 -15
@@ -12,6 +12,7 @@ import gql from 'graphql-tag';
12
12
  import { SITE_TYPE_DISPLAY } from './project-list';
13
13
  import '../lib/select2-component';
14
14
  import './component/project-update-header';
15
+ import { isProjectTypeDomain } from '../../shared/domain-context';
15
16
  let ProjectUpdate = class ProjectUpdate extends ScopedElementsMixin(PageView) {
16
17
  constructor() {
17
18
  super(...arguments);
@@ -36,10 +37,14 @@ let ProjectUpdate = class ProjectUpdate extends ScopedElementsMixin(PageView) {
36
37
  this.taskConstructorList = [];
37
38
  this.taskSupervisoryList = [];
38
39
  this.overallSupervisoryList = [];
40
+ this.collectingBasicInfo = false;
39
41
  }
40
42
  get context() {
43
+ var _a, _b;
41
44
  return {
42
- title: '프로젝트 정보 관리'
45
+ title: !isProjectTypeDomain() && ((_a = this.project) === null || _a === void 0 ? void 0 : _a.name)
46
+ ? `프로젝트 정보 관리 - ${(_b = this.project) === null || _b === void 0 ? void 0 : _b.name}`
47
+ : '프로젝트 정보 관리'
43
48
  };
44
49
  }
45
50
  render() {
@@ -84,7 +89,7 @@ let ProjectUpdate = class ProjectUpdate extends ScopedElementsMixin(PageView) {
84
89
  </div>
85
90
  <div row>
86
91
  <span>프로젝트 주소</span>
87
- <span>
92
+ <span class="address-row">
88
93
  <md-outlined-text-field
89
94
  type="text"
90
95
  name="address"
@@ -92,6 +97,14 @@ let ProjectUpdate = class ProjectUpdate extends ScopedElementsMixin(PageView) {
92
97
  .value=${((_b = (_a = this.project) === null || _a === void 0 ? void 0 : _a.buildingComplex) === null || _b === void 0 ? void 0 : _b.address) || ''}
93
98
  @input=${this._onInputChange}
94
99
  ></md-outlined-text-field>
100
+ <md-elevated-button
101
+ class="info-link-btn"
102
+ ?disabled=${this.collectingBasicInfo}
103
+ @click=${() => this._collectBasicInfo()}
104
+ title="입력된 주소로 세움터 건축물대장 정보를 가져와 폼을 채웁니다"
105
+ >
106
+ ${this.collectingBasicInfo ? '연동 중…' : '🔗 정보 연동'}
107
+ </md-elevated-button>
95
108
  </span>
96
109
  </div>
97
110
  <div row>
@@ -307,7 +320,7 @@ let ProjectUpdate = class ProjectUpdate extends ScopedElementsMixin(PageView) {
307
320
  building-complex
308
321
  .value=${((_11 = (_10 = (_9 = this.project) === null || _9 === void 0 ? void 0 : _9.buildingComplex) === null || _10 === void 0 ? void 0 : _10.constructionCost) === null || _11 === void 0 ? void 0 : _11.toString()) || ''}
309
322
  @input=${this._onInputChange}
310
- suffix-text=""
323
+ suffix-text="억원"
311
324
  ></md-outlined-text-field>
312
325
  </span>
313
326
  </div>
@@ -388,6 +401,44 @@ let ProjectUpdate = class ProjectUpdate extends ScopedElementsMixin(PageView) {
388
401
  </div>
389
402
 
390
403
  <div detail-info>
404
+ <div>
405
+ <h3>테넌트 관리</h3>
406
+ <div row>
407
+ <span>관리번호</span>
408
+ <span>
409
+ ${this.project.tenantDomain
410
+ ? html `<a href=${`/project/${this.project.code}/`} target="_blank" title="테넌트로 이동"
411
+ >${this.project.code} <md-icon style="font-size:14px;vertical-align:middle">open_in_new</md-icon></a
412
+ >`
413
+ : this.project.code
414
+ ? html `${this.project.code}`
415
+ : html `<span style="color:#999">미발번 (승격 시 자동 부여)</span>`}
416
+ </span>
417
+ </div>
418
+ <div row>
419
+ <span>현재 상태</span>
420
+ <span>
421
+ ${this.project.tenantDomain
422
+ ? html `<b style="color:#42b382">활성 테넌트</b>`
423
+ : this.project.code
424
+ ? html `<b style="color:#aa6633">강등됨</b> (재승격 시 ${this.project.code} 재사용)`
425
+ : html `<b style="color:#999">미승격</b>`}
426
+ </span>
427
+ </div>
428
+ <div row>
429
+ <span></span>
430
+ <span tenant-actions>
431
+ ${this.project.tenantDomain
432
+ ? html `<md-elevated-button @click=${this._demoteTenant} ?disabled=${!this.project.id}>
433
+ <md-icon slot="icon">link_off</md-icon>테넌트 강등
434
+ </md-elevated-button>`
435
+ : html `<md-elevated-button green @click=${this._promoteTenant} ?disabled=${!this.project.id}>
436
+ <md-icon slot="icon">verified</md-icon>테넌트 승격
437
+ </md-elevated-button>`}
438
+ </span>
439
+ </div>
440
+ </div>
441
+
391
442
  <div>
392
443
  <h3>건설구분 상세 정보</h3>
393
444
  <div row>
@@ -673,10 +724,30 @@ let ProjectUpdate = class ProjectUpdate extends ScopedElementsMixin(PageView) {
673
724
  }
674
725
  async pageInitialized(lifecycle) { }
675
726
  async pageUpdated(changes, lifecycle) {
676
- if (this.active) {
677
- this.projectId = lifecycle.resourceId || '';
678
- await this.initProject(this.projectId);
727
+ if (!this.active)
728
+ return;
729
+ this.projectId = await this._resolveProjectId(lifecycle.resourceId || '');
730
+ await this.initProject(this.projectId);
731
+ }
732
+ /**
733
+ * resourceId 를 정상 Project.id (UUID) 로 변환한다.
734
+ * - UUID 형식이면 그대로 사용
735
+ * - 그 외 (code 또는 비어있음) 에는 현재 테넌트 컨텍스트의 프로젝트 조회
736
+ */
737
+ async _resolveProjectId(resourceId) {
738
+ var _a, _b;
739
+ if (resourceId && resourceId.length === 36)
740
+ return resourceId;
741
+ const response = await client.query({
742
+ query: gql `
743
+ query CurrentProject {
744
+ currentProject {
745
+ id
746
+ }
679
747
  }
748
+ `
749
+ });
750
+ return ((_b = (_a = response.data) === null || _a === void 0 ? void 0 : _a.currentProject) === null || _b === void 0 ? void 0 : _b.id) || '';
680
751
  }
681
752
  async initProject(projectId = '') {
682
753
  var _a, _b, _c;
@@ -685,6 +756,12 @@ let ProjectUpdate = class ProjectUpdate extends ScopedElementsMixin(PageView) {
685
756
  query Project($id: String!, $filters: [Filter!]) {
686
757
  project(id: $id) {
687
758
  id
759
+ code
760
+ tenantDomain {
761
+ id
762
+ subdomain
763
+ name
764
+ }
688
765
  name
689
766
  documentNaming
690
767
  startDate
@@ -773,22 +850,41 @@ let ProjectUpdate = class ProjectUpdate extends ScopedElementsMixin(PageView) {
773
850
  ]
774
851
  }
775
852
  });
776
- this.project = (_a = response.data) === null || _a === void 0 ? void 0 : _a.project;
853
+ this.project = ((_a = response.data) === null || _a === void 0 ? void 0 : _a.project) || Object.assign({}, this.defaultProject);
777
854
  const items = ((_c = (_b = response.data) === null || _b === void 0 ? void 0 : _b.employees) === null || _c === void 0 ? void 0 : _c.items) || [];
778
855
  this.overallConstructorList = this._filterUserByPermission(items, 'OVERALL_CONSTRUCTOR');
779
856
  this.taskConstructorList = this._filterUserByPermission(items, 'TASK_CONSTRUCTOR');
780
857
  this.overallSupervisoryList = this._filterUserByPermission(items, 'OVERALL_SUPERVISORY');
781
858
  this.taskSupervisoryList = this._filterUserByPermission(items, 'TASK_SUPERVISORY');
859
+ this.updateContext();
782
860
  }
783
861
  _filterUserByPermission(userList, permission) {
784
862
  return userList
785
863
  .filter(v => v.jobResponsibility == permission || v.jobResponsibility == 'ADMIN')
786
864
  .map(v => ({ name: v.name, value: v.user.email }));
787
865
  }
866
+ _stripTypename(obj) {
867
+ if (Array.isArray(obj)) {
868
+ return obj.map(item => this._stripTypename(item));
869
+ }
870
+ if (obj && typeof obj === 'object' && !(obj instanceof File)) {
871
+ const cleaned = {};
872
+ for (const [key, value] of Object.entries(obj)) {
873
+ if (key === '__typename')
874
+ continue;
875
+ cleaned[key] = this._stripTypename(value);
876
+ }
877
+ return cleaned;
878
+ }
879
+ return obj;
880
+ }
788
881
  async _saveProject() {
789
882
  // 첨부 파일 필드 제거 (첨부 파일은 {filename}Upload 로 전송)
790
883
  delete this.project.mainPhoto;
791
884
  delete this.project.buildingComplex.drawing;
885
+ // ProjectPatch 입력 타입에 없는 표시 전용 필드 제거 (테넌트 승격 UI 표시용)
886
+ delete this.project.code;
887
+ delete this.project.tenantDomain;
792
888
  const response = await client.mutate({
793
889
  mutation: gql `
794
890
  mutation UpdateProject($project: ProjectPatch!) {
@@ -798,7 +894,7 @@ let ProjectUpdate = class ProjectUpdate extends ScopedElementsMixin(PageView) {
798
894
  }
799
895
  `,
800
896
  variables: {
801
- project: this.project
897
+ project: this._stripTypename(this.project)
802
898
  },
803
899
  context: {
804
900
  hasUpload: true
@@ -808,6 +904,174 @@ let ProjectUpdate = class ProjectUpdate extends ScopedElementsMixin(PageView) {
808
904
  notify({ message: '저장에 성공하였습니다.' });
809
905
  }
810
906
  }
907
+ /**
908
+ * 주소 옆 "정보 연동" 버튼 handler.
909
+ * - 현재 폼의 주소를 backend 로 보냄 → backend 가 EnvVar 갱신 + 세움터 시나리오 호출
910
+ * - 결과 (한글 raw + 숫자) 를 받아 BuildingComplex 폼 필드들에 매핑
911
+ * · siteType (한글) → SiteType enum 변환 (BC.siteType, enum 컬럼)
912
+ * · siteType (한글) → BC.constructionType 그대로 (자유 텍스트 컬럼)
913
+ * · area / floorAreaRatio / coverageRatio / householdCount / buildingCount /
914
+ * structureType → BC 동명 컬럼에 직접 대입
915
+ * · upperFloorCount / lowerFloorCount / bldNm / useAprDay / pmsDay → BC 컬럼
916
+ * 없음, 매핑 skip (참고용 콘솔 로그만)
917
+ */
918
+ async _collectBasicInfo() {
919
+ var _a, _b, _c;
920
+ const address = (((_b = (_a = this.project) === null || _a === void 0 ? void 0 : _a.buildingComplex) === null || _b === void 0 ? void 0 : _b.address) || '').trim();
921
+ if (!address) {
922
+ notify({ message: '먼저 프로젝트 주소를 입력해 주세요.' });
923
+ return;
924
+ }
925
+ this.collectingBasicInfo = true;
926
+ try {
927
+ const response = await client.mutate({
928
+ mutation: gql `
929
+ mutation CollectProjectBasicInfo($projectId: String!, $address: String) {
930
+ collectProjectBasicInfo(projectId: $projectId, address: $address) {
931
+ source
932
+ label
933
+ ok
934
+ message
935
+ data
936
+ }
937
+ }
938
+ `,
939
+ variables: { projectId: this.project.id, address }
940
+ });
941
+ if (response.errors) {
942
+ throw new Error(response.errors.map((e) => e.message).join('\n'));
943
+ }
944
+ const result = (_c = response.data) === null || _c === void 0 ? void 0 : _c.collectProjectBasicInfo;
945
+ if (!(result === null || result === void 0 ? void 0 : result.ok)) {
946
+ notify({ message: (result === null || result === void 0 ? void 0 : result.message) || '업데이트할 정보가 없습니다.' });
947
+ return;
948
+ }
949
+ const data = result.data || {};
950
+ this._applyBasicInfoToForm(data);
951
+ this.requestUpdate();
952
+ notify({ message: '외부 시스템에서 기본 정보를 가져왔습니다. 검토 후 [저장]을 눌러주세요.' });
953
+ }
954
+ catch (err) {
955
+ console.warn('[정보 연동] 실패', err);
956
+ notify({ message: '외부 시스템 연동이 일시적으로 안 됩니다.' });
957
+ }
958
+ finally {
959
+ this.collectingBasicInfo = false;
960
+ }
961
+ }
962
+ /**
963
+ * 한글 주용도명 → SiteType enum.
964
+ * - NFC normalize + 공백 제거로 보이지 않는 문자/표기 차이 대응
965
+ * - 매핑 미존재시 null
966
+ */
967
+ _siteTypeFromKorean(korean) {
968
+ if (!korean)
969
+ return null;
970
+ const KEYS = {
971
+ 공동주택: 'APARTMENT_COMPLEX',
972
+ 단독주택: 'DETACHED_HOUSE',
973
+ 제1종근린생활시설: 'NEIGHBORHOOD_FACILITY',
974
+ 제2종근린생활시설: 'NEIGHBORHOOD_FACILITY',
975
+ 근린생활시설: 'NEIGHBORHOOD_FACILITY',
976
+ 업무시설: 'OFFICE',
977
+ 판매시설: 'COMMERCIAL',
978
+ 교육연구시설: 'EDUCATION',
979
+ 의료시설: 'MEDICAL',
980
+ 문화및집회시설: 'CULTURAL',
981
+ 종교시설: 'RELIGIOUS',
982
+ 공장: 'INDUSTRIAL',
983
+ 창고시설: 'INDUSTRIAL',
984
+ 운수시설: 'TRANSPORT'
985
+ };
986
+ const key = korean.normalize('NFC').replace(/\s+/g, '').trim();
987
+ return KEYS[key] || null;
988
+ }
989
+ /**
990
+ * 시나리오 result data 를 폼에 매핑 — BuildingComplex 와 Project 양쪽.
991
+ * 빈 값(null/undefined/'')은 기존 값 유지 — 자동 수집이 사용자 입력을 무리하게 덮지 않도록.
992
+ */
993
+ _applyBasicInfoToForm(data) {
994
+ const bc = Object.assign({}, this.project.buildingComplex);
995
+ const setBC = (key, value) => {
996
+ if (value === null || value === undefined || value === '')
997
+ return;
998
+ bc[key] = value;
999
+ };
1000
+ setBC('area', this._toNum(data.area));
1001
+ setBC('floorAreaRatio', this._toNum(data.floorAreaRatio));
1002
+ setBC('coverageRatio', this._toNum(data.coverageRatio));
1003
+ setBC('householdCount', this._toNum(data.householdCount));
1004
+ setBC('buildingCount', this._toNum(data.buildingCount));
1005
+ setBC('structureType', data.structureType);
1006
+ // siteType: 한글 → SiteType enum 매핑. 매핑 안 되면 BC.siteType 빈 채로.
1007
+ if (data.siteType) {
1008
+ const enumVal = this._siteTypeFromKorean(data.siteType);
1009
+ if (enumVal)
1010
+ bc.siteType = enumVal;
1011
+ }
1012
+ // Project 엔티티 컬럼 — 착공일/준공일.
1013
+ // 세움터 useAprDay (사용승인일) = 준공으로 매핑. stcnsDay = 착공.
1014
+ const project = Object.assign(Object.assign({}, this.project), { buildingComplex: bc });
1015
+ if (data.startDate)
1016
+ project.startDate = data.startDate;
1017
+ if (data.endDate)
1018
+ project.endDate = data.endDate;
1019
+ this.project = project;
1020
+ // 참고 메타 — BC/Project 직접 컬럼 없음, 콘솔로만 (permitDate=건축허가일, bldNm 등)
1021
+ console.log('[정보 연동] meta:', JSON.stringify({
1022
+ upperFloorCount: data.upperFloorCount,
1023
+ lowerFloorCount: data.lowerFloorCount,
1024
+ bldNm: data.bldNm,
1025
+ permitDate: data.permitDate
1026
+ }));
1027
+ }
1028
+ _toNum(v) {
1029
+ if (v === null || v === undefined || v === '')
1030
+ return null;
1031
+ const n = Number(v);
1032
+ return Number.isFinite(n) ? n : null;
1033
+ }
1034
+ async _promoteTenant() {
1035
+ if (!this.project.id)
1036
+ return;
1037
+ if (!confirm('이 프로젝트를 테넌트로 승격하시겠습니까?\n승격 시 관리번호(YYYY-NNNNN)가 자동 발번되며 변경할 수 없습니다.')) {
1038
+ return;
1039
+ }
1040
+ const response = await client.mutate({
1041
+ mutation: gql `
1042
+ mutation PromoteProjectToTenant($projectId: String!) {
1043
+ promoteProjectToTenant(projectId: $projectId) {
1044
+ id
1045
+ code
1046
+ }
1047
+ }
1048
+ `,
1049
+ variables: { projectId: this.project.id }
1050
+ });
1051
+ if (!response.errors) {
1052
+ notify({ message: `테넌트로 승격되었습니다. 관리번호: ${response.data.promoteProjectToTenant.code}` });
1053
+ await this.initProject(this.projectId);
1054
+ }
1055
+ }
1056
+ async _demoteTenant() {
1057
+ if (!this.project.id)
1058
+ return;
1059
+ if (!confirm('이 프로젝트의 테넌트를 강등하시겠습니까?\n관리번호는 보존되며 재승격 시 같은 번호가 재사용됩니다.')) {
1060
+ return;
1061
+ }
1062
+ const response = await client.mutate({
1063
+ mutation: gql `
1064
+ mutation DemoteProjectTenant($projectId: String!) {
1065
+ demoteProjectTenant(projectId: $projectId)
1066
+ }
1067
+ `,
1068
+ variables: { projectId: this.project.id }
1069
+ });
1070
+ if (!response.errors) {
1071
+ notify({ message: '테넌트가 강등되었습니다.' });
1072
+ await this.initProject(this.projectId);
1073
+ }
1074
+ }
811
1075
  // 동 적용 버튼을 누르면 입력한 수 만큼 해당 단지에 동 데이터 생성
812
1076
  _setBuilding() {
813
1077
  var _a, _b, _c, _d, _e;
@@ -978,6 +1242,18 @@ ProjectUpdate.styles = [
978
1242
  margin-left: var(--spacing-medium, 8px);
979
1243
  align-items: center;
980
1244
 
1245
+ &.address-row {
1246
+ md-outlined-text-field {
1247
+ flex: 1;
1248
+ }
1249
+ .info-link-btn {
1250
+ flex: 0 0 auto;
1251
+ --md-elevated-button-container-color: #2e79be;
1252
+ --md-elevated-button-label-text-color: #fff;
1253
+ --md-elevated-button-container-height: 36px;
1254
+ }
1255
+ }
1256
+
981
1257
  &[align-end] {
982
1258
  align-items: end;
983
1259
  }
@@ -1190,6 +1466,10 @@ __decorate([
1190
1466
  state(),
1191
1467
  __metadata("design:type", Array)
1192
1468
  ], ProjectUpdate.prototype, "overallSupervisoryList", void 0);
1469
+ __decorate([
1470
+ state(),
1471
+ __metadata("design:type", Boolean)
1472
+ ], ProjectUpdate.prototype, "collectingBasicInfo", void 0);
1193
1473
  ProjectUpdate = __decorate([
1194
1474
  customElement('project-update')
1195
1475
  ], ProjectUpdate);