@dream-encode/wp-js-plugin-utils 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +109 -0
- package/dist/api/fetchOptions.js +39 -0
- package/dist/api/index.js +16 -0
- package/dist/components/Notices.js +24 -0
- package/dist/components/index.js +13 -0
- package/dist/data-migrations/index.js +50 -0
- package/dist/data-migrations/registerOnReady.js +36 -0
- package/dist/data-migrations/registry.js +136 -0
- package/dist/hooks/index.js +27 -0
- package/dist/hooks/useBlurableContent.js +19 -0
- package/dist/hooks/useDebouncedValue.js +33 -0
- package/dist/hooks/useValueChangeEffect.js +74 -0
- package/dist/index.js +19 -0
- package/dist/settings/AdminSettingsPage.js +86 -0
- package/dist/settings/createUseSettings.js +118 -0
- package/dist/settings/index.js +20 -0
- package/dist/settings/styles/_settings-page.scss +124 -0
- package/dist/utils/constants.js +12 -0
- package/dist/utils/dates.js +82 -0
- package/dist/utils/index.js +60 -0
- package/dist/utils/strings.js +41 -0
- package/dist/utils/time.js +83 -0
- package/dist/utils/wp.js +35 -0
- package/dist/webpack/createWebpackConfig.js +210 -0
- package/dist/webpack/postcss.config.js +6 -0
- package/package.json +165 -0
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _components = require("@wordpress/components");
|
|
8
|
+
var _element = require("@wordpress/element");
|
|
9
|
+
var _i18n = require("@wordpress/i18n");
|
|
10
|
+
var _Notices = _interopRequireDefault(require("../components/Notices"));
|
|
11
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
12
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
13
|
+
/**
|
|
14
|
+
* Generic admin settings page shell.
|
|
15
|
+
*
|
|
16
|
+
* Renders a header, loading placeholder, notices, body content, and a
|
|
17
|
+
* standard "Save" button wired to the `useSettings`-style API.
|
|
18
|
+
*
|
|
19
|
+
* @param {Object} props
|
|
20
|
+
* @param {string} props.title Page title.
|
|
21
|
+
* @param {string} [props.appVersion] Optional app version to display in the header.
|
|
22
|
+
* @param {Object} props.settings Object returned from a `useSettings` hook (must expose `settingsLoaded`, `settingsSaving`, `saveSettings`).
|
|
23
|
+
* @param {Function} [props.onSave] Optional override for the save handler.
|
|
24
|
+
* @param {string} [props.textDomain] Text domain for translated UI strings.
|
|
25
|
+
* @param {Function} props.children Render-prop receiving `settings` to render the form body.
|
|
26
|
+
* @return {JSX.Element}
|
|
27
|
+
*/const AdminSettingsPage = ({
|
|
28
|
+
title,
|
|
29
|
+
appVersion,
|
|
30
|
+
settings,
|
|
31
|
+
onSave,
|
|
32
|
+
textDomain = 'default',
|
|
33
|
+
children
|
|
34
|
+
}) => {
|
|
35
|
+
const {
|
|
36
|
+
settingsLoaded,
|
|
37
|
+
settingsSaving,
|
|
38
|
+
saveSettings
|
|
39
|
+
} = settings;
|
|
40
|
+
const handleSave = async event => {
|
|
41
|
+
event.preventDefault();
|
|
42
|
+
if (typeof onSave === 'function') {
|
|
43
|
+
await onSave(event);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
await saveSettings();
|
|
47
|
+
};
|
|
48
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_element.Fragment, {
|
|
49
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
50
|
+
className: "settings-header",
|
|
51
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
52
|
+
className: "settings-container",
|
|
53
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
|
|
54
|
+
className: "settings-logo",
|
|
55
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("h1", {
|
|
56
|
+
children: title
|
|
57
|
+
}), appVersion && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_components.__experimentalText, {
|
|
58
|
+
className: "version",
|
|
59
|
+
variant: "muted",
|
|
60
|
+
children: ["(v", appVersion, ")"]
|
|
61
|
+
})]
|
|
62
|
+
})
|
|
63
|
+
})
|
|
64
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
65
|
+
className: "settings-main",
|
|
66
|
+
children: !settingsLoaded ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.Placeholder, {
|
|
67
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.Spinner, {})
|
|
68
|
+
}) : /*#__PURE__*/(0, _jsxRuntime.jsxs)(_element.Fragment, {
|
|
69
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Notices.default, {}), typeof children === 'function' ? children(settings) : children, /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.__experimentalHStack, {
|
|
70
|
+
alignment: "center",
|
|
71
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.Button, {
|
|
72
|
+
variant: "primary",
|
|
73
|
+
isBusy: settingsSaving,
|
|
74
|
+
disabled: !settingsLoaded || settingsSaving,
|
|
75
|
+
isLarge: true,
|
|
76
|
+
target: "_blank",
|
|
77
|
+
href: "#",
|
|
78
|
+
onClick: handleSave,
|
|
79
|
+
children: settingsSaving ? (0, _i18n.__)('Saving...', textDomain) : (0, _i18n.__)('Save', textDomain)
|
|
80
|
+
})
|
|
81
|
+
})]
|
|
82
|
+
})
|
|
83
|
+
})]
|
|
84
|
+
});
|
|
85
|
+
};
|
|
86
|
+
var _default = exports.default = AdminSettingsPage;
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _i18n = require("@wordpress/i18n");
|
|
8
|
+
var _element = require("@wordpress/element");
|
|
9
|
+
var _apiFetch = _interopRequireDefault(require("@wordpress/api-fetch"));
|
|
10
|
+
var _data = require("@wordpress/data");
|
|
11
|
+
var _notices = require("@wordpress/notices");
|
|
12
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
13
|
+
/**
|
|
14
|
+
* Create a `useSettings` hook for a plugin.
|
|
15
|
+
*
|
|
16
|
+
* Reads/writes settings via the WordPress core REST settings endpoint
|
|
17
|
+
* (`/wp/v2/settings`), keyed by `optionName`. Each entry in `fields`
|
|
18
|
+
* defines a field with `key` (option key), optional `defaultValue`, and
|
|
19
|
+
* optional state name overrides.
|
|
20
|
+
*
|
|
21
|
+
* @param {Object} config Hook configuration.
|
|
22
|
+
* @param {string} config.optionName Top-level option key on the settings endpoint.
|
|
23
|
+
* @param {Array} config.fields Field definitions: `{ key, defaultValue, stateName, setterName }`.
|
|
24
|
+
* @param {string} [config.textDomain] Text domain for translated notice strings.
|
|
25
|
+
* @param {string} [config.path] REST path (default: '/wp/v2/settings').
|
|
26
|
+
* @return {Function} A `useSettings` React hook.
|
|
27
|
+
*/
|
|
28
|
+
const createUseSettings = config => {
|
|
29
|
+
const {
|
|
30
|
+
optionName,
|
|
31
|
+
fields = [],
|
|
32
|
+
textDomain = 'default',
|
|
33
|
+
path = '/wp/v2/settings'
|
|
34
|
+
} = config;
|
|
35
|
+
if (!optionName) {
|
|
36
|
+
throw new Error('[wp-plugin-utils] createUseSettings: "optionName" is required.');
|
|
37
|
+
}
|
|
38
|
+
const toCamel = key => key.replace(/[_-](.)/g, (_m, c) => c.toUpperCase());
|
|
39
|
+
const ucFirst = s => s.charAt(0).toUpperCase() + s.slice(1);
|
|
40
|
+
return function useSettings() {
|
|
41
|
+
const {
|
|
42
|
+
createSuccessNotice,
|
|
43
|
+
createErrorNotice
|
|
44
|
+
} = (0, _data.useDispatch)(_notices.store);
|
|
45
|
+
const [settingsLoaded, updateSettingsLoaded] = (0, _element.useState)(false);
|
|
46
|
+
const [settingsSaving, updateSettingsSaving] = (0, _element.useState)(false);
|
|
47
|
+
const initialState = {};
|
|
48
|
+
fields.forEach(field => {
|
|
49
|
+
const stateName = field.stateName || toCamel(field.key);
|
|
50
|
+
initialState[stateName] = field.defaultValue !== undefined ? field.defaultValue : '';
|
|
51
|
+
});
|
|
52
|
+
const [values, setValues] = (0, _element.useState)(initialState);
|
|
53
|
+
const setField = stateName => value => {
|
|
54
|
+
setValues(prev => ({
|
|
55
|
+
...prev,
|
|
56
|
+
[stateName]: value
|
|
57
|
+
}));
|
|
58
|
+
};
|
|
59
|
+
(0, _element.useEffect)(() => {
|
|
60
|
+
(0, _apiFetch.default)({
|
|
61
|
+
path
|
|
62
|
+
}).then(settings => {
|
|
63
|
+
const optionData = settings[optionName] || {};
|
|
64
|
+
const next = {
|
|
65
|
+
...initialState
|
|
66
|
+
};
|
|
67
|
+
fields.forEach(field => {
|
|
68
|
+
const stateName = field.stateName || toCamel(field.key);
|
|
69
|
+
if (optionData[field.key] !== undefined) {
|
|
70
|
+
next[stateName] = optionData[field.key];
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
setValues(next);
|
|
74
|
+
updateSettingsLoaded(true);
|
|
75
|
+
});
|
|
76
|
+
}, []);
|
|
77
|
+
const saveSettings = async () => {
|
|
78
|
+
updateSettingsSaving(true);
|
|
79
|
+
const optionData = {};
|
|
80
|
+
fields.forEach(field => {
|
|
81
|
+
const stateName = field.stateName || toCamel(field.key);
|
|
82
|
+
optionData[field.key] = values[stateName];
|
|
83
|
+
});
|
|
84
|
+
const saveResult = await (0, _apiFetch.default)({
|
|
85
|
+
path,
|
|
86
|
+
method: 'POST',
|
|
87
|
+
data: {
|
|
88
|
+
[optionName]: optionData
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
if (!saveResult) {
|
|
92
|
+
updateSettingsSaving(false);
|
|
93
|
+
createErrorNotice((0, _i18n.sprintf)(/* translators: %s: Error message. */
|
|
94
|
+
(0, _i18n.__)('Error saving settings: %s.', textDomain), saveResult?.message ?? (0, _i18n.__)('Unknown error', textDomain)));
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
updateSettingsSaving(false);
|
|
98
|
+
createSuccessNotice((0, _i18n.__)('Settings saved.', textDomain));
|
|
99
|
+
};
|
|
100
|
+
const exposed = {
|
|
101
|
+
settingsLoaded,
|
|
102
|
+
updateSettingsLoaded,
|
|
103
|
+
settingsSaving,
|
|
104
|
+
updateSettingsSaving,
|
|
105
|
+
values,
|
|
106
|
+
setValues,
|
|
107
|
+
saveSettings
|
|
108
|
+
};
|
|
109
|
+
fields.forEach(field => {
|
|
110
|
+
const stateName = field.stateName || toCamel(field.key);
|
|
111
|
+
const setterName = field.setterName || `update${ucFirst(stateName)}`;
|
|
112
|
+
exposed[stateName] = values[stateName];
|
|
113
|
+
exposed[setterName] = setField(stateName);
|
|
114
|
+
});
|
|
115
|
+
return exposed;
|
|
116
|
+
};
|
|
117
|
+
};
|
|
118
|
+
var _default = exports.default = createUseSettings;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
Object.defineProperty(exports, "AdminSettingsPage", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function () {
|
|
9
|
+
return _AdminSettingsPage.default;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
Object.defineProperty(exports, "createUseSettings", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function () {
|
|
15
|
+
return _createUseSettings.default;
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
var _createUseSettings = _interopRequireDefault(require("./createUseSettings"));
|
|
19
|
+
var _AdminSettingsPage = _interopRequireDefault(require("./AdminSettingsPage"));
|
|
20
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Generic styling for the wp-plugin-utils AdminSettingsPage shell.
|
|
3
|
+
*
|
|
4
|
+
* Wrap with the WordPress settings page selector for the plugin, e.g.:
|
|
5
|
+
*
|
|
6
|
+
* .settings_page_my-plugin-settings {
|
|
7
|
+
* @include de-wp-plugin-utils-settings-page;
|
|
8
|
+
* }
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
@mixin de-wp-plugin-utils-settings-page {
|
|
12
|
+
background: #f6f6f6;
|
|
13
|
+
position: relative;
|
|
14
|
+
box-sizing: border-box;
|
|
15
|
+
|
|
16
|
+
.components-placeholder {
|
|
17
|
+
background: #FFFFFF;
|
|
18
|
+
margin-top: 25px;
|
|
19
|
+
border: 1px solid #e2e4e7;
|
|
20
|
+
box-shadow: none;
|
|
21
|
+
|
|
22
|
+
.components-placeholder__fieldset {
|
|
23
|
+
justify-content: center;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.settings-header {
|
|
28
|
+
padding: 20px 10px;
|
|
29
|
+
background-color: #ffffff;
|
|
30
|
+
box-shadow: 0 1px 0 rgba(213, 213, 213, 0.5), 0 1px 2px #eee;
|
|
31
|
+
|
|
32
|
+
.settings-container {
|
|
33
|
+
margin: 0 auto;
|
|
34
|
+
max-width: 900px;
|
|
35
|
+
|
|
36
|
+
.settings-logo {
|
|
37
|
+
display: flex;
|
|
38
|
+
flex-direction: column;
|
|
39
|
+
align-items: center;
|
|
40
|
+
justify-content: center;
|
|
41
|
+
|
|
42
|
+
h1 {
|
|
43
|
+
display: flex;
|
|
44
|
+
flex-direction: row;
|
|
45
|
+
align-items: center;
|
|
46
|
+
justify-content: center;
|
|
47
|
+
margin: 0.6rem;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.version {
|
|
51
|
+
font-size: 12px;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.settings-main {
|
|
58
|
+
margin-left: auto;
|
|
59
|
+
margin-right: auto;
|
|
60
|
+
max-width: 1440px;
|
|
61
|
+
|
|
62
|
+
.components-panel__body {
|
|
63
|
+
margin: 25px 0;
|
|
64
|
+
background: #fff;
|
|
65
|
+
border: 1px solid #e2e4e7;
|
|
66
|
+
|
|
67
|
+
.components-panel__body-toggle {
|
|
68
|
+
border-bottom: 1px solid #d6e2ed;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.field-divider {
|
|
72
|
+
border-color: #cbd5e1;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.components-panel__row {
|
|
76
|
+
margin: 0;
|
|
77
|
+
width: 100%;
|
|
78
|
+
|
|
79
|
+
&.field-row {
|
|
80
|
+
padding: 1.0rem 0;
|
|
81
|
+
|
|
82
|
+
.components-base-control {
|
|
83
|
+
width: 100%;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.checkbox-group {
|
|
87
|
+
margin-left: 1.0rem;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
&.buttons-row {
|
|
92
|
+
justify-content: center;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.settings-info {
|
|
98
|
+
padding: 0 10px 10px;
|
|
99
|
+
|
|
100
|
+
h2 {
|
|
101
|
+
font-weight: 300;
|
|
102
|
+
margin-bottom: 10px;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
p {
|
|
106
|
+
margin: 0 0 1.5em 0;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
.settings-info-button-group {
|
|
110
|
+
display: flex;
|
|
111
|
+
|
|
112
|
+
.is-default {
|
|
113
|
+
padding: 2px 20px;
|
|
114
|
+
height: auto;
|
|
115
|
+
font-size: 14px;
|
|
116
|
+
|
|
117
|
+
&:first-child {
|
|
118
|
+
margin-right: 15px;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.SHOW_MIGRATION_ID_IN_PREVIOUS_MIGRATIONS_SELECT = exports.SHOW_CANCEL_ALL_MIGRATIONS_BUTTON = exports.MIGRATION_RESULTS_PER_PAGE = exports.MIGRATION_ACTION_SCHEDULER_QUEUE_MODE = exports.LOG_LEVELS = exports.ALERTS_TIMEOUT = void 0;
|
|
7
|
+
const ALERTS_TIMEOUT = exports.ALERTS_TIMEOUT = 10000;
|
|
8
|
+
const MIGRATION_RESULTS_PER_PAGE = exports.MIGRATION_RESULTS_PER_PAGE = 100;
|
|
9
|
+
const SHOW_CANCEL_ALL_MIGRATIONS_BUTTON = exports.SHOW_CANCEL_ALL_MIGRATIONS_BUTTON = false;
|
|
10
|
+
const SHOW_MIGRATION_ID_IN_PREVIOUS_MIGRATIONS_SELECT = exports.SHOW_MIGRATION_ID_IN_PREVIOUS_MIGRATIONS_SELECT = false;
|
|
11
|
+
const LOG_LEVELS = exports.LOG_LEVELS = ['emergency', 'alert', 'critical', 'error', 'warning', 'notice', 'info', 'debug', 'off'];
|
|
12
|
+
const MIGRATION_ACTION_SCHEDULER_QUEUE_MODE = exports.MIGRATION_ACTION_SCHEDULER_QUEUE_MODE = ['async', 'scheduled'];
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.convertUTCMySQLDateTimeToLocalTime = exports.convertUTCMySQLDateTimeToLocalDateTime = exports.convertTimestampToFriendlyTime = exports.convertTimestampToFriendlyDate = void 0;
|
|
7
|
+
var _i18n = require("@wordpress/i18n");
|
|
8
|
+
/**
|
|
9
|
+
* Convert a timestamp to a human readable date format, using toLocaleString.
|
|
10
|
+
*
|
|
11
|
+
* @param {number|string} timestamp Unix timestamp (seconds).
|
|
12
|
+
* @param {string} [textDomain='default']
|
|
13
|
+
* @return {string}
|
|
14
|
+
*/
|
|
15
|
+
const convertTimestampToFriendlyDate = (timestamp, textDomain = 'default') => {
|
|
16
|
+
if (!timestamp) {
|
|
17
|
+
return (0, _i18n.__)('N/A', textDomain);
|
|
18
|
+
}
|
|
19
|
+
const date = new Date(Number(timestamp) * 1000);
|
|
20
|
+
const options = {
|
|
21
|
+
dateStyle: 'full',
|
|
22
|
+
timeStyle: 'short'
|
|
23
|
+
};
|
|
24
|
+
return date.toLocaleString(undefined, options);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Convert a timestamp to a human readable time format, using toLocaleTimeString.
|
|
29
|
+
*
|
|
30
|
+
* @param {number} timestamp Unix timestamp (seconds).
|
|
31
|
+
* @param {string} [textDomain='default']
|
|
32
|
+
* @return {string}
|
|
33
|
+
*/
|
|
34
|
+
exports.convertTimestampToFriendlyDate = convertTimestampToFriendlyDate;
|
|
35
|
+
const convertTimestampToFriendlyTime = (timestamp, textDomain = 'default') => {
|
|
36
|
+
if (!timestamp) {
|
|
37
|
+
return (0, _i18n.__)('N/A', textDomain);
|
|
38
|
+
}
|
|
39
|
+
const date = new Date(timestamp * 1000);
|
|
40
|
+
const options = {
|
|
41
|
+
timeStyle: 'short'
|
|
42
|
+
};
|
|
43
|
+
return date.toLocaleTimeString(undefined, options);
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Convert a UTC MySQL DateTime to a local date time.
|
|
48
|
+
*
|
|
49
|
+
* @param {string} utcDateTime UTC MySQL DateTime.
|
|
50
|
+
* @return {string}
|
|
51
|
+
*/
|
|
52
|
+
exports.convertTimestampToFriendlyTime = convertTimestampToFriendlyTime;
|
|
53
|
+
const convertUTCMySQLDateTimeToLocalDateTime = utcDateTime => {
|
|
54
|
+
if (!utcDateTime) {
|
|
55
|
+
return '';
|
|
56
|
+
}
|
|
57
|
+
const localDate = new Date(utcDateTime + 'Z');
|
|
58
|
+
const options = {
|
|
59
|
+
dateStyle: 'full',
|
|
60
|
+
timeStyle: 'short'
|
|
61
|
+
};
|
|
62
|
+
return localDate.toLocaleString(undefined, options);
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Convert a UTC MySQL DateTime to a local time.
|
|
67
|
+
*
|
|
68
|
+
* @param {string} utcDateTime UTC MySQL DateTime.
|
|
69
|
+
* @return {string}
|
|
70
|
+
*/
|
|
71
|
+
exports.convertUTCMySQLDateTimeToLocalDateTime = convertUTCMySQLDateTimeToLocalDateTime;
|
|
72
|
+
const convertUTCMySQLDateTimeToLocalTime = utcDateTime => {
|
|
73
|
+
if (!utcDateTime) {
|
|
74
|
+
return '';
|
|
75
|
+
}
|
|
76
|
+
const localDate = new Date(utcDateTime + 'Z');
|
|
77
|
+
const options = {
|
|
78
|
+
timeStyle: 'short'
|
|
79
|
+
};
|
|
80
|
+
return localDate.toLocaleTimeString(undefined, options);
|
|
81
|
+
};
|
|
82
|
+
exports.convertUTCMySQLDateTimeToLocalTime = convertUTCMySQLDateTimeToLocalTime;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
var _constants = require("./constants");
|
|
7
|
+
Object.keys(_constants).forEach(function (key) {
|
|
8
|
+
if (key === "default" || key === "__esModule") return;
|
|
9
|
+
if (key in exports && exports[key] === _constants[key]) return;
|
|
10
|
+
Object.defineProperty(exports, key, {
|
|
11
|
+
enumerable: true,
|
|
12
|
+
get: function () {
|
|
13
|
+
return _constants[key];
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
var _strings = require("./strings");
|
|
18
|
+
Object.keys(_strings).forEach(function (key) {
|
|
19
|
+
if (key === "default" || key === "__esModule") return;
|
|
20
|
+
if (key in exports && exports[key] === _strings[key]) return;
|
|
21
|
+
Object.defineProperty(exports, key, {
|
|
22
|
+
enumerable: true,
|
|
23
|
+
get: function () {
|
|
24
|
+
return _strings[key];
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
var _time = require("./time");
|
|
29
|
+
Object.keys(_time).forEach(function (key) {
|
|
30
|
+
if (key === "default" || key === "__esModule") return;
|
|
31
|
+
if (key in exports && exports[key] === _time[key]) return;
|
|
32
|
+
Object.defineProperty(exports, key, {
|
|
33
|
+
enumerable: true,
|
|
34
|
+
get: function () {
|
|
35
|
+
return _time[key];
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
var _dates = require("./dates");
|
|
40
|
+
Object.keys(_dates).forEach(function (key) {
|
|
41
|
+
if (key === "default" || key === "__esModule") return;
|
|
42
|
+
if (key in exports && exports[key] === _dates[key]) return;
|
|
43
|
+
Object.defineProperty(exports, key, {
|
|
44
|
+
enumerable: true,
|
|
45
|
+
get: function () {
|
|
46
|
+
return _dates[key];
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
var _wp = require("./wp");
|
|
51
|
+
Object.keys(_wp).forEach(function (key) {
|
|
52
|
+
if (key === "default" || key === "__esModule") return;
|
|
53
|
+
if (key in exports && exports[key] === _wp[key]) return;
|
|
54
|
+
Object.defineProperty(exports, key, {
|
|
55
|
+
enumerable: true,
|
|
56
|
+
get: function () {
|
|
57
|
+
return _wp[key];
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
});
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.zeroPadNumber = exports.trimTrailingSlash = exports.capitalizeFirstLetter = void 0;
|
|
7
|
+
/**
|
|
8
|
+
* Capitalize the first letter of every word.
|
|
9
|
+
*
|
|
10
|
+
* @param {string} string String.
|
|
11
|
+
* @return {string}
|
|
12
|
+
*/
|
|
13
|
+
const capitalizeFirstLetter = string => {
|
|
14
|
+
return string.toLowerCase().replace(/\b[a-z]/g, letter => {
|
|
15
|
+
return letter.toUpperCase();
|
|
16
|
+
});
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Trim the trailing slash from a string.
|
|
21
|
+
*
|
|
22
|
+
* @param {string} string String.
|
|
23
|
+
* @return {string}
|
|
24
|
+
*/
|
|
25
|
+
exports.capitalizeFirstLetter = capitalizeFirstLetter;
|
|
26
|
+
const trimTrailingSlash = string => {
|
|
27
|
+
return string.replace(/\/$/, '');
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Add leading zeroes to a number.
|
|
32
|
+
*
|
|
33
|
+
* @param {number} num Number.
|
|
34
|
+
* @param {number} places Total places.
|
|
35
|
+
* @return {string}
|
|
36
|
+
*/
|
|
37
|
+
exports.trimTrailingSlash = trimTrailingSlash;
|
|
38
|
+
const zeroPadNumber = (num, places) => {
|
|
39
|
+
return String(num).padStart(places, '0');
|
|
40
|
+
};
|
|
41
|
+
exports.zeroPadNumber = zeroPadNumber;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.secondsToDhmsShortIso = exports.secondsToDhmsShort = exports.secondsToDhms = exports.addSecondsToCurrentTime = void 0;
|
|
7
|
+
var _strings = require("./strings");
|
|
8
|
+
/**
|
|
9
|
+
* Convert seconds to a human readable format.
|
|
10
|
+
* Example: "3 days, 11 hours, 2 minutes, 58 seconds".
|
|
11
|
+
*
|
|
12
|
+
* @param {number} seconds Seconds remaining.
|
|
13
|
+
* @return {string|false}
|
|
14
|
+
*/
|
|
15
|
+
const secondsToDhms = seconds => {
|
|
16
|
+
if (seconds <= 0) {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
seconds = Number(seconds);
|
|
20
|
+
const d = Math.floor(seconds / (3600 * 24));
|
|
21
|
+
const h = Math.floor(seconds % (3600 * 24) / 3600);
|
|
22
|
+
const m = Math.floor(seconds % 3600 / 60);
|
|
23
|
+
const s = Math.floor(seconds % 60);
|
|
24
|
+
const dDisplay = d > 0 ? d + (1 === d ? ' day, ' : ' days, ') : '';
|
|
25
|
+
const hDisplay = h > 0 ? h + (1 === h ? ' hour, ' : ' hours, ') : '';
|
|
26
|
+
const mDisplay = m > 0 ? m + (1 === m ? ' minute, ' : ' minutes, ') : '';
|
|
27
|
+
const sDisplay = s > 0 ? s + (1 === s ? ' second' : ' seconds') : '';
|
|
28
|
+
return dDisplay + hDisplay + mDisplay + sDisplay;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Convert seconds to a human readable format, using toISOString.
|
|
33
|
+
* Example: "2:58".
|
|
34
|
+
*
|
|
35
|
+
* @param {number} seconds Seconds remaining.
|
|
36
|
+
* @return {string|false}
|
|
37
|
+
*/
|
|
38
|
+
exports.secondsToDhms = secondsToDhms;
|
|
39
|
+
const secondsToDhmsShortIso = seconds => {
|
|
40
|
+
if (seconds <= 0) {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
if (seconds < 3600) {
|
|
44
|
+
return new Date(seconds * 1000).toISOString().substring(14, 19);
|
|
45
|
+
}
|
|
46
|
+
return new Date(seconds * 1000).toISOString().substring(11, 16);
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Convert seconds to a human readable format, but a bit shorter.
|
|
51
|
+
* Example: "11:02:59".
|
|
52
|
+
*
|
|
53
|
+
* @param {number} seconds Seconds remaining.
|
|
54
|
+
* @return {string|false}
|
|
55
|
+
*/
|
|
56
|
+
exports.secondsToDhmsShortIso = secondsToDhmsShortIso;
|
|
57
|
+
const secondsToDhmsShort = seconds => {
|
|
58
|
+
if (seconds <= 0) {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
seconds = Number(seconds);
|
|
62
|
+
const h = Math.floor(seconds % (3600 * 24) / 3600);
|
|
63
|
+
const m = Math.floor(seconds % 3600 / 60);
|
|
64
|
+
const s = Math.floor(seconds % 60);
|
|
65
|
+
const hDisplay = h > 0 ? h + ':' : '';
|
|
66
|
+
const mDisplay = h > 0 ? (0, _strings.zeroPadNumber)(m, 2) + ':' : m > 0 ? m + ':' : (0, _strings.zeroPadNumber)(m, 1) + ':';
|
|
67
|
+
const sDisplay = seconds > 0 ? (0, _strings.zeroPadNumber)(s, 2) : '';
|
|
68
|
+
return hDisplay + mDisplay + sDisplay;
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Add a number of seconds to the current time.
|
|
73
|
+
*
|
|
74
|
+
* @param {number} seconds Seconds to add.
|
|
75
|
+
* @return {number}
|
|
76
|
+
*/
|
|
77
|
+
exports.secondsToDhmsShort = secondsToDhmsShort;
|
|
78
|
+
const addSecondsToCurrentTime = seconds => {
|
|
79
|
+
let rawDate = new Date();
|
|
80
|
+
rawDate = new Date(rawDate.getTime() + Number(seconds * 1000));
|
|
81
|
+
return rawDate.getTime() / 1000;
|
|
82
|
+
};
|
|
83
|
+
exports.addSecondsToCurrentTime = addSecondsToCurrentTime;
|
package/dist/utils/wp.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.wpEditPostLinkFromPostId = exports.getAdminPageUrl = void 0;
|
|
7
|
+
var _url = require("@wordpress/url");
|
|
8
|
+
/**
|
|
9
|
+
* Get a URL to edit a post with a post ID.
|
|
10
|
+
*
|
|
11
|
+
* @param {number} postID Post ID.
|
|
12
|
+
* @param {string} adminUrl WP admin URL (with trailing slash).
|
|
13
|
+
* @return {string}
|
|
14
|
+
*/
|
|
15
|
+
const wpEditPostLinkFromPostId = (postID, adminUrl) => {
|
|
16
|
+
return (0, _url.addQueryArgs)(`${adminUrl}post.php`, {
|
|
17
|
+
post: postID,
|
|
18
|
+
action: 'edit'
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Build an admin page URL.
|
|
24
|
+
*
|
|
25
|
+
* @param {string} page Admin page slug.
|
|
26
|
+
* @param {string} [parent='admin.php'] Parent admin file.
|
|
27
|
+
* @return {string}
|
|
28
|
+
*/
|
|
29
|
+
exports.wpEditPostLinkFromPostId = wpEditPostLinkFromPostId;
|
|
30
|
+
const getAdminPageUrl = (page, parent = 'admin.php') => {
|
|
31
|
+
return (0, _url.addQueryArgs)(parent, {
|
|
32
|
+
page
|
|
33
|
+
});
|
|
34
|
+
};
|
|
35
|
+
exports.getAdminPageUrl = getAdminPageUrl;
|