querysub 0.695.0 → 0.696.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "querysub",
3
- "version": "0.695.0",
3
+ "version": "0.696.0",
4
4
  "main": "index.js",
5
5
  "license": "MIT",
6
6
  "note1": "note on node-forge fork, see https://github.com/digitalbazaar/forge/issues/744 for details",
@@ -106,22 +106,59 @@ export function confirmNoOverlapDeploy(actionLabel: string, onConfirm: () => voi
106
106
  });
107
107
  }
108
108
 
109
+ const CONFIRM_LIST_MAX_HEIGHT = 220;
110
+
111
+ /** Deploying every outdated service restarts all of them at once, which is most of the cluster — worth naming what is about to restart before it happens. */
112
+ class DeployAllConfirmModal extends qreact.Component<{ titles: string[]; latestRef: string; onConfirm: () => void }> {
113
+ render() {
114
+ let count = this.props.titles.length;
115
+ return <div className={css.vbox(14).maxWidth(560)}>
116
+ <div className={css.fontSize(18).boldStyle}>Deploy {count} service{count === 1 && "" || "s"}?</div>
117
+ <div>
118
+ Each one restarts onto {this.props.latestRef.slice(0, 6)}. The old instances keep running for {formatTime(DEFAULT_OVERLAP_TIME)} before shutting down, so there is somewhere for connections to go while clients move across.
119
+ </div>
120
+ <div className={css.vbox(2).fillWidth.maxHeight(CONFIRM_LIST_MAX_HEIGHT).overflowAuto}>
121
+ {this.props.titles.map(title => <div>{title}</div>)}
122
+ </div>
123
+ <div className={css.hbox(10)}>
124
+ <button
125
+ className={buttonStyle.hsl(120, 70, 90)}
126
+ onClick={() => {
127
+ closeAllModals();
128
+ this.props.onConfirm();
129
+ }}
130
+ >
131
+ Deploy & Restart All ({count})
132
+ </button>
133
+ <button className={buttonStyle.hsl(0, 0, 90)} onClick={() => closeAllModals()}>
134
+ Cancel
135
+ </button>
136
+ </div>
137
+ </div>;
138
+ }
139
+ }
140
+ export function confirmDeployAll(config: { titles: string[]; latestRef: string; onConfirm: () => void }) {
141
+ showFullscreenModal({
142
+ content: <DeployAllConfirmModal titles={config.titles} latestRef={config.latestRef} onConfirm={config.onConfirm} />,
143
+ });
144
+ }
145
+
109
146
  export class UpdateButtons extends qreact.Component<{
110
147
  services: ServiceConfig[];
111
148
  }> {
112
149
  state = t.state({
113
150
  isDeploying: t.type(false),
114
151
  });
115
- // Deploys all outdated services to latestRef, always immediately. The overlap is what keeps the service up - the old instances keep running for it, so connections have somewhere to go while clients move across. noOverlap kills them at once instead.
116
- private deployAll(outdatedServices: ServiceConfig[], latestRef: string, noOverlap: boolean) {
152
+ // Deploys all outdated services to latestRef, always immediately. The overlap is what keeps the service up - the old instances keep running for it, so connections have somewhere to go while clients move across.
153
+ private deployAll(outdatedServices: ServiceConfig[], latestRef: string) {
117
154
  this.state.isDeploying = true;
118
155
  // Props are synchronized state, so everything the async work needs is cloned into plain locals HERE, in the synced part
119
156
  let toDeploy = outdatedServices.map(service => {
120
157
  let updated = deepCloneJSON(service);
121
158
  updated.parameters.gitRef = latestRef;
122
159
  updated.parameters.releaseTime = Date.now();
123
- // Always set, never inherited: the overlap belongs to the deploy being made, and leaving the previous deploy's value in place means one no-overlap deploy silently makes every later deploy a no-overlap one. A ternary, as 0 is the value we actually want here and it is falsy.
124
- updated.parameters.overlapTime = noOverlap ? 0 : DEFAULT_OVERLAP_TIME;
160
+ // Always set, never inherited: the overlap belongs to the deploy being made, and leaving the previous deploy's value in place means one no-overlap deploy silently makes every later deploy a no-overlap one.
161
+ updated.parameters.overlapTime = DEFAULT_OVERLAP_TIME;
125
162
  return updated;
126
163
  });
127
164
  let controller = MachineServiceController(SocketFunction.browserNodeId());
@@ -190,9 +227,13 @@ export class UpdateButtons extends qreact.Component<{
190
227
  <button
191
228
  className={buttonStyle.hsl(120, 70, 90)}
192
229
  disabled={this.state.isDeploying}
193
- title="Deploys now; the old instances keep running for their configured overlap before shutting down"
230
+ title="Asks first, then deploys; the old instances keep running for their configured overlap before shutting down"
194
231
  onClick={() => {
195
- this.deployAll(outdatedServices, gitInfo.latestRef, false);
232
+ confirmDeployAll({
233
+ titles: outdatedServices.map(service => service.info.title),
234
+ latestRef: gitInfo.latestRef,
235
+ onConfirm: () => this.deployAll(outdatedServices, gitInfo.latestRef),
236
+ });
196
237
  }}
197
238
  >
198
239
  <div>
@@ -207,20 +248,6 @@ export class UpdateButtons extends qreact.Component<{
207
248
  <RenderGitRefInfo gitRef={ref} />
208
249
  </div>)}
209
250
  </button>
210
- <button
211
- className={buttonStyle.hsl(0, 85, 70)}
212
- disabled={this.state.isDeploying}
213
- title="Deploys now AND shuts the old instances down as soon as the new ones are up (overlap of 0)"
214
- onClick={() => {
215
- confirmNoOverlapDeploy(`Deploy All (${outdatedServices.length}), No Overlap`, () => {
216
- this.deployAll(outdatedServices, gitInfo.latestRef, true);
217
- });
218
- }}
219
- >
220
- <div>
221
- {bigEmoji("⚡")} <span>{this.state.isDeploying && "⏳ Deploying..." || `Deploy All (${outdatedServices.length}), No Overlap`}</span>
222
- </div>
223
- </button>
224
251
  </>}
225
252
  </>;
226
253
  }