@simplysm/angular 14.0.37 → 14.0.39
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/controls/checkbox/sd-checkbox.d.ts +1 -1
- package/dist/controls/checkbox/sd-checkbox.d.ts.map +1 -1
- package/dist/controls/checkbox/sd-checkbox.js +8 -5
- package/dist/controls/checkbox/sd-switch.d.ts +3 -1
- package/dist/controls/checkbox/sd-switch.d.ts.map +1 -1
- package/dist/controls/checkbox/sd-switch.js +11 -5
- package/dist/controls/dropdown/sd-dropdown.js +8 -8
- package/dist/controls/input/{sd-date-range.picker.d.ts → sd-date-range-picker.d.ts} +1 -1
- package/dist/controls/input/{sd-date-range.picker.d.ts.map → sd-date-range-picker.d.ts.map} +1 -1
- package/dist/controls/input/{sd-date-range.picker.js → sd-date-range-picker.js} +1 -1
- package/dist/controls/input/sd-textfield.d.ts.map +1 -1
- package/dist/controls/input/sd-textfield.js +1 -0
- package/dist/core/error-handler/sd-global-error-handler.plugin.d.ts.map +1 -1
- package/dist/core/error-handler/sd-global-error-handler.plugin.js +7 -2
- package/dist/core/modal/sd-activated-modal.provider.d.ts +1 -1
- package/dist/core/modal/sd-activated-modal.provider.d.ts.map +1 -1
- package/dist/core/modal/sd-activated-modal.provider.js +1 -1
- package/dist/core/modal/sd-modal.d.ts +2 -3
- package/dist/core/modal/sd-modal.d.ts.map +1 -1
- package/dist/core/modal/sd-modal.js +9 -10
- package/dist/core/modal/sd-modal.provider.d.ts +0 -1
- package/dist/core/modal/sd-modal.provider.d.ts.map +1 -1
- package/dist/core/modal/sd-modal.provider.js +14 -6
- package/dist/core/routing/sd-navigate-window.provider.d.ts.map +1 -1
- package/dist/core/routing/sd-navigate-window.provider.js +3 -1
- package/dist/core/routing/setupCanDeactivate.js +1 -1
- package/dist/core/selection/useSelectionManager.d.ts.map +1 -1
- package/dist/core/selection/useSelectionManager.js +4 -3
- package/dist/core/setupModelHook.d.ts.map +1 -1
- package/dist/core/setupModelHook.js +18 -1
- package/dist/core/shared-data/sd-shared-data.provider.d.ts.map +1 -1
- package/dist/core/shared-data/sd-shared-data.provider.js +12 -3
- package/dist/data/data-detail/sd-data-detail.base.d.ts +1 -1
- package/dist/data/data-detail/sd-data-detail.base.d.ts.map +1 -1
- package/dist/data/data-detail/sd-data-detail.base.js +24 -19
- package/dist/data/data-sheet/injectDataSheetExcelManager.js +1 -1
- package/dist/data/data-sheet/injectDataSheetModalEditManager.js +1 -1
- package/dist/data/data-sheet/sd-data-sheet.base.d.ts +1 -2
- package/dist/data/data-sheet/sd-data-sheet.base.d.ts.map +1 -1
- package/dist/data/data-sheet/sd-data-sheet.base.js +5 -13
- package/dist/data/getOrmDataEditToastErrorMessage.d.ts +2 -0
- package/dist/data/getOrmDataEditToastErrorMessage.d.ts.map +1 -0
- package/dist/data/getOrmDataEditToastErrorMessage.js +8 -0
- package/dist/data/permission-table/sd-permission-table.d.ts +1 -1
- package/dist/data/permission-table/sd-permission-table.d.ts.map +1 -1
- package/dist/data/permission-table/sd-permission-table.js +6 -5
- package/dist/data/shared-data/sd-shared-data-select.d.ts +1 -0
- package/dist/data/shared-data/sd-shared-data-select.d.ts.map +1 -1
- package/dist/data/shared-data/sd-shared-data-select.js +15 -7
- package/dist/data/sheet/injectSheetColumnResizing.d.ts.map +1 -1
- package/dist/data/sheet/injectSheetColumnResizing.js +1 -0
- package/dist/data/state-preset/sd-state-preset.d.ts.map +1 -1
- package/dist/data/state-preset/sd-state-preset.js +4 -0
- package/dist/features/address/sd-address-search.modal.d.ts +2 -1
- package/dist/features/address/sd-address-search.modal.d.ts.map +1 -1
- package/dist/features/address/sd-address-search.modal.js +69 -23
- package/dist/features/editor/sd-tiptap-editor.d.ts.map +1 -1
- package/dist/features/editor/sd-tiptap-editor.js +3 -1
- package/dist/features/visual/sd-barcode.d.ts.map +1 -1
- package/dist/features/visual/sd-barcode.js +10 -5
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/layout/base-container/sd-base-container.d.ts +1 -0
- package/dist/layout/base-container/sd-base-container.d.ts.map +1 -1
- package/dist/layout/base-container/sd-base-container.js +5 -2
- package/dist/layout/dock/sd-dock.d.ts.map +1 -1
- package/dist/layout/dock/sd-dock.js +1 -0
- package/package.json +8 -7
- package/src/controls/checkbox/sd-checkbox.ts +7 -3
- package/src/controls/checkbox/sd-switch.ts +8 -2
- package/src/controls/dropdown/sd-dropdown.ts +8 -8
- package/src/controls/input/sd-textfield.ts +1 -0
- package/src/core/error-handler/sd-global-error-handler.plugin.ts +6 -2
- package/src/core/modal/sd-activated-modal.provider.ts +1 -1
- package/src/core/modal/sd-modal.provider.ts +13 -7
- package/src/core/modal/sd-modal.ts +6 -6
- package/src/core/routing/sd-navigate-window.provider.ts +3 -1
- package/src/core/routing/setupCanDeactivate.ts +1 -1
- package/src/core/selection/useSelectionManager.ts +5 -3
- package/src/core/setupModelHook.ts +21 -1
- package/src/core/shared-data/sd-shared-data.provider.ts +13 -2
- package/src/data/data-detail/sd-data-detail.base.ts +27 -23
- package/src/data/data-sheet/injectDataSheetExcelManager.ts +1 -1
- package/src/data/data-sheet/injectDataSheetModalEditManager.ts +1 -1
- package/src/data/data-sheet/sd-data-sheet.base.ts +5 -16
- package/src/data/getOrmDataEditToastErrorMessage.ts +10 -0
- package/src/data/permission-table/sd-permission-table.ts +7 -6
- package/src/data/shared-data/sd-shared-data-select.ts +24 -13
- package/src/data/sheet/injectSheetColumnResizing.ts +2 -0
- package/src/data/state-preset/sd-state-preset.ts +6 -0
- package/src/features/address/sd-address-search.modal.ts +75 -31
- package/src/features/editor/sd-tiptap-editor.ts +2 -0
- package/src/features/visual/sd-barcode.ts +9 -5
- package/src/index.ts +4 -1
- package/src/layout/base-container/sd-base-container.ts +4 -1
- package/src/layout/dock/sd-dock.ts +2 -0
- /package/src/controls/input/{sd-date-range.picker.ts → sd-date-range-picker.ts} +0 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Directive,
|
|
3
3
|
effect,
|
|
4
|
+
ErrorHandler,
|
|
4
5
|
inject,
|
|
5
6
|
output,
|
|
6
7
|
signal,
|
|
@@ -15,6 +16,7 @@ import { injectViewTypeSignal } from "../../core/routing/injectViewTypeSignal";
|
|
|
15
16
|
import { withBusy } from "../../core/withBusy";
|
|
16
17
|
import { type SdModalContentDef } from "../../core/modal/sd-modal.provider";
|
|
17
18
|
import { SdToastProvider } from "../../core/toast/sd-toast.provider";
|
|
19
|
+
import { getOrmDataEditToastErrorMessage } from "../getOrmDataEditToastErrorMessage";
|
|
18
20
|
|
|
19
21
|
export interface SdDataDetailDataInfo {
|
|
20
22
|
isNew: boolean;
|
|
@@ -47,6 +49,7 @@ export abstract class SdDataDetailBase<T extends object, R = boolean>
|
|
|
47
49
|
|
|
48
50
|
private readonly _sdToast = inject(SdToastProvider);
|
|
49
51
|
private readonly _sdSharedData = inject(SdSharedDataProvider);
|
|
52
|
+
private readonly _errorHandler = inject(ErrorHandler);
|
|
50
53
|
|
|
51
54
|
viewType = injectViewTypeSignal(() => this);
|
|
52
55
|
|
|
@@ -63,22 +66,33 @@ export abstract class SdDataDetailBase<T extends object, R = boolean>
|
|
|
63
66
|
private _dataSnapshot?: T;
|
|
64
67
|
|
|
65
68
|
constructor() {
|
|
66
|
-
effect(() => {
|
|
69
|
+
effect((onCleanup) => {
|
|
67
70
|
this.prepareRefreshEffect?.();
|
|
68
71
|
|
|
72
|
+
let cancelled = false;
|
|
73
|
+
onCleanup(() => {
|
|
74
|
+
cancelled = true;
|
|
75
|
+
});
|
|
76
|
+
|
|
69
77
|
queueMicrotask(async () => {
|
|
70
|
-
|
|
78
|
+
try {
|
|
79
|
+
if (cancelled) return;
|
|
80
|
+
|
|
81
|
+
if (!this.canUse()) {
|
|
82
|
+
this.initialized.set(true);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
await withBusy(this.busyCount, () =>
|
|
87
|
+
this._sdToast.try(async () => {
|
|
88
|
+
await this._sdSharedData.wait();
|
|
89
|
+
await this.refresh();
|
|
90
|
+
}),
|
|
91
|
+
);
|
|
71
92
|
this.initialized.set(true);
|
|
72
|
-
|
|
93
|
+
} catch (err) {
|
|
94
|
+
this._errorHandler.handleError(err);
|
|
73
95
|
}
|
|
74
|
-
|
|
75
|
-
await withBusy(this.busyCount, () =>
|
|
76
|
-
this._sdToast.try(async () => {
|
|
77
|
-
await this._sdSharedData.wait();
|
|
78
|
-
await this.refresh();
|
|
79
|
-
}),
|
|
80
|
-
);
|
|
81
|
-
this.initialized.set(true);
|
|
82
96
|
});
|
|
83
97
|
});
|
|
84
98
|
|
|
@@ -130,7 +144,7 @@ export abstract class SdDataDetailBase<T extends object, R = boolean>
|
|
|
130
144
|
|
|
131
145
|
this.close.emit(result);
|
|
132
146
|
},
|
|
133
|
-
(err) =>
|
|
147
|
+
(err) => getOrmDataEditToastErrorMessage(err),
|
|
134
148
|
),
|
|
135
149
|
);
|
|
136
150
|
}
|
|
@@ -165,19 +179,9 @@ export abstract class SdDataDetailBase<T extends object, R = boolean>
|
|
|
165
179
|
|
|
166
180
|
await this.refresh();
|
|
167
181
|
},
|
|
168
|
-
(err) =>
|
|
182
|
+
(err) => getOrmDataEditToastErrorMessage(err),
|
|
169
183
|
),
|
|
170
184
|
);
|
|
171
185
|
}
|
|
172
186
|
|
|
173
|
-
private _getOrmDataEditToastErrorMessage(err: unknown) {
|
|
174
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
175
|
-
if (
|
|
176
|
-
message.includes("a parent row: a foreign key constraint") ||
|
|
177
|
-
message.includes("conflicted with the REFERENCE")
|
|
178
|
-
) {
|
|
179
|
-
return "경고! 연결된 작업에 의한 처리 거부. 후속작업 확인 요망";
|
|
180
|
-
}
|
|
181
|
-
return message;
|
|
182
|
-
}
|
|
183
187
|
}
|
|
@@ -46,7 +46,7 @@ export function injectDataSheetExcelManager<TItem>(options: {
|
|
|
46
46
|
async () => {
|
|
47
47
|
await uploadExcelFn(file);
|
|
48
48
|
await options.refresh();
|
|
49
|
-
sdToast.success("엑셀 업로드가
|
|
49
|
+
sdToast.success("엑셀 업로드가 완료되었습니다.");
|
|
50
50
|
},
|
|
51
51
|
(err) => options.errorMessageFn(err),
|
|
52
52
|
),
|
|
@@ -51,7 +51,7 @@ export function injectDataSheetModalEditManager<TItem, TKey>(options: {
|
|
|
51
51
|
if (!result) return;
|
|
52
52
|
|
|
53
53
|
await options.refresh();
|
|
54
|
-
sdToast.success(`${del ? "삭제" : "복구"}
|
|
54
|
+
sdToast.success(`${del ? "삭제" : "복구"}되었습니다.`);
|
|
55
55
|
},
|
|
56
56
|
(err) => options.errorMessageFn(err),
|
|
57
57
|
),
|
|
@@ -25,6 +25,7 @@ import { injectDataSheetRefreshManager } from "./injectDataSheetRefreshManager";
|
|
|
25
25
|
import { injectDataSheetInlineEditManager } from "./injectDataSheetInlineEditManager";
|
|
26
26
|
import { injectDataSheetModalEditManager } from "./injectDataSheetModalEditManager";
|
|
27
27
|
import { injectDataSheetExcelManager } from "./injectDataSheetExcelManager";
|
|
28
|
+
import { getOrmDataEditToastErrorMessage } from "../getOrmDataEditToastErrorMessage";
|
|
28
29
|
|
|
29
30
|
export type {
|
|
30
31
|
SdDataSheetItemPropInfo,
|
|
@@ -84,7 +85,7 @@ export abstract class SdDataSheetBase<
|
|
|
84
85
|
private readonly _excelMgr: ReturnType<typeof injectDataSheetExcelManager<TItem>>;
|
|
85
86
|
|
|
86
87
|
//-- shared state (D1: class 소유)
|
|
87
|
-
key = reflectComponentType(this.constructor as any)?.selector;
|
|
88
|
+
key = reflectComponentType(this.constructor as any)?.selector ?? this.constructor.name;
|
|
88
89
|
|
|
89
90
|
viewType = injectViewTypeSignal(() => this);
|
|
90
91
|
|
|
@@ -197,7 +198,7 @@ export abstract class SdDataSheetBase<
|
|
|
197
198
|
refresh: () => this._refreshMgr.refresh(),
|
|
198
199
|
getNewItemFn: () => this.newItem?.bind(this),
|
|
199
200
|
getSubmitFn: () => this.submit?.bind(this),
|
|
200
|
-
errorMessageFn: (err) =>
|
|
201
|
+
errorMessageFn: (err) => getOrmDataEditToastErrorMessage(err),
|
|
201
202
|
});
|
|
202
203
|
|
|
203
204
|
//-- modal edit composable
|
|
@@ -210,7 +211,7 @@ export abstract class SdDataSheetBase<
|
|
|
210
211
|
refresh: () => this._refreshMgr.refresh(),
|
|
211
212
|
getEditItemFn: () => this.editItem?.bind(this),
|
|
212
213
|
getToggleDeleteItemsFn: () => this.toggleDeleteItems?.bind(this),
|
|
213
|
-
errorMessageFn: (err) =>
|
|
214
|
+
errorMessageFn: (err) => getOrmDataEditToastErrorMessage(err),
|
|
214
215
|
});
|
|
215
216
|
|
|
216
217
|
//-- excel composable
|
|
@@ -220,7 +221,7 @@ export abstract class SdDataSheetBase<
|
|
|
220
221
|
refresh: () => this._refreshMgr.refresh(),
|
|
221
222
|
getDownloadExcelFn: () => this.downloadExcel?.bind(this),
|
|
222
223
|
getUploadExcelFn: () => this.uploadExcel?.bind(this),
|
|
223
|
-
errorMessageFn: (err) =>
|
|
224
|
+
errorMessageFn: (err) => getOrmDataEditToastErrorMessage(err),
|
|
224
225
|
});
|
|
225
226
|
|
|
226
227
|
setupCanDeactivate(() => this.viewType() === "modal" || this.checkIgnoreChanges());
|
|
@@ -290,16 +291,4 @@ export abstract class SdDataSheetBase<
|
|
|
290
291
|
await this._excelMgr.doUploadExcel();
|
|
291
292
|
}
|
|
292
293
|
|
|
293
|
-
//-- private
|
|
294
|
-
|
|
295
|
-
private _getOrmDataEditToastErrorMessage(err: unknown) {
|
|
296
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
297
|
-
if (
|
|
298
|
-
message.includes("a parent row: a foreign key constraint") ||
|
|
299
|
-
message.includes("conflicted with the REFERENCE")
|
|
300
|
-
) {
|
|
301
|
-
return "경고! 연결된 작업에 의한 처리 거부. 후속작업 확인 요망";
|
|
302
|
-
}
|
|
303
|
-
return message;
|
|
304
|
-
}
|
|
305
294
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export function getOrmDataEditToastErrorMessage(err: unknown): string {
|
|
2
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
3
|
+
if (
|
|
4
|
+
message.includes("a parent row: a foreign key constraint") ||
|
|
5
|
+
message.includes("conflicted with the REFERENCE")
|
|
6
|
+
) {
|
|
7
|
+
return "경고! 연결된 작업에 의한 처리 거부. 후속작업 확인 요망";
|
|
8
|
+
}
|
|
9
|
+
return message;
|
|
10
|
+
}
|
|
@@ -215,7 +215,7 @@ export class SdPermissionTable<TModule> {
|
|
|
215
215
|
items = input<SdPermission<TModule>[]>([]);
|
|
216
216
|
disabled = input(false, { transform: booleanAttribute });
|
|
217
217
|
|
|
218
|
-
collapsedItems = signal(new Set<
|
|
218
|
+
collapsedItems = signal(new Set<string>());
|
|
219
219
|
|
|
220
220
|
depthLength = computed(() => {
|
|
221
221
|
return this._getDepthLength(this.items(), 0);
|
|
@@ -347,7 +347,7 @@ export class SdPermissionTable<TModule> {
|
|
|
347
347
|
}
|
|
348
348
|
|
|
349
349
|
getIsPermCollapsed(item: SdPermission<TModule>): boolean {
|
|
350
|
-
return this.collapsedItems().has(item);
|
|
350
|
+
return this.collapsedItems().has(item.codeChain.join("."));
|
|
351
351
|
}
|
|
352
352
|
|
|
353
353
|
getAllChildren(item: SdPermission<TModule>): SdPermission<TModule>[] {
|
|
@@ -367,15 +367,16 @@ export class SdPermissionTable<TModule> {
|
|
|
367
367
|
}
|
|
368
368
|
|
|
369
369
|
onPermCollapseToggle(item: SdPermission<TModule>) {
|
|
370
|
+
const key = item.codeChain.join(".");
|
|
370
371
|
this.collapsedItems.update((v) => {
|
|
371
372
|
const r = new Set(v);
|
|
372
|
-
if (r.has(
|
|
373
|
-
r.delete(
|
|
373
|
+
if (r.has(key)) {
|
|
374
|
+
r.delete(key);
|
|
374
375
|
} else {
|
|
375
|
-
r.add(
|
|
376
|
+
r.add(key);
|
|
376
377
|
const allChildren = this.getAllChildren(item);
|
|
377
378
|
for (const allChild of allChildren) {
|
|
378
|
-
r.add(allChild);
|
|
379
|
+
r.add(allChild.codeChain.join("."));
|
|
379
380
|
}
|
|
380
381
|
}
|
|
381
382
|
return r;
|
|
@@ -321,23 +321,34 @@ export class SdSharedDataSelect<
|
|
|
321
321
|
return this._searchTextMatchCache().get(item.__valueKey) ?? false;
|
|
322
322
|
}
|
|
323
323
|
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
[];
|
|
324
|
+
private readonly _sortedChildrenMap = computed(() => {
|
|
325
|
+
const parentMap = this.itemByParentKeyMap();
|
|
326
|
+
if (parentMap == null) return undefined;
|
|
328
327
|
|
|
329
328
|
const orderProp = this.displayOrderKeyProp();
|
|
330
|
-
if (orderProp
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
329
|
+
if (orderProp == null) return parentMap;
|
|
330
|
+
|
|
331
|
+
const sorted = new Map<TItem["__valueKey"] | undefined, TItem[]>();
|
|
332
|
+
for (const [key, children] of parentMap) {
|
|
333
|
+
sorted.set(
|
|
334
|
+
key,
|
|
335
|
+
[...children].sort((a, b) => {
|
|
336
|
+
const aVal = (a as any)[orderProp];
|
|
337
|
+
const bVal = (b as any)[orderProp];
|
|
338
|
+
if (aVal < bVal) return -1;
|
|
339
|
+
if (aVal > bVal) return 1;
|
|
340
|
+
return 0;
|
|
341
|
+
}),
|
|
342
|
+
);
|
|
338
343
|
}
|
|
344
|
+
return sorted;
|
|
345
|
+
});
|
|
339
346
|
|
|
340
|
-
|
|
347
|
+
getChildren = (item: SharedDataBase<string | number>): TItem[] => {
|
|
348
|
+
return (
|
|
349
|
+
this._sortedChildrenMap()?.get(item.__valueKey as TItem["__valueKey"]) ??
|
|
350
|
+
[]
|
|
351
|
+
);
|
|
341
352
|
};
|
|
342
353
|
|
|
343
354
|
onUndefinedClick(): void {
|
|
@@ -130,6 +130,12 @@ export class SdStatePreset {
|
|
|
130
130
|
if (name == null) return;
|
|
131
131
|
|
|
132
132
|
const currentPresets = this._presets();
|
|
133
|
+
|
|
134
|
+
if (currentPresets.some((p) => p.name === name)) {
|
|
135
|
+
this._sdToast.warning("이미 존재하는 프리셋 이름입니다.");
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
|
|
133
139
|
const newPreset: SdStatePresetDef = {
|
|
134
140
|
name,
|
|
135
141
|
state: obj.clone(this.state()),
|
|
@@ -11,17 +11,19 @@ import type { OnInit } from "@angular/core";
|
|
|
11
11
|
import { SdBusyContainer } from "../../core/busy/sd-busy-container";
|
|
12
12
|
import type { SdModalContentDef } from "../../core/modal/sd-modal.provider";
|
|
13
13
|
|
|
14
|
-
declare const daum:
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
};
|
|
14
|
+
declare const daum:
|
|
15
|
+
| {
|
|
16
|
+
postcode: {
|
|
17
|
+
load(callback: () => void): void;
|
|
18
|
+
};
|
|
19
|
+
Postcode: new (options: {
|
|
20
|
+
oncomplete: (data: DaumPostcodeData) => void;
|
|
21
|
+
onresize: (size: { height: number }) => void;
|
|
22
|
+
width: string;
|
|
23
|
+
height: string;
|
|
24
|
+
}) => { embed(el: HTMLElement, options: { autoClose: boolean }): void };
|
|
25
|
+
}
|
|
26
|
+
| undefined;
|
|
25
27
|
|
|
26
28
|
interface DaumPostcodeData {
|
|
27
29
|
zonecode: string;
|
|
@@ -39,6 +41,51 @@ export interface Address {
|
|
|
39
41
|
buildingName: string | undefined;
|
|
40
42
|
}
|
|
41
43
|
|
|
44
|
+
function loadDaumPostcodeScript(): Promise<void> {
|
|
45
|
+
const existing = document.getElementById("daum_address");
|
|
46
|
+
if (existing != null) {
|
|
47
|
+
if (typeof daum !== "undefined") {
|
|
48
|
+
return Promise.resolve();
|
|
49
|
+
}
|
|
50
|
+
return new Promise<void>((resolve, reject) => {
|
|
51
|
+
existing.addEventListener(
|
|
52
|
+
"load",
|
|
53
|
+
() => {
|
|
54
|
+
daum!.postcode.load(() => {
|
|
55
|
+
resolve();
|
|
56
|
+
});
|
|
57
|
+
},
|
|
58
|
+
{ once: true },
|
|
59
|
+
);
|
|
60
|
+
existing.addEventListener(
|
|
61
|
+
"error",
|
|
62
|
+
() => {
|
|
63
|
+
existing.remove();
|
|
64
|
+
reject(new Error("주소 검색 스크립트를 불러올 수 없습니다."));
|
|
65
|
+
},
|
|
66
|
+
{ once: true },
|
|
67
|
+
);
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return new Promise<void>((resolve, reject) => {
|
|
72
|
+
const scriptEl = document.createElement("script");
|
|
73
|
+
scriptEl.src = "//t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js";
|
|
74
|
+
scriptEl.setAttribute("id", "daum_address");
|
|
75
|
+
|
|
76
|
+
scriptEl.onload = (): void => {
|
|
77
|
+
daum!.postcode.load(() => {
|
|
78
|
+
resolve();
|
|
79
|
+
});
|
|
80
|
+
};
|
|
81
|
+
scriptEl.onerror = (): void => {
|
|
82
|
+
scriptEl.remove();
|
|
83
|
+
reject(new Error("주소 검색 스크립트를 불러올 수 없습니다."));
|
|
84
|
+
};
|
|
85
|
+
document.head.appendChild(scriptEl);
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
42
89
|
@Component({
|
|
43
90
|
selector: "sd-address-search-modal",
|
|
44
91
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
@@ -47,45 +94,42 @@ export interface Address {
|
|
|
47
94
|
imports: [SdBusyContainer],
|
|
48
95
|
template: `
|
|
49
96
|
<sd-busy-container [busy]="!initialized()">
|
|
50
|
-
|
|
97
|
+
@if (errorMessage() !== null) {
|
|
98
|
+
<div class="_error">{{ errorMessage() }}</div>
|
|
99
|
+
} @else {
|
|
100
|
+
<div #content style="min-height: 100px;"></div>
|
|
101
|
+
}
|
|
51
102
|
</sd-busy-container>
|
|
52
103
|
`,
|
|
53
104
|
})
|
|
54
105
|
export class SdAddressSearchModal implements SdModalContentDef<Address>, OnInit {
|
|
55
|
-
contentElRef = viewChild
|
|
106
|
+
contentElRef = viewChild<"content", ElementRef<HTMLElement>>("content", {
|
|
56
107
|
read: ElementRef,
|
|
57
108
|
});
|
|
58
109
|
|
|
59
110
|
close = output<Address>();
|
|
60
111
|
|
|
61
112
|
initialized = signal(false);
|
|
113
|
+
errorMessage = signal<string | null>(null);
|
|
62
114
|
|
|
63
115
|
ngOnInit() {
|
|
64
116
|
void this._initAsync();
|
|
65
117
|
}
|
|
66
118
|
|
|
67
119
|
private async _initAsync() {
|
|
68
|
-
|
|
69
|
-
await
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
scriptEl.onload = (): void => {
|
|
75
|
-
daum.postcode.load(() => {
|
|
76
|
-
resolve();
|
|
77
|
-
});
|
|
78
|
-
};
|
|
79
|
-
scriptEl.onerror = (): void => {
|
|
80
|
-
reject(new Error("주소 검색 스크립트를 불러올 수 없습니다."));
|
|
81
|
-
};
|
|
82
|
-
document.head.appendChild(scriptEl);
|
|
83
|
-
});
|
|
120
|
+
try {
|
|
121
|
+
await loadDaumPostcodeScript();
|
|
122
|
+
} catch (err) {
|
|
123
|
+
this.errorMessage.set(err instanceof Error ? err.message : String(err));
|
|
124
|
+
this.initialized.set(true);
|
|
125
|
+
return;
|
|
84
126
|
}
|
|
85
127
|
|
|
86
|
-
const
|
|
128
|
+
const contentElRef = this.contentElRef();
|
|
129
|
+
if (contentElRef == null) return;
|
|
130
|
+
const contentEl = contentElRef.nativeElement;
|
|
87
131
|
|
|
88
|
-
new daum
|
|
132
|
+
new daum!.Postcode({
|
|
89
133
|
oncomplete: (data: DaumPostcodeData): void => {
|
|
90
134
|
const addr = data.userSelectedType === "R" ? data.roadAddress : data.jibunAddress;
|
|
91
135
|
|
|
@@ -22,6 +22,7 @@ import Color from "@tiptap/extension-color";
|
|
|
22
22
|
import Highlight from "@tiptap/extension-highlight";
|
|
23
23
|
import TextAlign from "@tiptap/extension-text-align";
|
|
24
24
|
import Image from "@tiptap/extension-image";
|
|
25
|
+
import Underline from "@tiptap/extension-underline";
|
|
25
26
|
import Placeholder from "@tiptap/extension-placeholder";
|
|
26
27
|
import { useTiptapToolbar } from "./useTiptapToolbar";
|
|
27
28
|
|
|
@@ -32,6 +33,7 @@ const DEFAULT_EXTENSIONS: AnyExtension[] = [
|
|
|
32
33
|
Highlight.configure({ multicolor: true }),
|
|
33
34
|
TextAlign.configure({ types: ["heading", "paragraph"] }),
|
|
34
35
|
Image.configure({ inline: false, allowBase64: true }),
|
|
36
|
+
Underline,
|
|
35
37
|
];
|
|
36
38
|
|
|
37
39
|
@Component({
|
|
@@ -32,11 +32,15 @@ export class SdBarcode {
|
|
|
32
32
|
if (text == null || text === "") {
|
|
33
33
|
return "";
|
|
34
34
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
35
|
+
try {
|
|
36
|
+
const svg = bwipjs.toSVG({
|
|
37
|
+
bcid: this.type(),
|
|
38
|
+
text,
|
|
39
|
+
});
|
|
40
|
+
return this._sanitizer.bypassSecurityTrustHtml(svg);
|
|
41
|
+
} catch {
|
|
42
|
+
return "";
|
|
43
|
+
}
|
|
40
44
|
});
|
|
41
45
|
}
|
|
42
46
|
|
package/src/index.ts
CHANGED
|
@@ -159,7 +159,7 @@ export { type SdTextfieldTypes, sdTextfieldTypes } from "./controls/input/sd-tex
|
|
|
159
159
|
export { SdTextarea } from "./controls/input/sd-textarea";
|
|
160
160
|
export { SdNumpad } from "./controls/input/sd-numpad";
|
|
161
161
|
export { SdRange } from "./controls/input/sd-range";
|
|
162
|
-
export { SdDateRangePicker } from "./controls/input/sd-date-range
|
|
162
|
+
export { SdDateRangePicker } from "./controls/input/sd-date-range-picker";
|
|
163
163
|
|
|
164
164
|
// controls/checkbox
|
|
165
165
|
export { SdCheckbox } from "./controls/checkbox/sd-checkbox";
|
|
@@ -252,6 +252,9 @@ export {
|
|
|
252
252
|
type SdDataDetailDataInfo,
|
|
253
253
|
} from "./data/data-detail/sd-data-detail.base";
|
|
254
254
|
|
|
255
|
+
// data/utils
|
|
256
|
+
export { getOrmDataEditToastErrorMessage } from "./data/getOrmDataEditToastErrorMessage";
|
|
257
|
+
|
|
255
258
|
// data/data-select-button
|
|
256
259
|
export { SdDataSelectButton } from "./data/data-select-button/sd-data-select-button";
|
|
257
260
|
export { SdDataSelectButtonBase } from "./data/data-select-button/sd-data-select-button.base";
|
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
type SdViewType,
|
|
23
23
|
} from "../../core/routing/injectViewTypeSignal";
|
|
24
24
|
import { injectParent } from "../../core/injectParent";
|
|
25
|
+
import { SdSystemLogProvider } from "../../core/config/sd-system-log.provider";
|
|
25
26
|
import { NgIcon } from "@ng-icons/core";
|
|
26
27
|
import { tablerAlertTriangle } from "@ng-icons/tabler-icons";
|
|
27
28
|
|
|
@@ -81,6 +82,7 @@ import { tablerAlertTriangle } from "@ng-icons/tabler-icons";
|
|
|
81
82
|
export class SdBaseContainer {
|
|
82
83
|
private readonly _sdActivatedModal = inject(SdActivatedModalProvider, { optional: true });
|
|
83
84
|
private readonly _sdAppStructure = inject(SdAppStructureProvider);
|
|
85
|
+
private readonly _systemLog = inject(SdSystemLogProvider);
|
|
84
86
|
|
|
85
87
|
private readonly _parent = injectParent();
|
|
86
88
|
|
|
@@ -104,7 +106,8 @@ export class SdBaseContainer {
|
|
|
104
106
|
this._sdActivatedModal?.modalComponent()?.title() ??
|
|
105
107
|
this._sdAppStructure.getTitleByFullCode(this._currPageCode?.() ?? this._fullPageCode())
|
|
106
108
|
);
|
|
107
|
-
} catch {
|
|
109
|
+
} catch (err) {
|
|
110
|
+
void this._systemLog.writeAsync("warn", `modalOrPageTitle 계산 중 에러: ${String(err)}`);
|
|
108
111
|
return "";
|
|
109
112
|
}
|
|
110
113
|
});
|
|
File without changes
|