@iyulab/enterprise 0.7.0 → 0.8.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.
- package/dist/helpers/index.d.ts +1 -0
- package/dist/helpers/messages.d.ts +25 -0
- package/dist/index.js +52 -15
- package/dist/styles/preset.css +15 -7
- package/package.json +2 -2
package/dist/helpers/index.d.ts
CHANGED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@iyulab/enterprise` 의 화면 문자열 — **영어 기본 + 로케일 레지스트리**.
|
|
3
|
+
*
|
|
4
|
+
* ## 왜 이 파일이 생겼나
|
|
5
|
+
*
|
|
6
|
+
* 헬퍼들이 라벨을 **한국어 리터럴로** 들고 있었다(실측 14건). 이 리포는 이미 로케일 표준을
|
|
7
|
+
* 채택했지만(영어 기본 + 레지스트리) **강제하는 장치가 없어서** 채택 이후에 들어온 코드가
|
|
8
|
+
* 한국어 기본값을 갖고 있었다.
|
|
9
|
+
*
|
|
10
|
+
* ⚠**「의견 있음」이 정당화하는 것은 스타일 값의 의견이지 언어가 아니다**(2026-08-04 결정).
|
|
11
|
+
*
|
|
12
|
+
* ## 왜 자체 레지스트리를 만들지 않았나
|
|
13
|
+
*
|
|
14
|
+
* `@iyulab/components` 의 `Locale.namespace()`(1.23.0~)를 쓴다. 자체 구현은 이 조직의
|
|
15
|
+
* **네 번째 레지스트리**가 됐을 것이고, 그러면 소비자가 앱 하나에서 로케일을 **두 번**
|
|
16
|
+
* 전환해야 한다. `Locale.set()` 한 번으로 검증 메시지·이 라벨이 함께 따라온다.
|
|
17
|
+
*
|
|
18
|
+
* ## 동작 변화
|
|
19
|
+
*
|
|
20
|
+
* ⚠기본 로케일은 브라우저 언어에서 감지된다 — **한국어 브라우저는 종전과 같은 문구**를 본다
|
|
21
|
+
* (`ko-KR` → `ko`). 그 밖의 환경은 한국어 대신 **영어**를 본다. 그것이 이 이주의 목적이다.
|
|
22
|
+
*/
|
|
23
|
+
export type EnterpriseMessageKey = 'progressNotStarted' | 'progressEarly' | 'progressInProgress' | 'progressPastMid' | 'progressAlmost' | 'progressDone' | 'urgencyOverdue' | 'urgencyCritical' | 'urgencyUrgent' | 'urgencySoon' | 'urgencyNormal' | 'daysOverdue' | 'daysToday' | 'daysRemaining';
|
|
24
|
+
/** 이 패키지의 문자열 묶음. 소비자는 `messages.register(locale, table)` 로 덮거나 언어를 더한다. */
|
|
25
|
+
export declare const messages: any;
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Locale } from "@iyulab/components";
|
|
2
3
|
import { HttpClient } from "@iyulab/http-client";
|
|
3
4
|
import buildQuery from "odata-query";
|
|
4
5
|
//#region src/FormSection.tsx
|
|
@@ -79,6 +80,42 @@ function FormRow({ children, full, columns = 2, className, style }) {
|
|
|
79
80
|
});
|
|
80
81
|
}
|
|
81
82
|
//#endregion
|
|
83
|
+
//#region src/helpers/messages.ts
|
|
84
|
+
/** 이 패키지의 문자열 묶음. 소비자는 `messages.register(locale, table)` 로 덮거나 언어를 더한다. */
|
|
85
|
+
var messages = Locale.namespace("@iyulab/enterprise");
|
|
86
|
+
messages.register("en", {
|
|
87
|
+
progressNotStarted: "Not started",
|
|
88
|
+
progressEarly: "Early stage",
|
|
89
|
+
progressInProgress: "In progress",
|
|
90
|
+
progressPastMid: "Past halfway",
|
|
91
|
+
progressAlmost: "Almost done",
|
|
92
|
+
progressDone: "Done",
|
|
93
|
+
urgencyOverdue: "Overdue",
|
|
94
|
+
urgencyCritical: "Critical",
|
|
95
|
+
urgencyUrgent: "Urgent",
|
|
96
|
+
urgencySoon: "Due soon",
|
|
97
|
+
urgencyNormal: "On track",
|
|
98
|
+
daysOverdue: "{days} days overdue",
|
|
99
|
+
daysToday: "Today",
|
|
100
|
+
daysRemaining: "{days} days left"
|
|
101
|
+
});
|
|
102
|
+
messages.register("ko", {
|
|
103
|
+
progressNotStarted: "시작 전",
|
|
104
|
+
progressEarly: "초기 단계",
|
|
105
|
+
progressInProgress: "진행 중",
|
|
106
|
+
progressPastMid: "중반 이상",
|
|
107
|
+
progressAlmost: "거의 완료",
|
|
108
|
+
progressDone: "완료",
|
|
109
|
+
urgencyOverdue: "지연",
|
|
110
|
+
urgencyCritical: "매우 급함",
|
|
111
|
+
urgencyUrgent: "급함",
|
|
112
|
+
urgencySoon: "곧 도래",
|
|
113
|
+
urgencyNormal: "여유",
|
|
114
|
+
daysOverdue: "{days}일 지연",
|
|
115
|
+
daysToday: "오늘",
|
|
116
|
+
daysRemaining: "{days}일"
|
|
117
|
+
});
|
|
118
|
+
//#endregion
|
|
82
119
|
//#region src/helpers/CurrencyHelper.ts
|
|
83
120
|
/**
|
|
84
121
|
* Currency formatting utility class
|
|
@@ -295,12 +332,12 @@ var ProgressHelper = class {
|
|
|
295
332
|
*/
|
|
296
333
|
static getProgressLabel(progress) {
|
|
297
334
|
const validated = this.validateProgress(progress);
|
|
298
|
-
if (validated === 0) return "
|
|
299
|
-
if (validated < 25) return "
|
|
300
|
-
if (validated < 50) return "
|
|
301
|
-
if (validated < 75) return "
|
|
302
|
-
if (validated < 100) return "
|
|
303
|
-
return "
|
|
335
|
+
if (validated === 0) return messages.text("progressNotStarted");
|
|
336
|
+
if (validated < 25) return messages.text("progressEarly");
|
|
337
|
+
if (validated < 50) return messages.text("progressInProgress");
|
|
338
|
+
if (validated < 75) return messages.text("progressPastMid");
|
|
339
|
+
if (validated < 100) return messages.text("progressAlmost");
|
|
340
|
+
return messages.text("progressDone");
|
|
304
341
|
}
|
|
305
342
|
/**
|
|
306
343
|
* Calculate progress from current and total values
|
|
@@ -373,11 +410,11 @@ var UrgencyHelper = class {
|
|
|
373
410
|
*/
|
|
374
411
|
static getUrgencyText(daysRemaining, config, labels) {
|
|
375
412
|
const defaultLabels = {
|
|
376
|
-
overdue: "
|
|
377
|
-
critical: "
|
|
378
|
-
urgent: "
|
|
379
|
-
soon: "
|
|
380
|
-
normal: "
|
|
413
|
+
overdue: messages.text("urgencyOverdue"),
|
|
414
|
+
critical: messages.text("urgencyCritical"),
|
|
415
|
+
urgent: messages.text("urgencyUrgent"),
|
|
416
|
+
soon: messages.text("urgencySoon"),
|
|
417
|
+
normal: messages.text("urgencyNormal")
|
|
381
418
|
};
|
|
382
419
|
const level = this.getUrgencyLevel(daysRemaining, config);
|
|
383
420
|
return labels?.[level] || defaultLabels[level];
|
|
@@ -421,9 +458,9 @@ var UrgencyHelper = class {
|
|
|
421
458
|
*/
|
|
422
459
|
static formatDaysRemaining(daysRemaining) {
|
|
423
460
|
if (daysRemaining === null || daysRemaining === void 0) return "-";
|
|
424
|
-
if (daysRemaining < 0) return
|
|
425
|
-
if (daysRemaining === 0) return "
|
|
426
|
-
return
|
|
461
|
+
if (daysRemaining < 0) return messages.text("daysOverdue", { days: Math.abs(daysRemaining) });
|
|
462
|
+
if (daysRemaining === 0) return messages.text("daysToday");
|
|
463
|
+
return messages.text("daysRemaining", { days: daysRemaining });
|
|
427
464
|
}
|
|
428
465
|
/**
|
|
429
466
|
* Check if deadline is overdue
|
|
@@ -945,4 +982,4 @@ function createAuthClient(config) {
|
|
|
945
982
|
};
|
|
946
983
|
}
|
|
947
984
|
//#endregion
|
|
948
|
-
export { ApiConfig, ApiError, CurrencyHelper, DateHelper, FormRow, FormSection, ProgressHelper, UrgencyHelper, clearPermissions, createAuthClient, createODataService, createPermissionStore, defaultPermissionStore, getPermissions, hasAllPermissions, hasAnyPermission, hasPermission, setPermissions };
|
|
985
|
+
export { ApiConfig, ApiError, CurrencyHelper, DateHelper, FormRow, FormSection, ProgressHelper, UrgencyHelper, clearPermissions, createAuthClient, createODataService, createPermissionStore, defaultPermissionStore, getPermissions, hasAllPermissions, hasAnyPermission, hasPermission, messages, setPermissions };
|
package/dist/styles/preset.css
CHANGED
|
@@ -23,11 +23,19 @@
|
|
|
23
23
|
* ⑵ **`--u-*` 값만 덮는다.** 새 클래스·새 선택자를 만들지 않는다. 만들기 시작하면
|
|
24
24
|
* 소비자가 그 선택자와 특이도 싸움을 하게 되고, 그때부터 이 파일은 프리셋이 아니라
|
|
25
25
|
* 또 하나의 프레임워크가 된다. (`tests/preset-contract.test.ts` 가 지킨다.)
|
|
26
|
-
* ⑶
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
26
|
+
* ⑶ 🔴**층은 «로드 순서»로 선다.** 세 층이 전부 `:root`(0,1,0)이므로 나중에 로드된
|
|
27
|
+
* 것이 이긴다 — 소비자가 이미 통제하는 축이다.
|
|
28
|
+
*
|
|
29
|
+
* 기본값(components/styles/light.css) → 하우스(이 파일) → 소비자 브랜드
|
|
30
|
+
*
|
|
31
|
+
* ⚠**종전 판(0.7.0)은 이 자리를 `:where()` 로 감싸 특이도 0 으로 만들었고,
|
|
32
|
+
* 그래서 «한 줄도 적용되지 않았다».** 의도는 옳았다 — *"프리셋이 소비자 브랜드를
|
|
33
|
+
* 덮으면 안 된다"*. 그러나 특이도 0 은 **이겨야 할 상대(기본값)와 지지 말아야 할
|
|
34
|
+
* 상대(브랜드)를 구분하지 못한다.** 기본 시트가 같은 토큰을 `:root` 로 선언하므로
|
|
35
|
+
* 구조적으로 졌다. 실측: 이 파일의 40선언 중 **기본 시트에 없는 것이 0개** —
|
|
36
|
+
* `:where()` 가 이길 수 있는 자리가 하나도 없었다.
|
|
37
|
+
* ★그리고 **그 실패는 조용했다.** 오류도 경고도 없고, 소비자에게는
|
|
38
|
+
* *"프리셋 값이 우리 값과 우연히 같았나 보다"* 로 보인다.
|
|
31
39
|
*
|
|
32
40
|
* ──────────────────────────────────────────────────────────────────────────
|
|
33
41
|
* 이 프리셋이 정하는 것 / 정하지 않는 것
|
|
@@ -39,7 +47,7 @@
|
|
|
39
47
|
* 안 정한다 **브랜드 색** — 그것은 소비앱의 몫이다. 프리셋은 브랜드를 갖지 않는다.
|
|
40
48
|
* ========================================================================== */
|
|
41
49
|
|
|
42
|
-
:
|
|
50
|
+
:root {
|
|
43
51
|
/* ==========================================================================
|
|
44
52
|
타이포 — LOB 밀도
|
|
45
53
|
★업무 화면은 한 화면에 담기는 정보량이 곧 생산성이다. 중립 기본값보다 한 단씩
|
|
@@ -120,7 +128,7 @@
|
|
|
120
128
|
* ★어두운 배경 위의 검은 그림자는 보이지 않는다. 알파를 라이트보다 크게 잡되,
|
|
121
129
|
* 깊이의 대부분은 표면 밝기 차(`--u-bg-color-raised` 등, `components` 소유)가 낸다.
|
|
122
130
|
*/
|
|
123
|
-
:
|
|
131
|
+
:root[theme='dark'] {
|
|
124
132
|
--u-shadow-color-weaker: rgba(0, 0, 0, 0.20);
|
|
125
133
|
--u-shadow-color-weak: rgba(0, 0, 0, 0.28);
|
|
126
134
|
--u-shadow-color-normal: rgba(0, 0, 0, 0.36);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@iyulab/enterprise",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "Enterprise utilities and components for iyulab framework",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"enterprise",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
},
|
|
46
46
|
"peerDependencies": {
|
|
47
47
|
"react": ">=18",
|
|
48
|
-
"@iyulab/components": ">=1.
|
|
48
|
+
"@iyulab/components": ">=1.23.0"
|
|
49
49
|
},
|
|
50
50
|
"peerDependenciesMeta": {
|
|
51
51
|
"@iyulab/components": {
|