@things-factory/dashboard 9.0.6 → 9.0.12

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.
@@ -0,0 +1,6 @@
1
+ import { LitElement } from 'lit';
2
+ export declare class KpiAlertPanel extends LitElement {
3
+ static styles: import("lit").CSSResult;
4
+ private alerts;
5
+ render(): import("lit-html").TemplateResult<1>;
6
+ }
@@ -0,0 +1,73 @@
1
+ import { __decorate, __metadata } from "tslib";
2
+ import { html, css, LitElement } from 'lit';
3
+ import { customElement, state } from 'lit/decorators.js';
4
+ let KpiAlertPanel = class KpiAlertPanel extends LitElement {
5
+ constructor() {
6
+ super(...arguments);
7
+ this.alerts = [
8
+ { icon: '⚠️', message: '목표 미달성 KPI 발생', date: '2024-06-01' },
9
+ { icon: '🔔', message: '이상 감지: 불량률 급증', date: '2024-05-28' }
10
+ ];
11
+ }
12
+ static { this.styles = css `
13
+ :host {
14
+ display: block;
15
+ background: #fff;
16
+ border-radius: 8px;
17
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
18
+ padding: 16px;
19
+ min-width: 320px;
20
+ max-width: 100%;
21
+ }
22
+ .alert-list {
23
+ margin: 0;
24
+ padding: 0;
25
+ list-style: none;
26
+ }
27
+ .alert-item {
28
+ padding: 12px 0;
29
+ border-bottom: 1px solid #eee;
30
+ display: flex;
31
+ align-items: center;
32
+ gap: 12px;
33
+ }
34
+ .alert-item:last-child {
35
+ border-bottom: none;
36
+ }
37
+ .icon {
38
+ font-size: 1.3em;
39
+ color: #e74c3c;
40
+ }
41
+ .message {
42
+ flex: 1;
43
+ color: #e74c3c;
44
+ font-weight: bold;
45
+ }
46
+ .date {
47
+ color: #888;
48
+ font-size: 0.95em;
49
+ }
50
+ `; }
51
+ render() {
52
+ return html `
53
+ <ul class="alert-list">
54
+ ${this.alerts.map(a => html `
55
+ <li class="alert-item">
56
+ <span class="icon">${a.icon}</span>
57
+ <span class="message">${a.message}</span>
58
+ <span class="date">${a.date}</span>
59
+ </li>
60
+ `)}
61
+ </ul>
62
+ `;
63
+ }
64
+ };
65
+ __decorate([
66
+ state(),
67
+ __metadata("design:type", Object)
68
+ ], KpiAlertPanel.prototype, "alerts", void 0);
69
+ KpiAlertPanel = __decorate([
70
+ customElement('kpi-alert-panel')
71
+ ], KpiAlertPanel);
72
+ export { KpiAlertPanel };
73
+ //# sourceMappingURL=kpi-alert-panel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kpi-alert-panel.js","sourceRoot":"","sources":["../../client/pages/kpi-alert-panel.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,KAAK,CAAA;AAC3C,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAGjD,IAAM,aAAa,GAAnB,MAAM,aAAc,SAAQ,UAAU;IAAtC;;QA0CG,WAAM,GAAG;YACf,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,eAAe,EAAE,IAAI,EAAE,YAAY,EAAE;YAC5D,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,eAAe,EAAE,IAAI,EAAE,YAAY,EAAE;SAC7D,CAAA;IAiBH,CAAC;aA7DQ,WAAM,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsClB,AAtCY,CAsCZ;IAQD,MAAM;QACJ,OAAO,IAAI,CAAA;;UAEL,IAAI,CAAC,MAAM,CAAC,GAAG,CACf,CAAC,CAAC,EAAE,CAAC,IAAI,CAAA;;mCAEgB,CAAC,CAAC,IAAI;sCACH,CAAC,CAAC,OAAO;mCACZ,CAAC,CAAC,IAAI;;WAE9B,CACF;;KAEJ,CAAA;IACH,CAAC;;AAnBO;IADP,KAAK,EAAE;;6CAIP;AA7CU,aAAa;IADzB,aAAa,CAAC,iBAAiB,CAAC;GACpB,aAAa,CA8DzB","sourcesContent":["import { html, css, LitElement } from 'lit'\nimport { customElement, state } from 'lit/decorators.js'\n\n@customElement('kpi-alert-panel')\nexport class KpiAlertPanel extends LitElement {\n static styles = css`\n :host {\n display: block;\n background: #fff;\n border-radius: 8px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);\n padding: 16px;\n min-width: 320px;\n max-width: 100%;\n }\n .alert-list {\n margin: 0;\n padding: 0;\n list-style: none;\n }\n .alert-item {\n padding: 12px 0;\n border-bottom: 1px solid #eee;\n display: flex;\n align-items: center;\n gap: 12px;\n }\n .alert-item:last-child {\n border-bottom: none;\n }\n .icon {\n font-size: 1.3em;\n color: #e74c3c;\n }\n .message {\n flex: 1;\n color: #e74c3c;\n font-weight: bold;\n }\n .date {\n color: #888;\n font-size: 0.95em;\n }\n `\n\n @state()\n private alerts = [\n { icon: '⚠️', message: '목표 미달성 KPI 발생', date: '2024-06-01' },\n { icon: '🔔', message: '이상 감지: 불량률 급증', date: '2024-05-28' }\n ]\n\n render() {\n return html`\n <ul class=\"alert-list\">\n ${this.alerts.map(\n a => html`\n <li class=\"alert-item\">\n <span class=\"icon\">${a.icon}</span>\n <span class=\"message\">${a.message}</span>\n <span class=\"date\">${a.date}</span>\n </li>\n `\n )}\n </ul>\n `\n }\n}\n"]}
@@ -0,0 +1,6 @@
1
+ import { LitElement } from 'lit';
2
+ import './kpi-performance-summary';
3
+ export declare class KpiDashboardPage extends LitElement {
4
+ static styles: import("lit").CSSResult;
5
+ render(): import("lit-html").TemplateResult<1>;
6
+ }
@@ -0,0 +1,47 @@
1
+ import { __decorate } from "tslib";
2
+ import { html, css, LitElement } from 'lit';
3
+ import { customElement } from 'lit/decorators.js';
4
+ import './kpi-performance-summary';
5
+ let KpiDashboardPage = class KpiDashboardPage extends LitElement {
6
+ static { this.styles = css `
7
+ :host {
8
+ display: block;
9
+ padding: 32px;
10
+ background: #f4f6fa;
11
+ min-height: 100vh;
12
+ }
13
+ .dashboard-title {
14
+ font-size: 2em;
15
+ font-weight: bold;
16
+ margin-bottom: 24px;
17
+ color: #2a7ae4;
18
+ }
19
+ .widgets {
20
+ display: flex;
21
+ flex-wrap: wrap;
22
+ gap: 32px;
23
+ }
24
+ .widget {
25
+ flex: 1 1 360px;
26
+ min-width: 360px;
27
+ max-width: 600px;
28
+ }
29
+ `; }
30
+ render() {
31
+ return html `
32
+ <div class="dashboard-title">KPI 대시보드</div>
33
+ <div class="widgets">
34
+ <div class="widget">
35
+ <kpi-performance-summary></kpi-performance-summary>
36
+ </div>
37
+ <!-- TODO: 다른 KPI 위젯(등급, 이력, 목록, 입력, 알림 등) 추가 예정 -->
38
+ </div>
39
+ `;
40
+ }
41
+ };
42
+ KpiDashboardPage = __decorate([
43
+ customElement('kpi-dashboard-page')
44
+ ], KpiDashboardPage);
45
+ export { KpiDashboardPage };
46
+ // 사용 예시: <kpi-dashboard-page></kpi-dashboard-page>
47
+ //# sourceMappingURL=kpi-dashboard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kpi-dashboard.js","sourceRoot":"","sources":["../../client/pages/kpi-dashboard.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,KAAK,CAAA;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AACjD,OAAO,2BAA2B,CAAA;AAG3B,IAAM,gBAAgB,GAAtB,MAAM,gBAAiB,SAAQ,UAAU;aACvC,WAAM,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBlB,AAvBY,CAuBZ;IAED,MAAM;QACJ,OAAO,IAAI,CAAA;;;;;;;;KAQV,CAAA;IACH,CAAC;;AApCU,gBAAgB;IAD5B,aAAa,CAAC,oBAAoB,CAAC;GACvB,gBAAgB,CAqC5B;;AAED,mDAAmD","sourcesContent":["import { html, css, LitElement } from 'lit'\nimport { customElement } from 'lit/decorators.js'\nimport './kpi-performance-summary'\n\n@customElement('kpi-dashboard-page')\nexport class KpiDashboardPage extends LitElement {\n static styles = css`\n :host {\n display: block;\n padding: 32px;\n background: #f4f6fa;\n min-height: 100vh;\n }\n .dashboard-title {\n font-size: 2em;\n font-weight: bold;\n margin-bottom: 24px;\n color: #2a7ae4;\n }\n .widgets {\n display: flex;\n flex-wrap: wrap;\n gap: 32px;\n }\n .widget {\n flex: 1 1 360px;\n min-width: 360px;\n max-width: 600px;\n }\n `\n\n render() {\n return html`\n <div class=\"dashboard-title\">KPI 대시보드</div>\n <div class=\"widgets\">\n <div class=\"widget\">\n <kpi-performance-summary></kpi-performance-summary>\n </div>\n <!-- TODO: 다른 KPI 위젯(등급, 이력, 목록, 입력, 알림 등) 추가 예정 -->\n </div>\n `\n }\n}\n\n// 사용 예시: <kpi-dashboard-page></kpi-dashboard-page>\n"]}
@@ -0,0 +1,7 @@
1
+ import { LitElement } from 'lit';
2
+ export declare class KpiGradeVisualization extends LitElement {
3
+ static styles: import("lit").CSSResult;
4
+ private grades;
5
+ private currentGrade;
6
+ render(): import("lit-html").TemplateResult<1>;
7
+ }
@@ -0,0 +1,87 @@
1
+ import { __decorate, __metadata } from "tslib";
2
+ import { html, css, LitElement } from 'lit';
3
+ import { customElement, state } from 'lit/decorators.js';
4
+ let KpiGradeVisualization = class KpiGradeVisualization extends LitElement {
5
+ constructor() {
6
+ super(...arguments);
7
+ this.grades = [
8
+ { label: 'A', range: '90~100', class: 'grade-A' },
9
+ { label: 'B', range: '80~89', class: 'grade-B' },
10
+ { label: 'C', range: '70~79', class: 'grade-C' },
11
+ { label: 'D', range: '0~69', class: 'grade-D' }
12
+ ];
13
+ this.currentGrade = 'A';
14
+ }
15
+ static { this.styles = css `
16
+ :host {
17
+ display: block;
18
+ background: #fff;
19
+ border-radius: 8px;
20
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
21
+ padding: 16px;
22
+ min-width: 320px;
23
+ max-width: 100%;
24
+ }
25
+ .grade-bar {
26
+ display: flex;
27
+ height: 36px;
28
+ border-radius: 8px;
29
+ overflow: hidden;
30
+ margin-bottom: 16px;
31
+ }
32
+ .grade-segment {
33
+ flex: 1;
34
+ display: flex;
35
+ align-items: center;
36
+ justify-content: center;
37
+ color: #fff;
38
+ font-weight: bold;
39
+ font-size: 1.1em;
40
+ }
41
+ .grade-A {
42
+ background: #2ecc40;
43
+ }
44
+ .grade-B {
45
+ background: #f1c40f;
46
+ }
47
+ .grade-C {
48
+ background: #e67e22;
49
+ }
50
+ .grade-D {
51
+ background: #e74c3c;
52
+ }
53
+ .grade-labels {
54
+ display: flex;
55
+ justify-content: space-between;
56
+ font-size: 0.95em;
57
+ color: #888;
58
+ }
59
+ .current-grade {
60
+ margin-top: 12px;
61
+ font-size: 1.3em;
62
+ font-weight: bold;
63
+ color: #2a7ae4;
64
+ text-align: center;
65
+ }
66
+ `; }
67
+ render() {
68
+ return html `
69
+ <div class="grade-bar">${this.grades.map(g => html `<div class="grade-segment ${g.class}">${g.label}</div>`)}</div>
70
+ <div class="grade-labels">${this.grades.map(g => html `<span>${g.range}</span>`)}</div>
71
+ <div class="current-grade">현재 등급: <span>${this.currentGrade}</span></div>
72
+ `;
73
+ }
74
+ };
75
+ __decorate([
76
+ state(),
77
+ __metadata("design:type", Object)
78
+ ], KpiGradeVisualization.prototype, "grades", void 0);
79
+ __decorate([
80
+ state(),
81
+ __metadata("design:type", Object)
82
+ ], KpiGradeVisualization.prototype, "currentGrade", void 0);
83
+ KpiGradeVisualization = __decorate([
84
+ customElement('kpi-grade-visualization')
85
+ ], KpiGradeVisualization);
86
+ export { KpiGradeVisualization };
87
+ //# sourceMappingURL=kpi-grade-visualization.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kpi-grade-visualization.js","sourceRoot":"","sources":["../../client/pages/kpi-grade-visualization.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,KAAK,CAAA;AAC3C,OAAO,EAAE,aAAa,EAAY,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAG3D,IAAM,qBAAqB,GAA3B,MAAM,qBAAsB,SAAQ,UAAU;IAA9C;;QAuDG,WAAM,GAAG;YACf,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE;YACjD,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE;YAChD,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE;YAChD,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE;SAChD,CAAA;QAGO,iBAAY,GAAG,GAAG,CAAA;IAS5B,CAAC;aAvEQ,WAAM,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDlB,AAnDY,CAmDZ;IAaD,MAAM;QACJ,OAAO,IAAI,CAAA;+BACgB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAA,6BAA6B,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,KAAK,QAAQ,CAAC;kCAC/E,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAA,SAAS,CAAC,CAAC,KAAK,SAAS,CAAC;gDACrC,IAAI,CAAC,YAAY;KAC5D,CAAA;IACH,CAAC;;AAhBO;IADP,KAAK,EAAE;;qDAMP;AAGO;IADP,KAAK,EAAE;;2DACkB;AA/Df,qBAAqB;IADjC,aAAa,CAAC,yBAAyB,CAAC;GAC5B,qBAAqB,CAwEjC","sourcesContent":["import { html, css, LitElement } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\n\n@customElement('kpi-grade-visualization')\nexport class KpiGradeVisualization extends LitElement {\n static styles = css`\n :host {\n display: block;\n background: #fff;\n border-radius: 8px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);\n padding: 16px;\n min-width: 320px;\n max-width: 100%;\n }\n .grade-bar {\n display: flex;\n height: 36px;\n border-radius: 8px;\n overflow: hidden;\n margin-bottom: 16px;\n }\n .grade-segment {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #fff;\n font-weight: bold;\n font-size: 1.1em;\n }\n .grade-A {\n background: #2ecc40;\n }\n .grade-B {\n background: #f1c40f;\n }\n .grade-C {\n background: #e67e22;\n }\n .grade-D {\n background: #e74c3c;\n }\n .grade-labels {\n display: flex;\n justify-content: space-between;\n font-size: 0.95em;\n color: #888;\n }\n .current-grade {\n margin-top: 12px;\n font-size: 1.3em;\n font-weight: bold;\n color: #2a7ae4;\n text-align: center;\n }\n `\n\n @state()\n private grades = [\n { label: 'A', range: '90~100', class: 'grade-A' },\n { label: 'B', range: '80~89', class: 'grade-B' },\n { label: 'C', range: '70~79', class: 'grade-C' },\n { label: 'D', range: '0~69', class: 'grade-D' }\n ]\n\n @state()\n private currentGrade = 'A'\n\n render() {\n return html`\n <div class=\"grade-bar\">${this.grades.map(g => html`<div class=\"grade-segment ${g.class}\">${g.label}</div>`)}</div>\n <div class=\"grade-labels\">${this.grades.map(g => html`<span>${g.range}</span>`)}</div>\n <div class=\"current-grade\">현재 등급: <span>${this.currentGrade}</span></div>\n `\n }\n}\n"]}
@@ -0,0 +1,6 @@
1
+ import { LitElement } from 'lit';
2
+ export declare class KpiHistoryViewer extends LitElement {
3
+ static styles: import("lit").CSSResult;
4
+ private history;
5
+ render(): import("lit-html").TemplateResult<1>;
6
+ }
@@ -0,0 +1,73 @@
1
+ import { __decorate, __metadata } from "tslib";
2
+ import { html, css, LitElement } from 'lit';
3
+ import { customElement, state } from 'lit/decorators.js';
4
+ let KpiHistoryViewer = class KpiHistoryViewer extends LitElement {
5
+ constructor() {
6
+ super(...arguments);
7
+ this.history = [
8
+ { version: 3, date: '2024-06-01', action: 'Released' },
9
+ { version: 2, date: '2024-05-01', action: 'Edited' },
10
+ { version: 1, date: '2024-04-01', action: 'Created' }
11
+ ];
12
+ }
13
+ static { this.styles = css `
14
+ :host {
15
+ display: block;
16
+ background: #fff;
17
+ border-radius: 8px;
18
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
19
+ padding: 16px;
20
+ min-width: 320px;
21
+ max-width: 100%;
22
+ }
23
+ .history-list {
24
+ margin: 0;
25
+ padding: 0;
26
+ list-style: none;
27
+ }
28
+ .history-item {
29
+ padding: 12px 0;
30
+ border-bottom: 1px solid #eee;
31
+ display: flex;
32
+ justify-content: space-between;
33
+ align-items: center;
34
+ }
35
+ .history-item:last-child {
36
+ border-bottom: none;
37
+ }
38
+ .version {
39
+ font-weight: bold;
40
+ color: #2a7ae4;
41
+ }
42
+ .date {
43
+ color: #888;
44
+ font-size: 0.95em;
45
+ }
46
+ .action {
47
+ color: #888;
48
+ font-size: 0.95em;
49
+ }
50
+ `; }
51
+ render() {
52
+ return html `
53
+ <ul class="history-list">
54
+ ${this.history.map(h => html `
55
+ <li class="history-item">
56
+ <span class="version">v${h.version}</span>
57
+ <span class="date">${h.date}</span>
58
+ <span class="action">${h.action}</span>
59
+ </li>
60
+ `)}
61
+ </ul>
62
+ `;
63
+ }
64
+ };
65
+ __decorate([
66
+ state(),
67
+ __metadata("design:type", Object)
68
+ ], KpiHistoryViewer.prototype, "history", void 0);
69
+ KpiHistoryViewer = __decorate([
70
+ customElement('kpi-history-viewer')
71
+ ], KpiHistoryViewer);
72
+ export { KpiHistoryViewer };
73
+ //# sourceMappingURL=kpi-history-viewer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kpi-history-viewer.js","sourceRoot":"","sources":["../../client/pages/kpi-history-viewer.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,KAAK,CAAA;AAC3C,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAGjD,IAAM,gBAAgB,GAAtB,MAAM,gBAAiB,SAAQ,UAAU;IAAzC;;QAyCG,YAAO,GAAG;YAChB,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE;YACtD,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE;YACpD,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE;SACtD,CAAA;IAiBH,CAAC;aA7DQ,WAAM,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqClB,AArCY,CAqCZ;IASD,MAAM;QACJ,OAAO,IAAI,CAAA;;UAEL,IAAI,CAAC,OAAO,CAAC,GAAG,CAChB,CAAC,CAAC,EAAE,CAAC,IAAI,CAAA;;uCAEoB,CAAC,CAAC,OAAO;mCACb,CAAC,CAAC,IAAI;qCACJ,CAAC,CAAC,MAAM;;WAElC,CACF;;KAEJ,CAAA;IACH,CAAC;;AApBO;IADP,KAAK,EAAE;;iDAKP;AA7CU,gBAAgB;IAD5B,aAAa,CAAC,oBAAoB,CAAC;GACvB,gBAAgB,CA8D5B","sourcesContent":["import { html, css, LitElement } from 'lit'\nimport { customElement, state } from 'lit/decorators.js'\n\n@customElement('kpi-history-viewer')\nexport class KpiHistoryViewer extends LitElement {\n static styles = css`\n :host {\n display: block;\n background: #fff;\n border-radius: 8px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);\n padding: 16px;\n min-width: 320px;\n max-width: 100%;\n }\n .history-list {\n margin: 0;\n padding: 0;\n list-style: none;\n }\n .history-item {\n padding: 12px 0;\n border-bottom: 1px solid #eee;\n display: flex;\n justify-content: space-between;\n align-items: center;\n }\n .history-item:last-child {\n border-bottom: none;\n }\n .version {\n font-weight: bold;\n color: #2a7ae4;\n }\n .date {\n color: #888;\n font-size: 0.95em;\n }\n .action {\n color: #888;\n font-size: 0.95em;\n }\n `\n\n @state()\n private history = [\n { version: 3, date: '2024-06-01', action: 'Released' },\n { version: 2, date: '2024-05-01', action: 'Edited' },\n { version: 1, date: '2024-04-01', action: 'Created' }\n ]\n\n render() {\n return html`\n <ul class=\"history-list\">\n ${this.history.map(\n h => html`\n <li class=\"history-item\">\n <span class=\"version\">v${h.version}</span>\n <span class=\"date\">${h.date}</span>\n <span class=\"action\">${h.action}</span>\n </li>\n `\n )}\n </ul>\n `\n }\n}\n"]}
@@ -0,0 +1,6 @@
1
+ import { LitElement } from 'lit';
2
+ export declare class KpiListSummary extends LitElement {
3
+ static styles: import("lit").CSSResult;
4
+ private kpis;
5
+ render(): import("lit-html").TemplateResult<1>;
6
+ }
@@ -0,0 +1,82 @@
1
+ import { __decorate, __metadata } from "tslib";
2
+ import { html, css, LitElement } from 'lit';
3
+ import { customElement, state } from 'lit/decorators.js';
4
+ let KpiListSummary = class KpiListSummary extends LitElement {
5
+ constructor() {
6
+ super(...arguments);
7
+ this.kpis = [
8
+ { name: '생산품질', description: '불량률, 수율 등 생산 KPI', status: 'Active' },
9
+ { name: '납기준수', description: '납기 이행률, 지연건수 등', status: 'Active' },
10
+ { name: '고객만족', description: 'VOC, CS 등 고객 KPI', status: 'Inactive' }
11
+ ];
12
+ }
13
+ static { this.styles = css `
14
+ :host {
15
+ display: block;
16
+ background: #fff;
17
+ border-radius: 8px;
18
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
19
+ padding: 16px;
20
+ min-width: 320px;
21
+ max-width: 100%;
22
+ }
23
+ table {
24
+ width: 100%;
25
+ border-collapse: collapse;
26
+ margin-bottom: 0;
27
+ }
28
+ th,
29
+ td {
30
+ padding: 8px 12px;
31
+ border-bottom: 1px solid #eee;
32
+ text-align: left;
33
+ }
34
+ th {
35
+ background: #f5f7fa;
36
+ color: #888;
37
+ font-weight: bold;
38
+ }
39
+ tr:last-child td {
40
+ border-bottom: none;
41
+ }
42
+ .kpi-name {
43
+ color: #2a7ae4;
44
+ font-weight: bold;
45
+ }
46
+ .kpi-desc {
47
+ color: #888;
48
+ font-size: 0.95em;
49
+ }
50
+ `; }
51
+ render() {
52
+ return html `
53
+ <table>
54
+ <thead>
55
+ <tr>
56
+ <th>KPI명</th>
57
+ <th>설명</th>
58
+ <th>상태</th>
59
+ </tr>
60
+ </thead>
61
+ <tbody>
62
+ ${this.kpis.map(kpi => html `
63
+ <tr>
64
+ <td class="kpi-name">${kpi.name}</td>
65
+ <td class="kpi-desc">${kpi.description}</td>
66
+ <td>${kpi.status}</td>
67
+ </tr>
68
+ `)}
69
+ </tbody>
70
+ </table>
71
+ `;
72
+ }
73
+ };
74
+ __decorate([
75
+ state(),
76
+ __metadata("design:type", Object)
77
+ ], KpiListSummary.prototype, "kpis", void 0);
78
+ KpiListSummary = __decorate([
79
+ customElement('kpi-list-summary')
80
+ ], KpiListSummary);
81
+ export { KpiListSummary };
82
+ //# sourceMappingURL=kpi-list-summary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kpi-list-summary.js","sourceRoot":"","sources":["../../client/pages/kpi-list-summary.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,KAAK,CAAA;AAC3C,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAGjD,IAAM,cAAc,GAApB,MAAM,cAAe,SAAQ,UAAU;IAAvC;;QAyCG,SAAI,GAAG;YACb,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,EAAE,QAAQ,EAAE;YACnE,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,EAAE,QAAQ,EAAE;YACjE,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,EAAE,UAAU,EAAE;SACtE,CAAA;IA0BH,CAAC;aAtEQ,WAAM,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqClB,AArCY,CAqCZ;IASD,MAAM;QACJ,OAAO,IAAI,CAAA;;;;;;;;;;YAUH,IAAI,CAAC,IAAI,CAAC,GAAG,CACb,GAAG,CAAC,EAAE,CAAC,IAAI,CAAA;;uCAEgB,GAAG,CAAC,IAAI;uCACR,GAAG,CAAC,WAAW;sBAChC,GAAG,CAAC,MAAM;;aAEnB,CACF;;;KAGN,CAAA;IACH,CAAC;;AA7BO;IADP,KAAK,EAAE;;4CAKP;AA7CU,cAAc;IAD1B,aAAa,CAAC,kBAAkB,CAAC;GACrB,cAAc,CAuE1B","sourcesContent":["import { html, css, LitElement } from 'lit'\nimport { customElement, state } from 'lit/decorators.js'\n\n@customElement('kpi-list-summary')\nexport class KpiListSummary extends LitElement {\n static styles = css`\n :host {\n display: block;\n background: #fff;\n border-radius: 8px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);\n padding: 16px;\n min-width: 320px;\n max-width: 100%;\n }\n table {\n width: 100%;\n border-collapse: collapse;\n margin-bottom: 0;\n }\n th,\n td {\n padding: 8px 12px;\n border-bottom: 1px solid #eee;\n text-align: left;\n }\n th {\n background: #f5f7fa;\n color: #888;\n font-weight: bold;\n }\n tr:last-child td {\n border-bottom: none;\n }\n .kpi-name {\n color: #2a7ae4;\n font-weight: bold;\n }\n .kpi-desc {\n color: #888;\n font-size: 0.95em;\n }\n `\n\n @state()\n private kpis = [\n { name: '생산품질', description: '불량률, 수율 등 생산 KPI', status: 'Active' },\n { name: '납기준수', description: '납기 이행률, 지연건수 등', status: 'Active' },\n { name: '고객만족', description: 'VOC, CS 등 고객 KPI', status: 'Inactive' }\n ]\n\n render() {\n return html`\n <table>\n <thead>\n <tr>\n <th>KPI명</th>\n <th>설명</th>\n <th>상태</th>\n </tr>\n </thead>\n <tbody>\n ${this.kpis.map(\n kpi => html`\n <tr>\n <td class=\"kpi-name\">${kpi.name}</td>\n <td class=\"kpi-desc\">${kpi.description}</td>\n <td>${kpi.status}</td>\n </tr>\n `\n )}\n </tbody>\n </table>\n `\n }\n}\n"]}
@@ -0,0 +1,6 @@
1
+ import { LitElement } from 'lit';
2
+ export declare class KpiPerformanceSummary extends LitElement {
3
+ static styles: import("lit").CSSResult;
4
+ private summary;
5
+ render(): import("lit-html").TemplateResult<1>;
6
+ }
@@ -0,0 +1,82 @@
1
+ import { __decorate, __metadata } from "tslib";
2
+ import { html, css, LitElement } from 'lit';
3
+ import { customElement, state } from 'lit/decorators.js';
4
+ let KpiPerformanceSummary = class KpiPerformanceSummary extends LitElement {
5
+ constructor() {
6
+ super(...arguments);
7
+ this.summary = [
8
+ { title: '목표 달성률', value: '92%' },
9
+ { title: '평균 등급', value: 'A' },
10
+ { title: '이상 감지', value: '0건' },
11
+ { title: '실적 입력률', value: '98%' }
12
+ ];
13
+ }
14
+ static { this.styles = css `
15
+ :host {
16
+ display: block;
17
+ padding: 16px;
18
+ background: #fff;
19
+ border-radius: 8px;
20
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
21
+ min-width: 320px;
22
+ max-width: 100%;
23
+ }
24
+ .summary-cards {
25
+ display: flex;
26
+ gap: 16px;
27
+ margin-bottom: 24px;
28
+ }
29
+ .card {
30
+ flex: 1;
31
+ background: #f5f7fa;
32
+ border-radius: 8px;
33
+ padding: 20px 16px;
34
+ text-align: center;
35
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.03);
36
+ }
37
+ .card-title {
38
+ font-size: 1.1em;
39
+ color: #888;
40
+ margin-bottom: 8px;
41
+ }
42
+ .card-value {
43
+ font-size: 2.2em;
44
+ font-weight: bold;
45
+ color: #2a7ae4;
46
+ }
47
+ .chart {
48
+ width: 100%;
49
+ height: 220px;
50
+ background: #f9fafb;
51
+ border-radius: 8px;
52
+ display: flex;
53
+ align-items: center;
54
+ justify-content: center;
55
+ color: #bbb;
56
+ font-size: 1.2em;
57
+ }
58
+ `; }
59
+ render() {
60
+ return html `
61
+ <div class="summary-cards">
62
+ ${this.summary.map(item => html `
63
+ <div class="card">
64
+ <div class="card-title">${item.title}</div>
65
+ <div class="card-value">${item.value}</div>
66
+ </div>
67
+ `)}
68
+ </div>
69
+ <div class="chart">(여기에 실적 추이 그래프/차트가 들어갑니다)</div>
70
+ `;
71
+ }
72
+ };
73
+ __decorate([
74
+ state(),
75
+ __metadata("design:type", Object)
76
+ ], KpiPerformanceSummary.prototype, "summary", void 0);
77
+ KpiPerformanceSummary = __decorate([
78
+ customElement('kpi-performance-summary')
79
+ ], KpiPerformanceSummary);
80
+ export { KpiPerformanceSummary };
81
+ // 사용 예시: <kpi-performance-summary></kpi-performance-summary>
82
+ //# sourceMappingURL=kpi-performance-summary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kpi-performance-summary.js","sourceRoot":"","sources":["../../client/pages/kpi-performance-summary.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,KAAK,CAAA;AAC3C,OAAO,EAAE,aAAa,EAAY,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAG3D,IAAM,qBAAqB,GAA3B,MAAM,qBAAsB,SAAQ,UAAU;IAA9C;;QAgDG,YAAO,GAAG;YAChB,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE;YACjC,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE;YAC9B,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE;YAC/B,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE;SAClC,CAAA;IAiBH,CAAC;aArEQ,WAAM,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4ClB,AA5CY,CA4CZ;IAUD,MAAM;QACJ,OAAO,IAAI,CAAA;;UAEL,IAAI,CAAC,OAAO,CAAC,GAAG,CAChB,IAAI,CAAC,EAAE,CAAC,IAAI,CAAA;;wCAEkB,IAAI,CAAC,KAAK;wCACV,IAAI,CAAC,KAAK;;WAEvC,CACF;;;KAGJ,CAAA;IACH,CAAC;;AArBO;IADP,KAAK,EAAE;;sDAMP;AArDU,qBAAqB;IADjC,aAAa,CAAC,yBAAyB,CAAC;GAC5B,qBAAqB,CAsEjC;;AAED,6DAA6D","sourcesContent":["import { html, css, LitElement } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\n\n@customElement('kpi-performance-summary')\nexport class KpiPerformanceSummary extends LitElement {\n static styles = css`\n :host {\n display: block;\n padding: 16px;\n background: #fff;\n border-radius: 8px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);\n min-width: 320px;\n max-width: 100%;\n }\n .summary-cards {\n display: flex;\n gap: 16px;\n margin-bottom: 24px;\n }\n .card {\n flex: 1;\n background: #f5f7fa;\n border-radius: 8px;\n padding: 20px 16px;\n text-align: center;\n box-shadow: 0 1px 4px rgba(0, 0, 0, 0.03);\n }\n .card-title {\n font-size: 1.1em;\n color: #888;\n margin-bottom: 8px;\n }\n .card-value {\n font-size: 2.2em;\n font-weight: bold;\n color: #2a7ae4;\n }\n .chart {\n width: 100%;\n height: 220px;\n background: #f9fafb;\n border-radius: 8px;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #bbb;\n font-size: 1.2em;\n }\n `\n\n @state()\n private summary = [\n { title: '목표 달성률', value: '92%' },\n { title: '평균 등급', value: 'A' },\n { title: '이상 감지', value: '0건' },\n { title: '실적 입력률', value: '98%' }\n ]\n\n render() {\n return html`\n <div class=\"summary-cards\">\n ${this.summary.map(\n item => html`\n <div class=\"card\">\n <div class=\"card-title\">${item.title}</div>\n <div class=\"card-value\">${item.value}</div>\n </div>\n `\n )}\n </div>\n <div class=\"chart\">(여기에 실적 추이 그래프/차트가 들어갑니다)</div>\n `\n }\n}\n\n// 사용 예시: <kpi-performance-summary></kpi-performance-summary>\n"]}
@@ -0,0 +1,8 @@
1
+ import { LitElement } from 'lit';
2
+ export declare class KpiValueEntry extends LitElement {
3
+ static styles: import("lit").CSSResult;
4
+ private value;
5
+ render(): import("lit-html").TemplateResult<1>;
6
+ submit(e: Event): void;
7
+ triggerAuto(): void;
8
+ }
@@ -0,0 +1,85 @@
1
+ import { __decorate, __metadata } from "tslib";
2
+ import { html, css, LitElement } from 'lit';
3
+ import { customElement, state } from 'lit/decorators.js';
4
+ let KpiValueEntry = class KpiValueEntry extends LitElement {
5
+ constructor() {
6
+ super(...arguments);
7
+ this.value = '';
8
+ }
9
+ static { this.styles = css `
10
+ :host {
11
+ display: block;
12
+ background: #fff;
13
+ border-radius: 8px;
14
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
15
+ padding: 16px;
16
+ min-width: 320px;
17
+ max-width: 100%;
18
+ }
19
+ .entry-form {
20
+ display: flex;
21
+ gap: 12px;
22
+ align-items: center;
23
+ }
24
+ input[type='number'] {
25
+ width: 100px;
26
+ padding: 6px 8px;
27
+ border: 1px solid #ccc;
28
+ border-radius: 4px;
29
+ font-size: 1em;
30
+ }
31
+ button {
32
+ padding: 6px 16px;
33
+ background: #2a7ae4;
34
+ color: #fff;
35
+ border: none;
36
+ border-radius: 4px;
37
+ font-size: 1em;
38
+ cursor: pointer;
39
+ transition: background 0.2s;
40
+ }
41
+ button:hover {
42
+ background: #1a5bb8;
43
+ }
44
+ .auto-trigger {
45
+ margin-top: 12px;
46
+ text-align: right;
47
+ }
48
+ .auto-trigger button {
49
+ background: #27ae60;
50
+ }
51
+ .auto-trigger button:hover {
52
+ background: #219150;
53
+ }
54
+ `; }
55
+ render() {
56
+ return html `
57
+ <form class="entry-form" @submit=${this.submit}>
58
+ <label>실적 입력:</label>
59
+ <input type="number" .value=${this.value} @input=${e => (this.value = e.target.value)} placeholder="값 입력" />
60
+ <button type="submit">저장</button>
61
+ </form>
62
+ <div class="auto-trigger">
63
+ <button @click=${this.triggerAuto}>자동 집계 실행</button>
64
+ </div>
65
+ `;
66
+ }
67
+ submit(e) {
68
+ e.preventDefault();
69
+ // TODO: GraphQL로 실적값 저장
70
+ alert(`입력값: ${this.value}`);
71
+ }
72
+ triggerAuto() {
73
+ // TODO: GraphQL로 자동 집계 트리거
74
+ alert('자동 집계 실행!');
75
+ }
76
+ };
77
+ __decorate([
78
+ state(),
79
+ __metadata("design:type", Object)
80
+ ], KpiValueEntry.prototype, "value", void 0);
81
+ KpiValueEntry = __decorate([
82
+ customElement('kpi-value-entry')
83
+ ], KpiValueEntry);
84
+ export { KpiValueEntry };
85
+ //# sourceMappingURL=kpi-value-entry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kpi-value-entry.js","sourceRoot":"","sources":["../../client/pages/kpi-value-entry.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,KAAK,CAAA;AAC3C,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAGjD,IAAM,aAAa,GAAnB,MAAM,aAAc,SAAQ,UAAU;IAAtC;;QAiDG,UAAK,GAAG,EAAE,CAAA;IAyBpB,CAAC;aAzEQ,WAAM,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6ClB,AA7CY,CA6CZ;IAKD,MAAM;QACJ,OAAO,IAAI,CAAA;yCAC0B,IAAI,CAAC,MAAM;;sCAEd,IAAI,CAAC,KAAK,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;;;;yBAIpE,IAAI,CAAC,WAAW;;KAEpC,CAAA;IACH,CAAC;IAED,MAAM,CAAC,CAAQ;QACb,CAAC,CAAC,cAAc,EAAE,CAAA;QAClB,wBAAwB;QACxB,KAAK,CAAC,QAAQ,IAAI,CAAC,KAAK,EAAE,CAAC,CAAA;IAC7B,CAAC;IAED,WAAW;QACT,2BAA2B;QAC3B,KAAK,CAAC,WAAW,CAAC,CAAA;IACpB,CAAC;;AAxBO;IADP,KAAK,EAAE;;4CACU;AAjDP,aAAa;IADzB,aAAa,CAAC,iBAAiB,CAAC;GACpB,aAAa,CA0EzB","sourcesContent":["import { html, css, LitElement } from 'lit'\nimport { customElement, state } from 'lit/decorators.js'\n\n@customElement('kpi-value-entry')\nexport class KpiValueEntry extends LitElement {\n static styles = css`\n :host {\n display: block;\n background: #fff;\n border-radius: 8px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);\n padding: 16px;\n min-width: 320px;\n max-width: 100%;\n }\n .entry-form {\n display: flex;\n gap: 12px;\n align-items: center;\n }\n input[type='number'] {\n width: 100px;\n padding: 6px 8px;\n border: 1px solid #ccc;\n border-radius: 4px;\n font-size: 1em;\n }\n button {\n padding: 6px 16px;\n background: #2a7ae4;\n color: #fff;\n border: none;\n border-radius: 4px;\n font-size: 1em;\n cursor: pointer;\n transition: background 0.2s;\n }\n button:hover {\n background: #1a5bb8;\n }\n .auto-trigger {\n margin-top: 12px;\n text-align: right;\n }\n .auto-trigger button {\n background: #27ae60;\n }\n .auto-trigger button:hover {\n background: #219150;\n }\n `\n\n @state()\n private value = ''\n\n render() {\n return html`\n <form class=\"entry-form\" @submit=${this.submit}>\n <label>실적 입력:</label>\n <input type=\"number\" .value=${this.value} @input=${e => (this.value = e.target.value)} placeholder=\"값 입력\" />\n <button type=\"submit\">저장</button>\n </form>\n <div class=\"auto-trigger\">\n <button @click=${this.triggerAuto}>자동 집계 실행</button>\n </div>\n `\n }\n\n submit(e: Event) {\n e.preventDefault()\n // TODO: GraphQL로 실적값 저장\n alert(`입력값: ${this.value}`)\n }\n\n triggerAuto() {\n // TODO: GraphQL로 자동 집계 트리거\n alert('자동 집계 실행!')\n }\n}\n"]}
@@ -5,6 +5,9 @@ export default function route(page) {
5
5
  case 'dashboard':
6
6
  import('./pages/dashboard');
7
7
  return page;
8
+ case 'kpi-dashboard':
9
+ import('./pages/kpi-dashboard');
10
+ return page;
8
11
  }
9
12
  }
10
13
  //# sourceMappingURL=route.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"route.js","sourceRoot":"","sources":["../client/route.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,OAAO,UAAU,KAAK,CAAC,IAAI;IAChC,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,EAAE;YACL,OAAO,YAAY,CAAA;QAErB,KAAK,WAAW;YACd,MAAM,CAAC,mBAAmB,CAAC,CAAA;YAC3B,OAAO,IAAI,CAAA;IACf,CAAC;AACH,CAAC","sourcesContent":["export default function route(page) {\n switch (page) {\n case '':\n return '/dashboard'\n\n case 'dashboard':\n import('./pages/dashboard')\n return page\n }\n}\n"]}
1
+ {"version":3,"file":"route.js","sourceRoot":"","sources":["../client/route.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,OAAO,UAAU,KAAK,CAAC,IAAI;IAChC,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,EAAE;YACL,OAAO,YAAY,CAAA;QAErB,KAAK,WAAW;YACd,MAAM,CAAC,mBAAmB,CAAC,CAAA;YAC3B,OAAO,IAAI,CAAA;QAEb,KAAK,eAAe;YAClB,MAAM,CAAC,uBAAuB,CAAC,CAAA;YAC/B,OAAO,IAAI,CAAA;IACf,CAAC;AACH,CAAC","sourcesContent":["export default function route(page) {\n switch (page) {\n case '':\n return '/dashboard'\n\n case 'dashboard':\n import('./pages/dashboard')\n return page\n\n case 'kpi-dashboard':\n import('./pages/kpi-dashboard')\n return page\n }\n}\n"]}