ui-soxo-bootstrap-core 2.6.32-dev.5 → 2.6.32-dev.6

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.
@@ -58,12 +58,7 @@ const TableComponent = ({ columns, dataSource, loading, fixed, scroll, summary,
58
58
 
59
59
  return (
60
60
  <Table
61
- title={() =>
62
- // <div style={{ fontWeight: 'bold', fontSize: 16, padding: '8px 16px' }}>
63
- title ? title : ''
64
- // </div>
65
- }
66
- // columns={updatedColumns}
61
+ title={title ? () => title : undefined}
67
62
  scroll={scroll}
68
63
  dataSource={dataSource}
69
64
  loading={loading}
@@ -32,7 +32,7 @@ const UserAdd = ({ model, callback, edit, history, formContent, match, additiona
32
32
  // for default branch
33
33
  // const [defaultBranch, setDefaultBranch] = useState(null);
34
34
  //Need to check this condition
35
- const [authentication, setAuthentication] = useState(false);
35
+ const [authentication, setAuthentication] = useState(true);
36
36
 
37
37
  /**To store user values */
38
38
  const [users, setUsers] = useState([]);
@@ -151,8 +151,10 @@ const UserAdd = ({ model, callback, edit, history, formContent, match, additiona
151
151
 
152
152
  /**if firmmas.otherdetails - 2FA == OPT, then, 2FA option will be enabled by default and editable */
153
153
  } else if (firmDetails.FA == 'USR') {
154
- setAuthentication(true);
155
-
154
+ /** If user has FA set to false , then disable authentication */
155
+ if (formContent?.FA !== undefined) {
156
+ setAuthentication(formContent?.FA);
157
+ }
156
158
  setDisabled(true);
157
159
 
158
160
  /**if firmmas.otherdetails - 2FA == NAP, then, 2FA option will be disabled by default and read-only*/
@@ -161,10 +163,6 @@ const UserAdd = ({ model, callback, edit, history, formContent, match, additiona
161
163
 
162
164
  setDisabled(true);
163
165
  }
164
- /** If user has FA set to false , then disable authentication */
165
- if (formContent?.FA === false) {
166
- setAuthentication(false);
167
- }
168
166
  }
169
167
  }, []);
170
168
 
@@ -387,7 +385,8 @@ const UserAdd = ({ model, callback, edit, history, formContent, match, additiona
387
385
  ...values,
388
386
  auth_type: 'LDAP',
389
387
  mobile: mobileWithCountryCode,
390
- FA: authentication,
388
+ FA: formContent?.FA === false ? false : authentication,
389
+
391
390
  };
392
391
 
393
392
  setLoading(true);
@@ -400,7 +399,7 @@ const UserAdd = ({ model, callback, edit, history, formContent, match, additiona
400
399
  addAllBranches: props.ldap.addAllBranches,
401
400
  auth_user: selectedOption.value,
402
401
  auth_type: 'LDAP',
403
- FA: authentication,
402
+ FA: formContent?.FA === false ? false : authentication,
404
403
  };
405
404
  }
406
405
 
@@ -292,6 +292,7 @@ export default function ProcessStepsPage({ match, CustomComponents = {}, ...prop
292
292
  const [steps, setSteps] = useState([]);
293
293
  const [processName, setProcessName] = useState(null);
294
294
  const [activeStep, setActiveStep] = useState(0);
295
+ const [resumableStep, setResumableStep] = useState(null);
295
296
  const [isStepCompleted, setIsStepCompleted] = useState(false);
296
297
 
297
298
  const [nextProcessId, setNextProcessId] = useState(null);
@@ -353,11 +354,46 @@ export default function ProcessStepsPage({ match, CustomComponents = {}, ...prop
353
354
 
354
355
  setProcessTimings(savedTimings);
355
356
 
357
+ let savedActiveStep = 0;
358
+ try {
359
+ const rawStep = localStorage.getItem(`processActiveStep_${currentProcessId}`);
360
+ const parsedStep = rawStep == null ? NaN : parseInt(rawStep, 10);
361
+ if (Number.isFinite(parsedStep) && parsedStep > 0) {
362
+ savedActiveStep = parsedStep;
363
+ }
364
+ } catch (error) {
365
+ console.warn('Unable to restore active step from local storage.', error);
366
+ }
367
+ setResumableStep(savedActiveStep > 0 ? savedActiveStep : null);
368
+
356
369
  setProcessStartTime(Date.now());
357
370
  setStepStartTime(Date.now());
358
371
  setShowNextProcessAction(false);
359
372
  }, [currentProcessId]);
360
373
 
374
+ /**
375
+ * Persist the active step so an unexpected exit (refresh, tab close, crash)
376
+ * can offer a Resume action on the next mount. Only steps beyond the first
377
+ * are persisted — step 0 is the natural entry point and does not need a
378
+ * resume marker. The marker is cleared on successful process submission and
379
+ * when the user explicitly dismisses the resume banner.
380
+ */
381
+ useEffect(() => {
382
+ if (typeof window === 'undefined' || !window.localStorage || !currentProcessId) {
383
+ return;
384
+ }
385
+
386
+ if (activeStep <= 0) {
387
+ return;
388
+ }
389
+
390
+ try {
391
+ localStorage.setItem(`processActiveStep_${currentProcessId}`, String(activeStep));
392
+ } catch (error) {
393
+ console.warn('Unable to persist active step to local storage.', error);
394
+ }
395
+ }, [activeStep, currentProcessId]);
396
+
361
397
  /**
362
398
  * Sync the loaded process name into the address bar.
363
399
  * - Mirrors `processName` into a `process` query parameter so deep-links and
@@ -599,10 +635,12 @@ export default function ProcessStepsPage({ match, CustomComponents = {}, ...prop
599
635
  if (response.success) {
600
636
  try {
601
637
  localStorage.removeItem(`processTimings_${currentProcessId}`);
638
+ localStorage.removeItem(`processActiveStep_${currentProcessId}`);
602
639
  } catch (error) {
603
640
  console.warn('Unable to clear process timings from local storage.', error);
604
641
  }
605
642
  setProcessTimings([]);
643
+ setResumableStep(null);
606
644
  return true;
607
645
  }
608
646
  } catch (e) {
@@ -659,6 +697,33 @@ export default function ProcessStepsPage({ match, CustomComponents = {}, ...prop
659
697
  * - Records timing data for the current step.
660
698
  */
661
699
  const handleTimelineClick = (i) => gotoStep(i);
700
+ /**
701
+ * Resume Handlers
702
+ * - `handleResume` jumps to the persisted step (clamped to current step
703
+ * range) so a returning user picks up where they left off.
704
+ * - `dismissResume` discards the saved marker so the banner does not appear
705
+ * again for this process.
706
+ */
707
+ const handleResume = () => {
708
+ if (resumableStep == null || !steps.length) {
709
+ return;
710
+ }
711
+ const target = Math.max(0, Math.min(resumableStep, steps.length - 1));
712
+ setResumableStep(null);
713
+ if (target !== activeStep) {
714
+ gotoStep(target);
715
+ }
716
+ };
717
+ const dismissResume = () => {
718
+ setResumableStep(null);
719
+ try {
720
+ if (typeof window !== 'undefined' && window.localStorage && currentProcessId) {
721
+ localStorage.removeItem(`processActiveStep_${currentProcessId}`);
722
+ }
723
+ } catch (error) {
724
+ console.warn('Unable to clear resume marker from local storage.', error);
725
+ }
726
+ };
662
727
  /**
663
728
  * Process Completion
664
729
  * - Records final step timing.
@@ -1425,6 +1490,33 @@ export default function ProcessStepsPage({ match, CustomComponents = {}, ...prop
1425
1490
  </div>
1426
1491
  </div>
1427
1492
 
1493
+ {/*
1494
+ Resume banner.
1495
+ - Renders only when a saved active step is ahead of the current
1496
+ position, so it stays out of the way during normal navigation
1497
+ and only surfaces when the user returns after an unexpected
1498
+ exit (refresh, tab close, navigation away).
1499
+ - Resuming clamps to the current step range; dismissing clears
1500
+ the persisted marker so the banner does not return for this
1501
+ process.
1502
+ */}
1503
+ {resumableStep != null && resumableStep > activeStep && resumableStep < steps.length ? (
1504
+ <div className="steps-resume-banner" role="status">
1505
+ <span className="steps-resume-banner-text">
1506
+ You left at Step {resumableStep + 1}
1507
+ {steps[resumableStep]?.step_name ? ` — ${steps[resumableStep].step_name}` : ''}.
1508
+ </span>
1509
+ <div className="steps-resume-banner-actions">
1510
+ <Button type="primary" size="small" onClick={handleResume}>
1511
+ Resume
1512
+ </Button>
1513
+ <Button type="text" size="small" onClick={dismissResume}>
1514
+ Dismiss
1515
+ </Button>
1516
+ </div>
1517
+ </div>
1518
+ ) : null}
1519
+
1428
1520
  <div className={`steps-content-panel${isStepFullscreen ? ' is-fullscreen' : ''}`}>
1429
1521
  {/*
1430
1522
  Stage body:
@@ -212,6 +212,37 @@
212
212
  height: 3px;
213
213
  }
214
214
 
215
+ /* ── Resume banner ──────────────────────────────────────── */
216
+
217
+ .steps-resume-banner {
218
+ flex: 0 0 auto;
219
+ display: flex;
220
+ align-items: center;
221
+ justify-content: space-between;
222
+ gap: 12px;
223
+ padding: 8px 14px;
224
+ background: #fff8e1;
225
+ border-bottom: 1px solid #f5e3a3;
226
+ color: #5b4400;
227
+ font-size: 13px;
228
+ font-weight: 500;
229
+ }
230
+
231
+ .steps-resume-banner-text {
232
+ flex: 1 1 auto;
233
+ min-width: 0;
234
+ overflow: hidden;
235
+ text-overflow: ellipsis;
236
+ white-space: nowrap;
237
+ }
238
+
239
+ .steps-resume-banner-actions {
240
+ flex: 0 0 auto;
241
+ display: flex;
242
+ align-items: center;
243
+ gap: 6px;
244
+ }
245
+
215
246
  .steps-breadcrumb-strip::-webkit-scrollbar-track {
216
247
  background: transparent;
217
248
  }
@@ -474,13 +505,17 @@
474
505
 
475
506
  @media (prefers-reduced-motion: reduce) {
476
507
  .steps-touch-nav {
477
- transition: opacity 120ms linear, visibility 0s linear 120ms;
508
+ transition:
509
+ opacity 120ms linear,
510
+ visibility 0s linear 120ms;
478
511
  transform: translateY(-50%);
479
512
  }
480
513
 
481
514
  .steps-touch-nav.is-visible {
482
515
  transform: translateY(-50%);
483
- transition: opacity 120ms linear, visibility 0s linear 0s;
516
+ transition:
517
+ opacity 120ms linear,
518
+ visibility 0s linear 0s;
484
519
  }
485
520
 
486
521
  .steps-touch-nav.is-visible:not(:disabled)::before {
@@ -635,7 +670,7 @@
635
670
  }
636
671
 
637
672
  .steps-chat-step-component {
638
- margin-top: 10px;
673
+ // margin-top: 10px;
639
674
  display: flex;
640
675
  flex: 1 1 auto;
641
676
  flex-direction: column;
@@ -730,14 +765,14 @@
730
765
 
731
766
  .steps-viewport:fullscreen .steps-stage-body,
732
767
  .steps-viewport:-webkit-full-screen .steps-stage-body {
733
- padding: 6px;
768
+ padding: 3px;
734
769
  }
735
770
 
736
771
  /* ── Small laptops (13" / 1366px and below) ─────────────── */
737
772
 
738
773
  @media (max-width: 1366px) {
739
774
  .steps-top-bar {
740
- padding: 6px 10px;
775
+ // padding: 6px 10px;
741
776
  gap: 6px;
742
777
  }
743
778
 
@@ -768,7 +803,7 @@
768
803
  }
769
804
 
770
805
  .steps-chat-step-card {
771
- padding: 12px 14px;
806
+ padding: 9px;
772
807
  }
773
808
 
774
809
  .steps-title {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ui-soxo-bootstrap-core",
3
- "version": "2.6.32-dev.5",
3
+ "version": "2.6.32-dev.6",
4
4
  "description": "All the Core Components for you to start",
5
5
  "keywords": [
6
6
  "all in one"