@wpmoo/toolkit 0.9.18 → 0.9.19

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.
@@ -51,36 +51,14 @@ function moduleDisabledReason(command, moduleCount) {
51
51
  function disabledReason(command, serviceStatus, moduleCount) {
52
52
  return serviceDisabledReason(command, serviceStatus) ?? moduleDisabledReason(command, moduleCount);
53
53
  }
54
- function disabledMenuReasons(serviceStatus, moduleCount) {
55
- const reasons = [];
56
- if (serviceStatus?.kind === 'docker-not-running')
57
- reasons.push('Docker not running.');
58
- if (serviceStatus?.kind === 'running')
59
- reasons.push('Already running.');
60
- if (serviceStatus?.kind === 'stopped')
61
- reasons.push('Services stopped.');
62
- if (moduleCount === 0)
63
- reasons.push('No modules found.');
64
- return reasons;
65
- }
66
- function disabledError(serviceStatus, moduleCount) {
67
- const reasons = disabledMenuReasons(serviceStatus, moduleCount);
68
- if (reasons.length === 0) {
69
- return undefined;
70
- }
71
- return [
72
- 'This option is disabled and cannot be selected.',
73
- ...reasons.map((reason) => `Reason: ${reason}`),
74
- ].join('\n');
54
+ function disabledError() {
55
+ return 'This option is disabled and cannot be selected.';
75
56
  }
76
- function moduleChoiceDisabledValue(reason) {
57
+ function commandDisabledValue(reason) {
77
58
  if (!reason) {
78
59
  return undefined;
79
60
  }
80
- return reason === 'No modules found.' ? reason : true;
81
- }
82
- function commandDisabledValue(command, serviceStatus, moduleCount) {
83
- return moduleChoiceDisabledValue(disabledReason(command, serviceStatus, moduleCount));
61
+ return reason;
84
62
  }
85
63
  function categoryChoices(category, index, serviceStatus, moduleCount) {
86
64
  const choices = [
@@ -92,7 +70,7 @@ function categoryChoices(category, index, serviceStatus, moduleCount) {
92
70
  value: command,
93
71
  name: commandName(command),
94
72
  short: command.label,
95
- disabled: commandDisabledValue(command, serviceStatus, moduleCount),
73
+ disabled: commandDisabledValue(disabledReason(command, serviceStatus, moduleCount)),
96
74
  };
97
75
  }),
98
76
  ];
@@ -148,7 +126,7 @@ export async function selectCockpitTopLevelMenu(options = {}) {
148
126
  pageSize: topLevelPageSize(choices.length),
149
127
  loop: false,
150
128
  hideMessage: true,
151
- disabledError: disabledError(options.serviceStatus, options.moduleCount),
129
+ disabledError: disabledError(),
152
130
  navigationWarning: options.navigationWarning,
153
131
  escapeBehavior: 'ignore',
154
132
  });
@@ -129,13 +129,30 @@ function renderedNavigationWarning(navigationWarning) {
129
129
  const warning = typeof navigationWarning === 'function' ? navigationWarning() : navigationWarning;
130
130
  return warning ? `\u001B[2m\u001B[38;2;226;184;96m${warning}\u001B[0m` : undefined;
131
131
  }
132
- function hiddenSelectTheme(disabledError, navigationHelp = 'exit', navigationWarning, hideMessage = true) {
132
+ function hiddenSelectTheme(disabledError, navigationHelp = 'exit', navigationWarning, hideMessage = true, disabledReasonLabels = []) {
133
+ let activeDisabledReason;
133
134
  const keysHelpTip = navigationHelp === 'back'
134
135
  ? '↑↓ navigate • ⏎ select • Esc to go back'
135
136
  : '↑↓ navigate • ⏎ select • Ctrl+C exit';
137
+ const disabledLabelPattern = / \(disabled\)$/u;
138
+ const disabledReasonSuffixes = [...disabledReasonLabels]
139
+ .sort((left, right) => right.length - left.length)
140
+ .map((reason) => ` ${reason}`);
141
+ const cursor = '\u001B[38;2;226;184;96m❯\u001B[39m';
142
+ const disabledCursor = '-';
136
143
  const style = {
137
144
  highlight: (text) => text,
138
- disabled: (text) => styleText('dim', text.replace(/ \(disabled\)$/u, ''), { validateStream: false }),
145
+ disabled: (text) => {
146
+ let renderedText = text.replace(disabledLabelPattern, '');
147
+ const reasonSuffix = disabledReasonSuffixes.find((suffix) => renderedText.endsWith(suffix));
148
+ if (reasonSuffix) {
149
+ renderedText = renderedText.slice(0, -reasonSuffix.length);
150
+ }
151
+ if (text.startsWith(`${cursor} `) || text.startsWith(`${disabledCursor} ${cursor} `)) {
152
+ activeDisabledReason = reasonSuffix?.trim();
153
+ }
154
+ return styleText('dim', renderedText, { validateStream: false });
155
+ },
139
156
  keysHelpTip: () => {
140
157
  const warning = renderedNavigationWarning(navigationWarning);
141
158
  return warning ? `${warning}\n${keysHelpTip}` : keysHelpTip;
@@ -147,12 +164,34 @@ function hiddenSelectTheme(disabledError, navigationHelp = 'exit', navigationWar
147
164
  return {
148
165
  prefix: '',
149
166
  icon: {
150
- cursor: '\u001B[38;2;226;184;96m❯\u001B[39m',
167
+ cursor,
151
168
  },
152
169
  style,
153
- i18n: disabledError ? { disabledError } : undefined,
170
+ i18n: disabledError ? disabledErrorI18n(disabledError, () => activeDisabledReason) : undefined,
154
171
  };
155
172
  }
173
+ function disabledErrorI18n(disabledError, activeReason) {
174
+ const i18n = { disabledError };
175
+ Object.defineProperty(i18n, 'disabledError', {
176
+ get: () => {
177
+ const reason = activeReason();
178
+ return reason ? `${disabledError}\nReason: ${reason}` : disabledError;
179
+ },
180
+ });
181
+ return i18n;
182
+ }
183
+ function collectDisabledReasonLabels(choices) {
184
+ const reasons = new Set();
185
+ for (const choice of choices) {
186
+ if (typeof choice === 'object' &&
187
+ choice !== null &&
188
+ 'disabled' in choice &&
189
+ typeof choice.disabled === 'string') {
190
+ reasons.add(choice.disabled);
191
+ }
192
+ }
193
+ return [...reasons];
194
+ }
156
195
  function withHiddenSelectMessage(config) {
157
196
  if (!config.hideMessage &&
158
197
  !config.disabledError &&
@@ -165,7 +204,7 @@ function withHiddenSelectMessage(config) {
165
204
  return {
166
205
  ...inquirerConfig,
167
206
  message: config.hideMessage ? '' : inquirerConfig.message,
168
- theme: hiddenSelectTheme(disabledError, navigationHelp, navigationWarning, Boolean(config.hideMessage)),
207
+ theme: hiddenSelectTheme(disabledError, navigationHelp, navigationWarning, Boolean(config.hideMessage), collectDisabledReasonLabels(inquirerConfig.choices)),
169
208
  };
170
209
  }
171
210
  function asInquirerConfirmConfig(options) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wpmoo/toolkit",
3
- "version": "0.9.18",
3
+ "version": "0.9.19",
4
4
  "description": "WPMoo Toolkit for development, staging, and production lifecycle workflows.",
5
5
  "type": "module",
6
6
  "repository": {