@dream-encode/wp-js-plugin-utils 0.2.6 → 0.4.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.
@@ -0,0 +1,112 @@
1
+ /*
2
+ * Generic styling for the wp-plugin-utils Progress component.
3
+ *
4
+ * Targets the `<progress>` element rendered by `<Progress>`. Apply to a
5
+ * selector that matches the `className` prop (defaults to `progress-bar`).
6
+ *
7
+ * .progress-bar {
8
+ * @include de-wp-plugin-utils-progress();
9
+ * }
10
+ */
11
+
12
+ $de-wp-plugin-utils-progress-waiting-color: #f1efef !default;
13
+ $de-wp-plugin-utils-progress-processing-color: #006FE6 !default;
14
+ $de-wp-plugin-utils-progress-complete-color: #65C728 !default;
15
+ $de-wp-plugin-utils-progress-border-radius: 5px !default;
16
+ $de-wp-plugin-utils-progress-shimmer-end-color: rgba(255, 255, 255, 0.3) !default;
17
+
18
+ @mixin de-wp-plugin-utils-progress(
19
+ $waiting-color: $de-wp-plugin-utils-progress-waiting-color,
20
+ $processing-color: $de-wp-plugin-utils-progress-processing-color,
21
+ $complete-color: $de-wp-plugin-utils-progress-complete-color,
22
+ $border-radius: $de-wp-plugin-utils-progress-border-radius,
23
+ $shimmer-end-color: $de-wp-plugin-utils-progress-shimmer-end-color
24
+ ) {
25
+ height: 20px;
26
+ width: 100%;
27
+ border-radius: $border-radius;
28
+ position: relative;
29
+
30
+ &::-webkit-progress-bar {
31
+ background: $waiting-color;
32
+ border-radius: $border-radius;
33
+ }
34
+
35
+ &.processing {
36
+ &::after {
37
+ content: '';
38
+ position: absolute;
39
+ top: 0;
40
+ left: 0;
41
+ width: 100%;
42
+ height: 100%;
43
+ background: linear-gradient(
44
+ 90deg,
45
+ transparent 0%,
46
+ $shimmer-end-color 50%,
47
+ transparent 100%
48
+ );
49
+ background-size: 200% 100%;
50
+ border-radius: $border-radius;
51
+ animation: de-wp-plugin-utils-progress-shimmer 2s infinite linear;
52
+ pointer-events: none;
53
+ }
54
+
55
+ &::-webkit-progress-value {
56
+ background: $processing-color;
57
+ animation: none;
58
+ }
59
+
60
+ &::-webkit-progress-bar {
61
+ animation: none;
62
+ }
63
+ }
64
+
65
+ &.pending,
66
+ &.queued {
67
+ &::-webkit-progress-value {
68
+ background: $waiting-color;
69
+ animation-name: de-wp-plugin-utils-progress-pulse-waiting;
70
+ animation-duration: 2s;
71
+ animation-iteration-count: infinite;
72
+ }
73
+
74
+ &::-webkit-progress-bar {
75
+ animation-name: de-wp-plugin-utils-progress-pulse-waiting;
76
+ animation-duration: 2s;
77
+ animation-iteration-count: infinite;
78
+ }
79
+ }
80
+
81
+ &.complete {
82
+ &::-webkit-progress-value {
83
+ background: $complete-color;
84
+ }
85
+ }
86
+
87
+ &::-webkit-progress-value,
88
+ &[value]::-webkit-progress-value {
89
+ border-radius: $border-radius;
90
+ transition: all 1s ease;
91
+ }
92
+ }
93
+
94
+ @keyframes de-wp-plugin-utils-progress-pulse-waiting {
95
+ 0% {
96
+ background-color: hsl( 200, 20%, 70% );
97
+ }
98
+
99
+ 100% {
100
+ background-color: hsl( 200, 20%, 95% );
101
+ }
102
+ }
103
+
104
+ @keyframes de-wp-plugin-utils-progress-shimmer {
105
+ 0% {
106
+ background-position: -200% 0;
107
+ }
108
+
109
+ 100% {
110
+ background-position: 200% 0;
111
+ }
112
+ }
@@ -3,11 +3,69 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
+ Object.defineProperty(exports, "DismissAllButton", {
7
+ enumerable: true,
8
+ get: function () {
9
+ return _NotificationsDrawer.DismissAllButton;
10
+ }
11
+ });
6
12
  Object.defineProperty(exports, "Notices", {
7
13
  enumerable: true,
8
14
  get: function () {
9
15
  return _Notices.default;
10
16
  }
11
17
  });
18
+ Object.defineProperty(exports, "NotificationItem", {
19
+ enumerable: true,
20
+ get: function () {
21
+ return _NotificationsDrawer.NotificationItem;
22
+ }
23
+ });
24
+ Object.defineProperty(exports, "NotificationsDrawer", {
25
+ enumerable: true,
26
+ get: function () {
27
+ return _NotificationsDrawer.default;
28
+ }
29
+ });
30
+ Object.defineProperty(exports, "NotificationsList", {
31
+ enumerable: true,
32
+ get: function () {
33
+ return _NotificationsDrawer.NotificationsList;
34
+ }
35
+ });
36
+ Object.defineProperty(exports, "ProcessInfo", {
37
+ enumerable: true,
38
+ get: function () {
39
+ return _Process.default;
40
+ }
41
+ });
42
+ Object.defineProperty(exports, "ProcessInfoRow", {
43
+ enumerable: true,
44
+ get: function () {
45
+ return _Process.ProcessInfoRow;
46
+ }
47
+ });
48
+ Object.defineProperty(exports, "ProcessStatusInfo", {
49
+ enumerable: true,
50
+ get: function () {
51
+ return _Process.ProcessStatusInfo;
52
+ }
53
+ });
54
+ Object.defineProperty(exports, "ProcessStatusSummary", {
55
+ enumerable: true,
56
+ get: function () {
57
+ return _Process.ProcessStatusSummary;
58
+ }
59
+ });
60
+ Object.defineProperty(exports, "Progress", {
61
+ enumerable: true,
62
+ get: function () {
63
+ return _Progress.default;
64
+ }
65
+ });
12
66
  var _Notices = _interopRequireDefault(require("./Notices"));
67
+ var _NotificationsDrawer = _interopRequireWildcard(require("./NotificationsDrawer"));
68
+ var _Process = _interopRequireWildcard(require("./Process"));
69
+ var _Progress = _interopRequireDefault(require("./Progress"));
70
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
13
71
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.secondsToDhmsShortIso = exports.secondsToDhmsShort = exports.secondsToDhms = exports.addSecondsToCurrentTime = void 0;
6
+ exports.secondsToDhmsShortIso = exports.secondsToDhmsShort = exports.secondsToDhms = exports.calculateEstimatedTimeRemainingUsingSMA = exports.calculateEstimatedTimeRemainingUsingEMA = exports.calculateEstimatedTimeRemainingSimple = exports.addSecondsToCurrentTime = void 0;
7
7
  var _strings = require("./strings");
8
8
  /**
9
9
  * Convert seconds to a human readable format.
@@ -80,4 +80,135 @@ const addSecondsToCurrentTime = seconds => {
80
80
  rawDate = new Date(rawDate.getTime() + Number(seconds * 1000));
81
81
  return rawDate.getTime() / 1000;
82
82
  };
83
- exports.addSecondsToCurrentTime = addSecondsToCurrentTime;
83
+
84
+ /**
85
+ * Calculate an estimated time remaining based on elapsed time and percent complete.
86
+ *
87
+ * @param {number} startTime Unix timestamp (seconds) when the process started.
88
+ * @param {number} percentComplete Percent complete (0-100).
89
+ * @return {number}
90
+ */
91
+ exports.addSecondsToCurrentTime = addSecondsToCurrentTime;
92
+ const calculateEstimatedTimeRemainingSimple = (startTime, percentComplete) => {
93
+ if (!startTime || percentComplete <= 0 || percentComplete >= 100) {
94
+ return 0;
95
+ }
96
+ const secondsSinceStartTime = Date.now() / 1000 - Number(startTime);
97
+ const decimalComplete = percentComplete / 100;
98
+ const totalSeconds = secondsSinceStartTime / decimalComplete;
99
+ const remaining = totalSeconds - secondsSinceStartTime;
100
+ return Math.max(1, remaining);
101
+ };
102
+
103
+ /**
104
+ * Calculate an estimated time remaining, using Simple Moving Average (SMA).
105
+ *
106
+ * @param {number[]} times Array of previous run times (seconds).
107
+ * @param {number} window Subset of times to use.
108
+ * @param {number} n Number of loops.
109
+ * @return {number[]}
110
+ */
111
+ exports.calculateEstimatedTimeRemainingSimple = calculateEstimatedTimeRemainingSimple;
112
+ const calculateEstimatedTimeRemainingUsingSMA = (times, window = 2, n = Infinity) => {
113
+ if (!times || times.length < window) {
114
+ return [];
115
+ }
116
+ let index = window - 1;
117
+ const length = times.length + 1;
118
+ const simpleMovingAverages = [];
119
+ let numberOfSMAsCalculated = 0;
120
+ while (++index < length && numberOfSMAsCalculated++ < n) {
121
+ const windowSlice = times.slice(index - window, index);
122
+ const sum = windowSlice.reduce((prev, curr) => prev + curr, 0);
123
+ simpleMovingAverages.push(sum / window);
124
+ }
125
+ return simpleMovingAverages;
126
+ };
127
+
128
+ /**
129
+ * Calculate an estimated time remaining, using Exponential Moving Average (EMA).
130
+ *
131
+ * Each run object should expose at least `start_time`. Optional fields
132
+ * `completed_time`, `last_attempt_time` and `total_time` are used when present.
133
+ *
134
+ * @param {Object[]} runs Array of process run records.
135
+ * @param {number} window Subset of times to use.
136
+ * @param {boolean} useCycleTime Whether to use full cycle time instead of pure processing time.
137
+ * @return {{emaValues: number[], avgTime: number}}
138
+ */
139
+ exports.calculateEstimatedTimeRemainingUsingSMA = calculateEstimatedTimeRemainingUsingSMA;
140
+ const calculateEstimatedTimeRemainingUsingEMA = (runs, window = 2, useCycleTime = true) => {
141
+ if (!runs || runs.length < window + 1) {
142
+ return {
143
+ emaValues: [],
144
+ avgTime: 0
145
+ };
146
+ }
147
+ const sortedRuns = [...runs].sort((a, b) => Number(a.start_time) - Number(b.start_time));
148
+ let timesToUse = [];
149
+ if (useCycleTime) {
150
+ const runsWithCycleTimes = [];
151
+ for (let i = 1; i < sortedRuns.length; i++) {
152
+ const previousRun = sortedRuns[i - 1];
153
+ const currentRun = sortedRuns[i];
154
+ const processingTime = currentRun.completed_time ? Number(currentRun.completed_time) - Number(currentRun.start_time) : currentRun.last_attempt_time ? Number(currentRun.last_attempt_time) - Number(currentRun.start_time) : 0;
155
+ const previousEndTime = previousRun.completed_time ? Number(previousRun.completed_time) : previousRun.last_attempt_time ? Number(previousRun.last_attempt_time) : Number(previousRun.start_time);
156
+ const currentEndTime = currentRun.completed_time ? Number(currentRun.completed_time) : currentRun.last_attempt_time ? Number(currentRun.last_attempt_time) : Number(currentRun.start_time);
157
+ const cycleTime = currentEndTime - previousEndTime;
158
+ if (cycleTime > 0 && processingTime > 0) {
159
+ runsWithCycleTimes.push({
160
+ ...currentRun,
161
+ total_time: processingTime,
162
+ cycle_time: cycleTime
163
+ });
164
+ }
165
+ }
166
+ if (runsWithCycleTimes.length < window) {
167
+ return {
168
+ emaValues: [],
169
+ avgTime: 0
170
+ };
171
+ }
172
+ timesToUse = runsWithCycleTimes.map(run => run.cycle_time);
173
+ } else {
174
+ timesToUse = sortedRuns.map(run => {
175
+ if (typeof run.total_time === 'number' && run.total_time > 0) {
176
+ return run.total_time;
177
+ }
178
+ const startTime = run.start_time ? Number(run.start_time) : null;
179
+ const endTime = run.completed_time ? Number(run.completed_time) : run.last_attempt_time ? Number(run.last_attempt_time) : null;
180
+ return startTime && endTime ? endTime - startTime : 0;
181
+ }).filter(time => time > 0);
182
+ if (timesToUse.length < window) {
183
+ return {
184
+ emaValues: [],
185
+ avgTime: 0
186
+ };
187
+ }
188
+ }
189
+ let index = window - 1;
190
+ let previousEmaIndex = 0;
191
+ const length = timesToUse.length;
192
+ const smoothingFactor = 2 / (window + 1);
193
+ const exponentialMovingAverages = [];
194
+ const smaValues = calculateEstimatedTimeRemainingUsingSMA(timesToUse, window, 1);
195
+ const sma = smaValues.length > 0 ? smaValues[0] : 0;
196
+ if (sma <= 0) {
197
+ return {
198
+ emaValues: [],
199
+ avgTime: 0
200
+ };
201
+ }
202
+ exponentialMovingAverages.push(sma);
203
+ while (++index < length) {
204
+ const value = timesToUse[index];
205
+ const previousEma = exponentialMovingAverages[previousEmaIndex++];
206
+ const currentEma = (value - previousEma) * smoothingFactor + previousEma;
207
+ exponentialMovingAverages.push(currentEma);
208
+ }
209
+ return {
210
+ emaValues: exponentialMovingAverages,
211
+ avgTime: exponentialMovingAverages.length > 0 ? exponentialMovingAverages[exponentialMovingAverages.length - 1] : 0
212
+ };
213
+ };
214
+ exports.calculateEstimatedTimeRemainingUsingEMA = calculateEstimatedTimeRemainingUsingEMA;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dream-encode/wp-js-plugin-utils",
3
- "version": "0.2.6",
3
+ "version": "0.4.0",
4
4
  "description": "Common JS functionality used by custom WP plugins.",
5
5
  "keywords": [
6
6
  "wordpress",
@@ -27,6 +27,9 @@
27
27
  "./settings/styles": "./dist/settings/styles/_settings-page.scss",
28
28
  "./data-migrations": "./dist/data-migrations/index.js",
29
29
  "./components": "./dist/components/index.js",
30
+ "./components/notifications-drawer/styles": "./dist/components/NotificationsDrawer/styles/_notifications-drawer.scss",
31
+ "./components/process/styles": "./dist/components/Process/styles/_process.scss",
32
+ "./components/progress/styles": "./dist/components/Progress/styles/_progress.scss",
30
33
  "./hooks": "./dist/hooks/index.js",
31
34
  "./api": "./dist/api/index.js",
32
35
  "./utils": "./dist/utils/index.js",