@nyaruka/temba-components 0.107.0 → 0.107.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/demo/index.html +1 -2
- package/dist/temba-components.js +29 -21
- package/dist/temba-components.js.map +1 -1
- package/out-tsc/src/progress/FlowStartProgress.js +11 -2
- package/out-tsc/src/progress/FlowStartProgress.js.map +1 -1
- package/out-tsc/src/progress/ProgressBar.js +43 -22
- package/out-tsc/src/progress/ProgressBar.js.map +1 -1
- package/package.json +1 -1
- package/src/progress/FlowStartProgress.ts +13 -4
- package/src/progress/ProgressBar.ts +42 -22
|
@@ -22,9 +22,18 @@ export class FlowStartProgress extends RapidElement {
|
|
|
22
22
|
this.started = start.progress.started;
|
|
23
23
|
this.total = start.progress.total;
|
|
24
24
|
const elapsed = new Date().getTime() - new Date(start.created_on).getTime();
|
|
25
|
-
const rate = this.started /
|
|
25
|
+
const rate = this.started / elapsed;
|
|
26
26
|
// calculate the estimated time of arrival
|
|
27
|
-
|
|
27
|
+
const eta = new Date(new Date().getTime() + (this.total - this.started) / rate);
|
|
28
|
+
// Don't bother with estimates months out
|
|
29
|
+
const nextMonth = new Date();
|
|
30
|
+
nextMonth.setMonth(nextMonth.getMonth() + 2);
|
|
31
|
+
if (eta > nextMonth) {
|
|
32
|
+
this.eta = null;
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
this.eta = eta.toISOString();
|
|
36
|
+
}
|
|
28
37
|
if (this.started < this.total) {
|
|
29
38
|
// refresh with a backoff up to 1 minute
|
|
30
39
|
setTimeout(() => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FlowStartProgress.js","sourceRoot":"","sources":["../../../src/progress/FlowStartProgress.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAoC,MAAM,KAAK,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAExC,MAAM,OAAO,iBAAkB,SAAQ,YAAY;IAAnD;;QAWE,cAAS,GAAW,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"FlowStartProgress.js","sourceRoot":"","sources":["../../../src/progress/FlowStartProgress.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, PropertyValueMap, TemplateResult } from 'lit';\nimport { RapidElement } from '../RapidElement';\nimport { property } from 'lit/decorators.js';\nimport { fetchResults } from '../utils';\n\nexport class FlowStartProgress extends RapidElement {\n @property({ type: String })\n uuid: string;\n\n @property({ type: Number })\n started: number;\n\n @property({ type: Number })\n total: number;\n\n @property({ type: Number })\n refreshes: number = 0;\n\n @property({ type: String })\n eta: string;\n\n public updated(\n changes: PropertyValueMap<any> | Map<PropertyKey, unknown>\n ): void {\n super.updated(changes);\n if (changes.has('uuid')) {\n this.refresh();\n }\n }\n\n public refresh(): void {\n fetchResults(`/api/v2/flow_starts.json?uuid=${this.uuid}`).then(\n (data: any) => {\n if (data.length > 0) {\n this.refreshes++;\n const start = data[0];\n this.started = start.progress.started;\n this.total = start.progress.total;\n\n const elapsed =\n new Date().getTime() - new Date(start.created_on).getTime();\n const rate = this.started / elapsed;\n\n // calculate the estimated time of arrival\n const eta = new Date(\n new Date().getTime() + (this.total - this.started) / rate\n );\n\n // Don't bother with estimates months out\n const nextMonth = new Date();\n nextMonth.setMonth(nextMonth.getMonth() + 2);\n if (eta > nextMonth) {\n this.eta = null;\n } else {\n this.eta = eta.toISOString();\n }\n\n if (this.started < this.total) {\n // refresh with a backoff up to 1 minute\n setTimeout(() => {\n this.refresh();\n }, Math.min(1000 * this.refreshes, 60000));\n }\n }\n }\n );\n }\n\n public render(): TemplateResult {\n return html`<temba-progress\n total=${this.total}\n current=${this.started}\n eta=${this.eta}\n ></temba-progress>`;\n }\n}\n"]}
|
|
@@ -10,6 +10,7 @@ export class ProgressBar extends RapidElement {
|
|
|
10
10
|
this.pct = 0;
|
|
11
11
|
this.done = false;
|
|
12
12
|
this.showEstimatedCompletion = false;
|
|
13
|
+
this.showPercentage = false;
|
|
13
14
|
}
|
|
14
15
|
updated(changes) {
|
|
15
16
|
if (changes.has('eta') && this.eta) {
|
|
@@ -17,17 +18,29 @@ export class ProgressBar extends RapidElement {
|
|
|
17
18
|
this.showEstimatedCompletion = this.estimatedCompletionDate > new Date();
|
|
18
19
|
}
|
|
19
20
|
if (changes.has('current')) {
|
|
20
|
-
|
|
21
|
+
const pct = Math.floor(Math.min((this.current / this.total) * 100, 100));
|
|
22
|
+
if (Number.isNaN(pct)) {
|
|
23
|
+
this.showPercentage = false;
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
this.pct = pct;
|
|
27
|
+
this.showPercentage = true;
|
|
28
|
+
}
|
|
21
29
|
this.done = this.pct >= 100;
|
|
22
30
|
}
|
|
23
31
|
}
|
|
24
32
|
render() {
|
|
25
|
-
return html `<div class="
|
|
26
|
-
<
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
33
|
+
return html `<div class="wrapper">
|
|
34
|
+
<div class="meter ${this.done ? 'done' : ''}">
|
|
35
|
+
<span class="complete" style="flex-basis: ${this.pct}%"></span>
|
|
36
|
+
<div class="incomplete"></div>
|
|
37
|
+
</div>
|
|
38
|
+
|
|
39
|
+
${this.showPercentage || this.showEstimatedCompletion
|
|
40
|
+
? html `<div class="etc">
|
|
41
|
+
${this.estimatedCompletionDate &&
|
|
42
|
+
this.showEstimatedCompletion &&
|
|
43
|
+
!this.done
|
|
31
44
|
? html `<temba-date
|
|
32
45
|
value="${this.estimatedCompletionDate.toISOString()}"
|
|
33
46
|
display="countdown"
|
|
@@ -39,23 +52,29 @@ export class ProgressBar extends RapidElement {
|
|
|
39
52
|
}
|
|
40
53
|
}
|
|
41
54
|
ProgressBar.styles = css `
|
|
55
|
+
.wrapper {
|
|
56
|
+
display: flex;
|
|
57
|
+
box-sizing: content-box;
|
|
58
|
+
background: #f1f1f1;
|
|
59
|
+
border-radius: var(--curvature);
|
|
60
|
+
box-shadow: inset 1px 1px 1px rgba(0, 0, 0, 0.05);
|
|
61
|
+
}
|
|
62
|
+
|
|
42
63
|
.meter {
|
|
64
|
+
flex-grow: 1;
|
|
43
65
|
display: flex;
|
|
44
66
|
box-sizing: content-box;
|
|
45
|
-
height: 8px;
|
|
46
67
|
position: relative;
|
|
47
|
-
background: #f1f1f1;
|
|
48
68
|
border-radius: var(--curvature);
|
|
69
|
+
border-top-right-radius: 0;
|
|
70
|
+
border-bottom-right-radius: 0;
|
|
49
71
|
padding: 4px;
|
|
50
|
-
|
|
72
|
+
min-height: 6px;
|
|
51
73
|
}
|
|
52
74
|
.meter > span {
|
|
53
75
|
display: block;
|
|
54
76
|
height: 100%;
|
|
55
|
-
border-
|
|
56
|
-
border-bottom-right-radius: var(--curvature);
|
|
57
|
-
border-top-left-radius: var(--curvature);
|
|
58
|
-
border-bottom-left-radius: var(--curvature);
|
|
77
|
+
border-radius: var(--curvature);
|
|
59
78
|
background-color: var(--color-primary-dark);
|
|
60
79
|
background-image: linear-gradient(
|
|
61
80
|
center bottom,
|
|
@@ -65,7 +84,9 @@ ProgressBar.styles = css `
|
|
|
65
84
|
|
|
66
85
|
position: relative;
|
|
67
86
|
overflow: hidden;
|
|
87
|
+
min-width: 3px;
|
|
68
88
|
}
|
|
89
|
+
|
|
69
90
|
.meter > span:after,
|
|
70
91
|
.animate > span > span {
|
|
71
92
|
content: '';
|
|
@@ -117,17 +138,14 @@ ProgressBar.styles = css `
|
|
|
117
138
|
|
|
118
139
|
.etc {
|
|
119
140
|
font-size: 0.7em;
|
|
120
|
-
padding: 4px;
|
|
121
|
-
padding-top: 1px;
|
|
122
|
-
padding-left: 8px;
|
|
123
|
-
padding-right: 8px;
|
|
124
|
-
margin-top: -4px;
|
|
125
|
-
margin-bottom: -4px;
|
|
126
|
-
margin-right: -4px;
|
|
127
|
-
margin-left: 0.5em;
|
|
128
141
|
background: rgba(0, 0, 0, 0.07);
|
|
129
142
|
font-weight: bold;
|
|
130
143
|
white-space: nowrap;
|
|
144
|
+
border-top-right-radius: var(--curvature);
|
|
145
|
+
border-bottom-right-radius: var(--curvature);
|
|
146
|
+
color: rgba(0, 0, 0, 0.5);
|
|
147
|
+
align-self: center;
|
|
148
|
+
padding: 2px 6px;
|
|
131
149
|
}
|
|
132
150
|
|
|
133
151
|
.meter.done > span:after,
|
|
@@ -160,4 +178,7 @@ __decorate([
|
|
|
160
178
|
__decorate([
|
|
161
179
|
property({ type: Boolean })
|
|
162
180
|
], ProgressBar.prototype, "showEstimatedCompletion", void 0);
|
|
181
|
+
__decorate([
|
|
182
|
+
property({ type: Boolean })
|
|
183
|
+
], ProgressBar.prototype, "showPercentage", void 0);
|
|
163
184
|
//# sourceMappingURL=ProgressBar.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProgressBar.js","sourceRoot":"","sources":["../../../src/progress/ProgressBar.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAoC,MAAM,KAAK,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE7C,MAAM,OAAO,WAAY,SAAQ,YAAY;IAA7C;;
|
|
1
|
+
{"version":3,"file":"ProgressBar.js","sourceRoot":"","sources":["../../../src/progress/ProgressBar.ts"],"names":[],"mappings":"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","sourcesContent":["import { css, html, PropertyValueMap, TemplateResult } from 'lit';\nimport { RapidElement } from '../RapidElement';\nimport { property } from 'lit/decorators.js';\n\nexport class ProgressBar extends RapidElement {\n static styles = css`\n .wrapper {\n display: flex;\n box-sizing: content-box;\n background: #f1f1f1;\n border-radius: var(--curvature);\n box-shadow: inset 1px 1px 1px rgba(0, 0, 0, 0.05);\n }\n\n .meter {\n flex-grow: 1;\n display: flex;\n box-sizing: content-box;\n position: relative;\n border-radius: var(--curvature);\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n padding: 4px;\n min-height: 6px;\n }\n .meter > span {\n display: block;\n height: 100%;\n border-radius: var(--curvature);\n background-color: var(--color-primary-dark);\n background-image: linear-gradient(\n center bottom,\n rgb(43, 194, 83) 37%,\n rgb(84, 240, 83) 69%\n );\n\n position: relative;\n overflow: hidden;\n min-width: 3px;\n }\n\n .meter > span:after,\n .animate > span > span {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n right: 0;\n background-image: linear-gradient(\n -45deg,\n rgba(255, 255, 255, 0.2) 25%,\n transparent 25%,\n transparent 50%,\n rgba(255, 255, 255, 0.2) 50%,\n rgba(255, 255, 255, 0.2) 75%,\n transparent 75%,\n transparent\n );\n z-index: 1;\n background-size: 50px 50px;\n animation: move 16s linear infinite;\n border-top-right-radius: var(--curvature);\n border-bottom-right-radius: var(--curvature);\n border-top-left-radius: var(--curvature);\n border-bottom-left-radius: var(--curvature);\n overflow: hidden;\n }\n\n .animate > span:after {\n display: none;\n }\n\n @keyframes move {\n 0% {\n background-position: 0 0;\n }\n 100% {\n background-position: 50px 50px;\n }\n }\n\n .complete {\n transition: width 2s;\n }\n\n .incomplete {\n flex-grow: 1;\n }\n\n .etc {\n font-size: 0.7em;\n background: rgba(0, 0, 0, 0.07);\n font-weight: bold;\n white-space: nowrap;\n border-top-right-radius: var(--curvature);\n border-bottom-right-radius: var(--curvature);\n color: rgba(0, 0, 0, 0.5);\n align-self: center;\n padding: 2px 6px;\n }\n\n .meter.done > span:after,\n .done .animate > span > span {\n display: none;\n }\n\n .meter.done > span {\n background: rgb(var(--success-rgb));\n }\n `;\n\n @property({ type: Number })\n total = 100;\n\n @property({ type: Number })\n current = 0;\n\n @property({ type: Number })\n pct = 0;\n\n @property({ type: Boolean })\n done = false;\n\n @property({ type: String })\n eta: string;\n\n @property({ type: String, attribute: false })\n estimatedCompletionDate: Date;\n\n @property({ type: Boolean })\n showEstimatedCompletion = false;\n\n @property({ type: Boolean })\n showPercentage = false;\n\n public updated(\n changes: PropertyValueMap<any> | Map<PropertyKey, unknown>\n ): void {\n if (changes.has('eta') && this.eta) {\n this.estimatedCompletionDate = new Date(this.eta);\n this.showEstimatedCompletion = this.estimatedCompletionDate > new Date();\n }\n\n if (changes.has('current')) {\n const pct = Math.floor(Math.min((this.current / this.total) * 100, 100));\n if (Number.isNaN(pct)) {\n this.showPercentage = false;\n } else {\n this.pct = pct;\n this.showPercentage = true;\n }\n\n this.done = this.pct >= 100;\n }\n }\n\n public render(): TemplateResult {\n return html`<div class=\"wrapper\">\n <div class=\"meter ${this.done ? 'done' : ''}\">\n <span class=\"complete\" style=\"flex-basis: ${this.pct}%\"></span>\n <div class=\"incomplete\"></div>\n </div>\n\n ${this.showPercentage || this.showEstimatedCompletion\n ? html`<div class=\"etc\">\n ${this.estimatedCompletionDate &&\n this.showEstimatedCompletion &&\n !this.done\n ? html`<temba-date\n value=\"${this.estimatedCompletionDate.toISOString()}\"\n display=\"countdown\"\n ></temba-date>`\n : html`${this.pct}%`}\n </div>`\n : null}\n </div>`;\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -39,12 +39,21 @@ export class FlowStartProgress extends RapidElement {
|
|
|
39
39
|
|
|
40
40
|
const elapsed =
|
|
41
41
|
new Date().getTime() - new Date(start.created_on).getTime();
|
|
42
|
-
const rate = this.started /
|
|
42
|
+
const rate = this.started / elapsed;
|
|
43
43
|
|
|
44
44
|
// calculate the estimated time of arrival
|
|
45
|
-
|
|
46
|
-
new Date().getTime() + (
|
|
47
|
-
)
|
|
45
|
+
const eta = new Date(
|
|
46
|
+
new Date().getTime() + (this.total - this.started) / rate
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
// Don't bother with estimates months out
|
|
50
|
+
const nextMonth = new Date();
|
|
51
|
+
nextMonth.setMonth(nextMonth.getMonth() + 2);
|
|
52
|
+
if (eta > nextMonth) {
|
|
53
|
+
this.eta = null;
|
|
54
|
+
} else {
|
|
55
|
+
this.eta = eta.toISOString();
|
|
56
|
+
}
|
|
48
57
|
|
|
49
58
|
if (this.started < this.total) {
|
|
50
59
|
// refresh with a backoff up to 1 minute
|
|
@@ -4,23 +4,29 @@ import { property } from 'lit/decorators.js';
|
|
|
4
4
|
|
|
5
5
|
export class ProgressBar extends RapidElement {
|
|
6
6
|
static styles = css`
|
|
7
|
+
.wrapper {
|
|
8
|
+
display: flex;
|
|
9
|
+
box-sizing: content-box;
|
|
10
|
+
background: #f1f1f1;
|
|
11
|
+
border-radius: var(--curvature);
|
|
12
|
+
box-shadow: inset 1px 1px 1px rgba(0, 0, 0, 0.05);
|
|
13
|
+
}
|
|
14
|
+
|
|
7
15
|
.meter {
|
|
16
|
+
flex-grow: 1;
|
|
8
17
|
display: flex;
|
|
9
18
|
box-sizing: content-box;
|
|
10
|
-
height: 8px;
|
|
11
19
|
position: relative;
|
|
12
|
-
background: #f1f1f1;
|
|
13
20
|
border-radius: var(--curvature);
|
|
21
|
+
border-top-right-radius: 0;
|
|
22
|
+
border-bottom-right-radius: 0;
|
|
14
23
|
padding: 4px;
|
|
15
|
-
|
|
24
|
+
min-height: 6px;
|
|
16
25
|
}
|
|
17
26
|
.meter > span {
|
|
18
27
|
display: block;
|
|
19
28
|
height: 100%;
|
|
20
|
-
border-
|
|
21
|
-
border-bottom-right-radius: var(--curvature);
|
|
22
|
-
border-top-left-radius: var(--curvature);
|
|
23
|
-
border-bottom-left-radius: var(--curvature);
|
|
29
|
+
border-radius: var(--curvature);
|
|
24
30
|
background-color: var(--color-primary-dark);
|
|
25
31
|
background-image: linear-gradient(
|
|
26
32
|
center bottom,
|
|
@@ -30,7 +36,9 @@ export class ProgressBar extends RapidElement {
|
|
|
30
36
|
|
|
31
37
|
position: relative;
|
|
32
38
|
overflow: hidden;
|
|
39
|
+
min-width: 3px;
|
|
33
40
|
}
|
|
41
|
+
|
|
34
42
|
.meter > span:after,
|
|
35
43
|
.animate > span > span {
|
|
36
44
|
content: '';
|
|
@@ -82,17 +90,14 @@ export class ProgressBar extends RapidElement {
|
|
|
82
90
|
|
|
83
91
|
.etc {
|
|
84
92
|
font-size: 0.7em;
|
|
85
|
-
padding: 4px;
|
|
86
|
-
padding-top: 1px;
|
|
87
|
-
padding-left: 8px;
|
|
88
|
-
padding-right: 8px;
|
|
89
|
-
margin-top: -4px;
|
|
90
|
-
margin-bottom: -4px;
|
|
91
|
-
margin-right: -4px;
|
|
92
|
-
margin-left: 0.5em;
|
|
93
93
|
background: rgba(0, 0, 0, 0.07);
|
|
94
94
|
font-weight: bold;
|
|
95
95
|
white-space: nowrap;
|
|
96
|
+
border-top-right-radius: var(--curvature);
|
|
97
|
+
border-bottom-right-radius: var(--curvature);
|
|
98
|
+
color: rgba(0, 0, 0, 0.5);
|
|
99
|
+
align-self: center;
|
|
100
|
+
padding: 2px 6px;
|
|
96
101
|
}
|
|
97
102
|
|
|
98
103
|
.meter.done > span:after,
|
|
@@ -126,6 +131,9 @@ export class ProgressBar extends RapidElement {
|
|
|
126
131
|
@property({ type: Boolean })
|
|
127
132
|
showEstimatedCompletion = false;
|
|
128
133
|
|
|
134
|
+
@property({ type: Boolean })
|
|
135
|
+
showPercentage = false;
|
|
136
|
+
|
|
129
137
|
public updated(
|
|
130
138
|
changes: PropertyValueMap<any> | Map<PropertyKey, unknown>
|
|
131
139
|
): void {
|
|
@@ -135,18 +143,30 @@ export class ProgressBar extends RapidElement {
|
|
|
135
143
|
}
|
|
136
144
|
|
|
137
145
|
if (changes.has('current')) {
|
|
138
|
-
|
|
146
|
+
const pct = Math.floor(Math.min((this.current / this.total) * 100, 100));
|
|
147
|
+
if (Number.isNaN(pct)) {
|
|
148
|
+
this.showPercentage = false;
|
|
149
|
+
} else {
|
|
150
|
+
this.pct = pct;
|
|
151
|
+
this.showPercentage = true;
|
|
152
|
+
}
|
|
153
|
+
|
|
139
154
|
this.done = this.pct >= 100;
|
|
140
155
|
}
|
|
141
156
|
}
|
|
142
157
|
|
|
143
158
|
public render(): TemplateResult {
|
|
144
|
-
return html`<div class="
|
|
145
|
-
<
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
159
|
+
return html`<div class="wrapper">
|
|
160
|
+
<div class="meter ${this.done ? 'done' : ''}">
|
|
161
|
+
<span class="complete" style="flex-basis: ${this.pct}%"></span>
|
|
162
|
+
<div class="incomplete"></div>
|
|
163
|
+
</div>
|
|
164
|
+
|
|
165
|
+
${this.showPercentage || this.showEstimatedCompletion
|
|
166
|
+
? html`<div class="etc">
|
|
167
|
+
${this.estimatedCompletionDate &&
|
|
168
|
+
this.showEstimatedCompletion &&
|
|
169
|
+
!this.done
|
|
150
170
|
? html`<temba-date
|
|
151
171
|
value="${this.estimatedCompletionDate.toISOString()}"
|
|
152
172
|
display="countdown"
|