@things-factory/kpi 10.0.4 → 10.0.5
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/client/pages/kpi/kpi-view.ts +2 -0
- package/client/pages/kpi-metric-value/kpi-metric-value-manual-entry-form.ts +2 -0
- package/client/viewparts/kpi-metric-input.ts +2 -0
- package/client/viewparts/kpi-metric-meta-editor.ts +2 -0
- package/dist-client/pages/kpi/kpi-view.js +2 -0
- package/dist-client/pages/kpi/kpi-view.js.map +1 -1
- package/dist-client/pages/kpi-metric-value/kpi-metric-value-manual-entry-form.js +2 -0
- package/dist-client/pages/kpi-metric-value/kpi-metric-value-manual-entry-form.js.map +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/dist-client/viewparts/kpi-metric-input.js +2 -0
- package/dist-client/viewparts/kpi-metric-input.js.map +1 -1
- package/dist-client/viewparts/kpi-metric-meta-editor.js +2 -0
- package/dist-client/viewparts/kpi-metric-meta-editor.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +5 -5
|
@@ -28,6 +28,8 @@ let KpiMetricInput = class KpiMetricInput extends LitElement {
|
|
|
28
28
|
}
|
|
29
29
|
input,
|
|
30
30
|
select {
|
|
31
|
+
background-color: var(--input-field-background, var(--md-sys-color-surface-container-highest));
|
|
32
|
+
color: var(--input-field-color, var(--md-sys-color-on-surface));
|
|
31
33
|
font: inherit;
|
|
32
34
|
padding: 2px 4px;
|
|
33
35
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kpi-metric-input.js","sourceRoot":"","sources":["../../client/viewparts/kpi-metric-input.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,KAAK,CAAA;AACpD,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAE3D,OAAO,EAAE,gBAAgB,EAA4B,MAAM,qBAAqB,CAAA;AAChF,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAA;AAEnE;;;;;;;;GAQG;AAEI,IAAM,cAAc,GAApB,MAAM,cAAe,SAAQ,UAAU;IAAvC;;
|
|
1
|
+
{"version":3,"file":"kpi-metric-input.js","sourceRoot":"","sources":["../../client/viewparts/kpi-metric-input.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,KAAK,CAAA;AACpD,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAE3D,OAAO,EAAE,gBAAgB,EAA4B,MAAM,qBAAqB,CAAA;AAChF,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAA;AAEnE;;;;;;;;GAQG;AAEI,IAAM,cAAc,GAApB,MAAM,cAAe,SAAQ,UAAU;IAAvC;;QAuCuB,WAAM,GAAkB,EAAE,CAAA;QAEtD,2CAA2C;QACd,aAAQ,GAAG,KAAK,CAAA;IAyE/C,CAAC;aAlHQ,WAAM,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoClB,AApCY,CAoCZ;IAOO,KAAK,CAAC,KAAU;QACtB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;QAClB,IAAI,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,qBAAqB,EAAE,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;IAClH,CAAC;IAED,MAAM;QACJ,MAAM,MAAM,GAAG,sBAAsB,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QAC1D,IAAI,MAAM;YAAE,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;QAEtE,MAAM,IAAI,GAAG,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QAC1C,MAAM,EAAE,GAAG,IAAI,CAAC,QAAQ,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAA;QAC3C,MAAM,IAAI,GAAI,IAAI,CAAC,MAAc,EAAE,IAAI,CAAA;QAEvC,oEAAoE;QACpE,OAAO,IAAI,CAAA;QACP,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAA,sBAAsB,IAAI,SAAS,CAAC,CAAC,CAAC,OAAO;KAC1F,CAAA;IACH,CAAC;IAEO,aAAa,CAAC,IAAe,EAAE,EAAW;QAChD,QAAQ,IAAI,CAAC,MAAM,EAAE,CAAC;YACpB,KAAK,QAAQ;gBACX,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,EAAE,CAAC,CAAA;YACrC,KAAK,QAAQ;gBACX,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,EAAE,CAAC,CAAA;YACrC,KAAK,MAAM;gBACT,OAAO,IAAI,CAAA,6BAA6B,IAAI,CAAC,KAAK,IAAI,EAAE,cAAc,EAAE;oBAC5D,CAAC,CAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAE,CAAC,CAAC,MAA2B,CAAC,KAAK,CAAC,KAAK,CAAA;YACjF,KAAK,QAAQ;gBACX,OAAO,IAAI,CAAA,mCAAmC,CAAC,CAAC,IAAI,CAAC,KAAK,cAAc,EAAE;oBAC9D,CAAC,CAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAE,CAAC,CAAC,MAA2B,CAAC,OAAO,CAAC,KAAK,CAAA;YACnF,KAAK,MAAM;gBACT,OAAO,IAAI,CAAA,6BAA6B,IAAI,CAAC,KAAK,IAAI,EAAE,cAAc,EAAE;wBACxD,IAAI,CAAC,WAAW,IAAI,EAAE,WAAW,CAAC,CAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAE,CAAC,CAAC,MAA2B,CAAC,KAAK,CAAC,KAAK,CAAA;YACtH,KAAK,QAAQ,CAAC;YACd;gBACE,OAAO,IAAI,CAAA,+BAA+B,IAAI,CAAC,KAAK,IAAI,EAAE,cAAc,EAAE;gBAClE,IAAI,CAAC,GAAG,IAAI,OAAO,QAAQ,IAAI,CAAC,GAAG,IAAI,OAAO,SAAS,IAAI,CAAC,IAAI,IAAI,OAAO;wBACnE,IAAI,CAAC,WAAW,IAAI,EAAE;mBAC3B,CAAC,CAAQ,EAAE,EAAE;oBACpB,MAAM,GAAG,GAAI,CAAC,CAAC,MAA2B,CAAC,KAAK,CAAA;oBAChD,IAAI,CAAC,KAAK,CAAC,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAA;gBAC7C,CAAC,KAAK,CAAA;QACZ,CAAC;IACH,CAAC;IAEO,aAAa,CAAC,IAAe,EAAE,EAAW;QAChD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,CAAA;QACzB,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,CAAA;QACrC,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE;YACnD,MAAM,CAAC,GAAG,GAAG,GAAG,CAAC,CAAA;YACjB,MAAM,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;YACrC,OAAO,IAAI,CAAA,6BAA6B,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,SAAS,CAAA;QAC1G,CAAC,CAAC,CAAA;QACF,OAAO,IAAI,CAAA,iCAAiC,EAAE,UAAU,GAAG,KAAK,IAAI,GAAG,EAAE,IAAI,KAAK,SAAS,CAAA;IAC7F,CAAC;IAEO,aAAa,CAAC,IAAe,EAAE,EAAW;QAChD,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,EAAE,CAAA;QAClC,OAAO,IAAI,CAAA,qBAAqB,EAAE,YAAY,CAAC,CAAQ,EAAE,EAAE;YACzD,MAAM,GAAG,GAAI,CAAC,CAAC,MAA4B,CAAC,KAAK,CAAA;YACjD,uCAAuC;YACvC,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAA;YACtD,IAAI,CAAC,KAAK,CAAC,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;QACvD,CAAC;mCAC8B,IAAI,CAAC,KAAK,IAAI,IAAI,IAAI,IAAI,CAAC,KAAK,KAAK,EAAE;QAClE,OAAO,CAAC,GAAG,CACX,CAAC,CAAC,EAAE,CAAC,IAAI,CAAA,iBAAiB,CAAC,CAAC,KAAK,cAAc,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,WAAW,CAC5G;cACO,CAAA;IACZ,CAAC;;AA3E2B;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;8CAA2B;AAC1C;IAAX,QAAQ,EAAE;;6CAAW;AAEO;IAA5B,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;;gDAAiB;AA1ClC,cAAc;IAD1B,aAAa,CAAC,kBAAkB,CAAC;GACrB,cAAc,CAmH1B","sourcesContent":["import { html, css, LitElement, nothing } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\n\nimport { resolveInputHint, InputHint, KpiMetricLike } from './metric-input-hint'\nimport { MetricRendererRegistry } from './metric-renderer-registry'\n\n/**\n * metric 정의(meta.input)에 따라 입력 위젯을 **선언적으로 자동 렌더**하는 제네릭 컴포넌트.\n * 이름 추측(isRating 등) 없이 `resolveInputHint` 로 위젯을 결정한다.\n *\n * <kpi-metric-input .metric=${metric} .value=${v}\n * @metric-input-change=${e => (v = e.detail.value)}></kpi-metric-input>\n *\n * 예외 UI 는 MetricRendererRegistry 로 등록(제네릭 우선순위보다 먼저 적용).\n */\n@customElement('kpi-metric-input')\nexport class KpiMetricInput extends LitElement {\n static styles = css`\n :host {\n display: inline-flex;\n align-items: baseline;\n gap: 2px;\n font: 13px/18px var(--theme-font, sans-serif);\n }\n input,\n select {\n background-color: var(--input-field-background, var(--md-sys-color-surface-container-highest));\n color: var(--input-field-color, var(--md-sys-color-on-surface));\n font: inherit;\n padding: 2px 4px;\n }\n input[type='number'] {\n width: 5em;\n text-align: right;\n }\n .stars {\n display: inline-flex;\n cursor: pointer;\n font-size: 18px;\n line-height: 1;\n color: var(--md-sys-color-primary, #2e79be);\n }\n .stars[readonly] {\n cursor: default;\n opacity: 0.85;\n }\n .star {\n width: 1em;\n }\n .unit {\n color: var(--md-sys-color-on-surface-variant, #888);\n font-size: 11px;\n }\n `\n\n @property({ type: Object }) metric: KpiMetricLike = {}\n @property() value: any\n /** 상위에서 강제 비활성화(권한 등). readonly 힌트와 별개. */\n @property({ type: Boolean }) disabled = false\n\n private _emit(value: any) {\n this.value = value\n this.dispatchEvent(new CustomEvent('metric-input-change', { detail: { value }, bubbles: true, composed: true }))\n }\n\n render() {\n const custom = MetricRendererRegistry.resolve(this.metric)\n if (custom) return custom(this.metric, this.value, v => this._emit(v))\n\n const hint = resolveInputHint(this.metric)\n const ro = this.disabled || !!hint.readonly\n const unit = (this.metric as any)?.unit\n\n // 값(우측정렬) 바로 옆에 단위 — 값이 단위에 붙어 자연스럽게. (rating/toggle 등엔 unit 보통 없음)\n return html`\n ${this._renderWidget(hint, ro)}${unit ? html`<span class=\"unit\">${unit}</span>` : nothing}\n `\n }\n\n private _renderWidget(hint: InputHint, ro: boolean) {\n switch (hint.widget) {\n case 'rating':\n return this._renderRating(hint, ro)\n case 'select':\n return this._renderSelect(hint, ro)\n case 'date':\n return html`<input type=\"date\" .value=${this.value ?? ''} ?disabled=${ro}\n @change=${(e: Event) => this._emit((e.target as HTMLInputElement).value)} />`\n case 'toggle':\n return html`<input type=\"checkbox\" .checked=${!!this.value} ?disabled=${ro}\n @change=${(e: Event) => this._emit((e.target as HTMLInputElement).checked)} />`\n case 'text':\n return html`<input type=\"text\" .value=${this.value ?? ''} ?disabled=${ro}\n placeholder=${hint.placeholder ?? ''} @input=${(e: Event) => this._emit((e.target as HTMLInputElement).value)} />`\n case 'number':\n default:\n return html`<input type=\"number\" .value=${this.value ?? ''} ?disabled=${ro}\n min=${hint.min ?? nothing} max=${hint.max ?? nothing} step=${hint.step ?? nothing}\n placeholder=${hint.placeholder ?? ''}\n @input=${(e: Event) => {\n const raw = (e.target as HTMLInputElement).value\n this._emit(raw === '' ? null : Number(raw))\n }} />`\n }\n }\n\n private _renderRating(hint: InputHint, ro: boolean) {\n const max = hint.max ?? 5\n const score = Number(this.value ?? 0)\n const stars = Array.from({ length: max }, (_, idx) => {\n const i = idx + 1\n const filled = i <= Math.round(score)\n return html`<span class=\"star\" @click=${() => (ro ? null : this._emit(i))}>${filled ? '★' : '☆'}</span>`\n })\n return html`<span class=\"stars\" ?readonly=${ro} title=${`${score}/${max}`}>${stars}</span>`\n }\n\n private _renderSelect(hint: InputHint, ro: boolean) {\n const options = hint.options ?? []\n return html`<select ?disabled=${ro} @change=${(e: Event) => {\n const raw = (e.target as HTMLSelectElement).value\n // 옵션의 원래 타입(숫자 등)을 보존해 방출 — 문자열 강제 방지.\n const opt = options.find(o => String(o.value) === raw)\n this._emit(raw === '' ? null : opt ? opt.value : raw)\n }}>\n <option value=\"\" ?selected=${this.value == null || this.value === ''}>-</option>\n ${options.map(\n o => html`<option value=${o.value} ?selected=${String(this.value) === String(o.value)}>${o.label}</option>`\n )}\n </select>`\n }\n}\n"]}
|
|
@@ -71,6 +71,8 @@ let KpiMetricMetaEditor = class KpiMetricMetaEditor extends LitElement {
|
|
|
71
71
|
input[type='number'],
|
|
72
72
|
select,
|
|
73
73
|
textarea {
|
|
74
|
+
background-color: var(--input-field-background, var(--md-sys-color-surface-container-highest));
|
|
75
|
+
color: var(--input-field-color, var(--md-sys-color-on-surface));
|
|
74
76
|
width: 100%;
|
|
75
77
|
box-sizing: border-box;
|
|
76
78
|
padding: 6px 8px;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kpi-metric-meta-editor.js","sourceRoot":"","sources":["../../client/viewparts/kpi-metric-meta-editor.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\n\nimport { css, html, LitElement } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { CommonHeaderStyles } from '@operato/styles'\n\n/**\n * KpiMetric.meta.input(입력 위젯 힌트) 구조화 에디터.\n *\n * metric 관리 화면(kpi-metric-list-page)에서 팝업으로 열려 meta.input 을 편집한다.\n * raw JSON 을 직접 만지지 않고 위젯/필드를 폼으로 구성 → 내부적으로 meta 객체 생성.\n * meta 의 다른 키(kind/source…)는 보존하고 input 만 교체/삭제한다.\n *\n * - `metric-meta-save` detail:{ meta } — 저장 (widget 미선택 시 input 제거된 meta)\n * - `metric-meta-cancel` — 취소\n */\n@customElement('kpi-metric-meta-editor')\nexport class KpiMetricMetaEditor extends LitElement {\n static styles = [\n CommonHeaderStyles,\n css`\n :host {\n display: flex;\n flex-direction: column;\n height: 100%;\n box-sizing: border-box;\n width: 100%;\n min-width: 520px;\n font-size: 14px;\n color: #212529;\n }\n /* 스크롤되는 내용부 — 버튼은 아래에 고정 (kpi-metric-value-manual-entry-form 패턴) */\n .content {\n flex: 1;\n overflow-y: auto;\n padding: 20px 24px 8px 24px;\n }\n h3 {\n margin: 0 0 4px 0;\n font-size: 15px;\n }\n .sub {\n color: #6b7684;\n margin-bottom: 14px;\n }\n .field {\n display: grid;\n grid-template-columns: 96px 1fr;\n align-items: center;\n gap: 8px 10px;\n margin-bottom: 10px;\n }\n label {\n color: #35618e;\n font-weight: 500;\n }\n input[type='text'],\n input[type='number'],\n select,\n textarea {\n width: 100%;\n box-sizing: border-box;\n padding: 6px 8px;\n border: 1px solid #cdd5df;\n border-radius: 5px;\n font-size: 13px;\n }\n textarea {\n min-height: 72px;\n resize: vertical;\n font-family: monospace;\n }\n .checks {\n display: flex;\n gap: 16px;\n flex-wrap: wrap;\n margin: 4px 0 12px 0;\n }\n .checks label {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n color: #212529;\n font-weight: 400;\n }\n .hint {\n color: #8b95a1;\n font-size: 11px;\n grid-column: 2;\n margin-top: -4px;\n }\n `\n ]\n\n /** { name, meta, collectType } */\n @property({ type: Object }) metric: any = {}\n\n @state() widget = ''\n @state() min = ''\n @state() max = ''\n @state() step = ''\n @state() decimals = ''\n @state() placeholder = ''\n @state() optionsText = ''\n @state() readonly = false\n @state() required = false\n @state() hasPlan = false\n\n connectedCallback() {\n super.connectedCallback()\n const input = this.metric?.meta?.input || {}\n this.widget = input.widget || ''\n this.min = input.min !== undefined ? String(input.min) : ''\n this.max = input.max !== undefined ? String(input.max) : ''\n this.step = input.step !== undefined ? String(input.step) : ''\n this.decimals = input.decimals !== undefined ? String(input.decimals) : ''\n this.placeholder = input.placeholder || ''\n this.optionsText = (input.options || []).map((o: any) => `${o.value}|${o.label ?? o.value}`).join('\\n')\n this.readonly = !!input.readonly\n this.required = !!input.required\n this.hasPlan = !!input.hasPlan\n }\n\n render() {\n const w = this.widget\n return html`\n <div class=\"content\">\n <h3>입력 힌트 · ${this.metric?.name || ''}</h3>\n <div class=\"sub\">값 입력 화면(월별/완료평가 등)이 이 힌트로 위젯을 그립니다. 위젯을 비우면 힌트가 제거되어 숫자 입력으로 폴백합니다.</div>\n\n <div class=\"field\">\n <label>위젯</label>\n <select .value=${w} @change=${(e: any) => (this.widget = e.target.value)}>\n <option value=\"\">(자동/폴백 — 숫자)</option>\n <option value=\"number\" ?selected=${w === 'number'}>number — 숫자</option>\n <option value=\"rating\" ?selected=${w === 'rating'}>rating — 별점</option>\n <option value=\"select\" ?selected=${w === 'select'}>select — 선택목록</option>\n <option value=\"toggle\" ?selected=${w === 'toggle'}>toggle — 스위치</option>\n <option value=\"text\" ?selected=${w === 'text'}>text — 텍스트</option>\n <option value=\"date\" ?selected=${w === 'date'}>date — 날짜</option>\n </select>\n </div>\n\n ${w === 'number' || w === 'rating'\n ? html`\n ${w === 'number'\n ? html`<div class=\"field\">\n <label>최소</label>\n <input type=\"number\" .value=${this.min} @input=${(e: any) => (this.min = e.target.value)} />\n </div>`\n : ''}\n <div class=\"field\">\n <label>최대</label>\n <input type=\"number\" .value=${this.max} @input=${(e: any) => (this.max = e.target.value)} />\n ${w === 'rating' ? html`<span class=\"hint\">별 개수 (기본 5)</span>` : ''}\n </div>\n <div class=\"field\">\n <label>스텝</label>\n <input type=\"number\" .value=${this.step} @input=${(e: any) => (this.step = e.target.value)} />\n ${w === 'rating' ? html`<span class=\"hint\">1=정수, 0.5=반별 (기본 1)</span>` : ''}\n </div>\n ${w === 'number'\n ? html`<div class=\"field\">\n <label>소수자리</label>\n <input type=\"number\" .value=${this.decimals} @input=${(e: any) => (this.decimals = e.target.value)} />\n </div>`\n : ''}\n `\n : ''}\n ${w === 'select'\n ? html`\n <div class=\"field\">\n <label>옵션</label>\n <textarea\n .value=${this.optionsText}\n placeholder=\"한 줄에 하나: 값|표시라벨 예) 1|양호 2|보통\"\n @input=${(e: any) => (this.optionsText = e.target.value)}\n ></textarea>\n <span class=\"hint\">한 줄당 <code>값|라벨</code> (라벨 생략 시 값 사용)</span>\n </div>\n `\n : ''}\n ${w === 'text'\n ? html`<div class=\"field\">\n <label>placeholder</label>\n <input type=\"text\" .value=${this.placeholder} @input=${(e: any) => (this.placeholder = e.target.value)} />\n </div>`\n : ''}\n\n ${w\n ? html`<div class=\"checks\">\n <label><input type=\"checkbox\" .checked=${this.readonly} @change=${(e: any) => (this.readonly = e.target.checked)} /> 읽기전용</label>\n <label><input type=\"checkbox\" .checked=${this.required} @change=${(e: any) => (this.required = e.target.checked)} /> 필수</label>\n <label><input type=\"checkbox\" .checked=${this.hasPlan} @change=${(e: any) => (this.hasPlan = e.target.checked)} /> 계획/실제 2열</label>\n </div>`\n : ''}\n </div>\n\n <div class=\"footer\">\n ${this.metric?.meta?.input\n ? html`<button danger @click=${this._clear}><md-icon>delete</md-icon>힌트 삭제</button>`\n : ''}\n <div filler></div>\n <button @click=${this._cancel}><md-icon>cancel</md-icon>취소</button>\n <button done @click=${this._save}><md-icon>done</md-icon>저장</button>\n </div>\n `\n }\n\n private _num(v: string): number | undefined {\n if (v === '' || v === null || v === undefined) return undefined\n const n = Number(v)\n return Number.isNaN(n) ? undefined : n\n }\n\n private _buildInput(): any {\n if (!this.widget) return undefined\n const input: any = { widget: this.widget }\n\n if (this.widget === 'number' || this.widget === 'rating') {\n const min = this._num(this.min)\n const max = this._num(this.max)\n const step = this._num(this.step)\n const decimals = this._num(this.decimals)\n if (this.widget === 'number' && min !== undefined) input.min = min\n if (max !== undefined) input.max = max\n if (step !== undefined) input.step = step\n if (this.widget === 'number' && decimals !== undefined) input.decimals = decimals\n }\n\n if (this.widget === 'select') {\n const options = this.optionsText\n .split('\\n')\n .map(line => line.trim())\n .filter(Boolean)\n .map(line => {\n const [value, label] = line.split('|').map(s => s.trim())\n return { value, label: label || value }\n })\n if (options.length) input.options = options\n }\n\n if (this.widget === 'text' && this.placeholder) input.placeholder = this.placeholder\n\n if (this.readonly) input.readonly = true\n if (this.required) input.required = true\n if (this.hasPlan) input.hasPlan = true\n\n return input\n }\n\n /** 기존 meta 는 보존하고 input 만 교체(또는 삭제). */\n private _buildMeta(): any {\n const rest = { ...(this.metric?.meta || {}) }\n delete rest.input\n const input = this._buildInput()\n const meta = input ? { ...rest, input } : rest\n return Object.keys(meta).length ? meta : null\n }\n\n private _save() {\n this.dispatchEvent(\n new CustomEvent('metric-meta-save', { detail: { meta: this._buildMeta() }, bubbles: true, composed: true })\n )\n }\n\n private _clear() {\n this.widget = ''\n this.dispatchEvent(\n new CustomEvent('metric-meta-save', { detail: { meta: this._buildMeta() }, bubbles: true, composed: true })\n )\n }\n\n private _cancel() {\n this.dispatchEvent(new CustomEvent('metric-meta-cancel', { bubbles: true, composed: true }))\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"kpi-metric-meta-editor.js","sourceRoot":"","sources":["../../client/viewparts/kpi-metric-meta-editor.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\n\nimport { css, html, LitElement } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport { CommonHeaderStyles } from '@operato/styles'\n\n/**\n * KpiMetric.meta.input(입력 위젯 힌트) 구조화 에디터.\n *\n * metric 관리 화면(kpi-metric-list-page)에서 팝업으로 열려 meta.input 을 편집한다.\n * raw JSON 을 직접 만지지 않고 위젯/필드를 폼으로 구성 → 내부적으로 meta 객체 생성.\n * meta 의 다른 키(kind/source…)는 보존하고 input 만 교체/삭제한다.\n *\n * - `metric-meta-save` detail:{ meta } — 저장 (widget 미선택 시 input 제거된 meta)\n * - `metric-meta-cancel` — 취소\n */\n@customElement('kpi-metric-meta-editor')\nexport class KpiMetricMetaEditor extends LitElement {\n static styles = [\n CommonHeaderStyles,\n css`\n :host {\n display: flex;\n flex-direction: column;\n height: 100%;\n box-sizing: border-box;\n width: 100%;\n min-width: 520px;\n font-size: 14px;\n color: #212529;\n }\n /* 스크롤되는 내용부 — 버튼은 아래에 고정 (kpi-metric-value-manual-entry-form 패턴) */\n .content {\n flex: 1;\n overflow-y: auto;\n padding: 20px 24px 8px 24px;\n }\n h3 {\n margin: 0 0 4px 0;\n font-size: 15px;\n }\n .sub {\n color: #6b7684;\n margin-bottom: 14px;\n }\n .field {\n display: grid;\n grid-template-columns: 96px 1fr;\n align-items: center;\n gap: 8px 10px;\n margin-bottom: 10px;\n }\n label {\n color: #35618e;\n font-weight: 500;\n }\n input[type='text'],\n input[type='number'],\n select,\n textarea {\n background-color: var(--input-field-background, var(--md-sys-color-surface-container-highest));\n color: var(--input-field-color, var(--md-sys-color-on-surface));\n width: 100%;\n box-sizing: border-box;\n padding: 6px 8px;\n border: 1px solid #cdd5df;\n border-radius: 5px;\n font-size: 13px;\n }\n textarea {\n min-height: 72px;\n resize: vertical;\n font-family: monospace;\n }\n .checks {\n display: flex;\n gap: 16px;\n flex-wrap: wrap;\n margin: 4px 0 12px 0;\n }\n .checks label {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n color: #212529;\n font-weight: 400;\n }\n .hint {\n color: #8b95a1;\n font-size: 11px;\n grid-column: 2;\n margin-top: -4px;\n }\n `\n ]\n\n /** { name, meta, collectType } */\n @property({ type: Object }) metric: any = {}\n\n @state() widget = ''\n @state() min = ''\n @state() max = ''\n @state() step = ''\n @state() decimals = ''\n @state() placeholder = ''\n @state() optionsText = ''\n @state() readonly = false\n @state() required = false\n @state() hasPlan = false\n\n connectedCallback() {\n super.connectedCallback()\n const input = this.metric?.meta?.input || {}\n this.widget = input.widget || ''\n this.min = input.min !== undefined ? String(input.min) : ''\n this.max = input.max !== undefined ? String(input.max) : ''\n this.step = input.step !== undefined ? String(input.step) : ''\n this.decimals = input.decimals !== undefined ? String(input.decimals) : ''\n this.placeholder = input.placeholder || ''\n this.optionsText = (input.options || []).map((o: any) => `${o.value}|${o.label ?? o.value}`).join('\\n')\n this.readonly = !!input.readonly\n this.required = !!input.required\n this.hasPlan = !!input.hasPlan\n }\n\n render() {\n const w = this.widget\n return html`\n <div class=\"content\">\n <h3>입력 힌트 · ${this.metric?.name || ''}</h3>\n <div class=\"sub\">값 입력 화면(월별/완료평가 등)이 이 힌트로 위젯을 그립니다. 위젯을 비우면 힌트가 제거되어 숫자 입력으로 폴백합니다.</div>\n\n <div class=\"field\">\n <label>위젯</label>\n <select .value=${w} @change=${(e: any) => (this.widget = e.target.value)}>\n <option value=\"\">(자동/폴백 — 숫자)</option>\n <option value=\"number\" ?selected=${w === 'number'}>number — 숫자</option>\n <option value=\"rating\" ?selected=${w === 'rating'}>rating — 별점</option>\n <option value=\"select\" ?selected=${w === 'select'}>select — 선택목록</option>\n <option value=\"toggle\" ?selected=${w === 'toggle'}>toggle — 스위치</option>\n <option value=\"text\" ?selected=${w === 'text'}>text — 텍스트</option>\n <option value=\"date\" ?selected=${w === 'date'}>date — 날짜</option>\n </select>\n </div>\n\n ${w === 'number' || w === 'rating'\n ? html`\n ${w === 'number'\n ? html`<div class=\"field\">\n <label>최소</label>\n <input type=\"number\" .value=${this.min} @input=${(e: any) => (this.min = e.target.value)} />\n </div>`\n : ''}\n <div class=\"field\">\n <label>최대</label>\n <input type=\"number\" .value=${this.max} @input=${(e: any) => (this.max = e.target.value)} />\n ${w === 'rating' ? html`<span class=\"hint\">별 개수 (기본 5)</span>` : ''}\n </div>\n <div class=\"field\">\n <label>스텝</label>\n <input type=\"number\" .value=${this.step} @input=${(e: any) => (this.step = e.target.value)} />\n ${w === 'rating' ? html`<span class=\"hint\">1=정수, 0.5=반별 (기본 1)</span>` : ''}\n </div>\n ${w === 'number'\n ? html`<div class=\"field\">\n <label>소수자리</label>\n <input type=\"number\" .value=${this.decimals} @input=${(e: any) => (this.decimals = e.target.value)} />\n </div>`\n : ''}\n `\n : ''}\n ${w === 'select'\n ? html`\n <div class=\"field\">\n <label>옵션</label>\n <textarea\n .value=${this.optionsText}\n placeholder=\"한 줄에 하나: 값|표시라벨 예) 1|양호 2|보통\"\n @input=${(e: any) => (this.optionsText = e.target.value)}\n ></textarea>\n <span class=\"hint\">한 줄당 <code>값|라벨</code> (라벨 생략 시 값 사용)</span>\n </div>\n `\n : ''}\n ${w === 'text'\n ? html`<div class=\"field\">\n <label>placeholder</label>\n <input type=\"text\" .value=${this.placeholder} @input=${(e: any) => (this.placeholder = e.target.value)} />\n </div>`\n : ''}\n\n ${w\n ? html`<div class=\"checks\">\n <label><input type=\"checkbox\" .checked=${this.readonly} @change=${(e: any) => (this.readonly = e.target.checked)} /> 읽기전용</label>\n <label><input type=\"checkbox\" .checked=${this.required} @change=${(e: any) => (this.required = e.target.checked)} /> 필수</label>\n <label><input type=\"checkbox\" .checked=${this.hasPlan} @change=${(e: any) => (this.hasPlan = e.target.checked)} /> 계획/실제 2열</label>\n </div>`\n : ''}\n </div>\n\n <div class=\"footer\">\n ${this.metric?.meta?.input\n ? html`<button danger @click=${this._clear}><md-icon>delete</md-icon>힌트 삭제</button>`\n : ''}\n <div filler></div>\n <button @click=${this._cancel}><md-icon>cancel</md-icon>취소</button>\n <button done @click=${this._save}><md-icon>done</md-icon>저장</button>\n </div>\n `\n }\n\n private _num(v: string): number | undefined {\n if (v === '' || v === null || v === undefined) return undefined\n const n = Number(v)\n return Number.isNaN(n) ? undefined : n\n }\n\n private _buildInput(): any {\n if (!this.widget) return undefined\n const input: any = { widget: this.widget }\n\n if (this.widget === 'number' || this.widget === 'rating') {\n const min = this._num(this.min)\n const max = this._num(this.max)\n const step = this._num(this.step)\n const decimals = this._num(this.decimals)\n if (this.widget === 'number' && min !== undefined) input.min = min\n if (max !== undefined) input.max = max\n if (step !== undefined) input.step = step\n if (this.widget === 'number' && decimals !== undefined) input.decimals = decimals\n }\n\n if (this.widget === 'select') {\n const options = this.optionsText\n .split('\\n')\n .map(line => line.trim())\n .filter(Boolean)\n .map(line => {\n const [value, label] = line.split('|').map(s => s.trim())\n return { value, label: label || value }\n })\n if (options.length) input.options = options\n }\n\n if (this.widget === 'text' && this.placeholder) input.placeholder = this.placeholder\n\n if (this.readonly) input.readonly = true\n if (this.required) input.required = true\n if (this.hasPlan) input.hasPlan = true\n\n return input\n }\n\n /** 기존 meta 는 보존하고 input 만 교체(또는 삭제). */\n private _buildMeta(): any {\n const rest = { ...(this.metric?.meta || {}) }\n delete rest.input\n const input = this._buildInput()\n const meta = input ? { ...rest, input } : rest\n return Object.keys(meta).length ? meta : null\n }\n\n private _save() {\n this.dispatchEvent(\n new CustomEvent('metric-meta-save', { detail: { meta: this._buildMeta() }, bubbles: true, composed: true })\n )\n }\n\n private _clear() {\n this.widget = ''\n this.dispatchEvent(\n new CustomEvent('metric-meta-save', { detail: { meta: this._buildMeta() }, bubbles: true, composed: true })\n )\n }\n\n private _cancel() {\n this.dispatchEvent(new CustomEvent('metric-meta-cancel', { bubbles: true, composed: true }))\n }\n}\n"]}
|