Skip to content

Notices with the code of an error, and a loading that never gets stuck

Choose a tag to compare

@uatisdeproblem uatisdeproblem released this 02 Oct 17:56
· 33 commits to main since this release

New features

  • Common. Every message is a notice. IDEAMessageService no longer uses ion-toast: a new component (idea-notices) takes its look from the app's Ionic tokens, dark mode included.

    • Notices are stacked at the bottom, at the bottom-right corner on a wide screen, at most 3 at a time.
    • They close by themselves after 3, 5 or 10 seconds, pausing while pointed or focused.
    • Refinable with --idea-notice-background, --idea-notice-border-radius, --idea-notice-width.
  • Common. The code of an unhandled back-end error. The error IDEAApiService throws carries the requestId the back-end adds to the errors it didn't handle (IDEAApiError.requestId, idea-aws >= 4.8.0). Pass it to the message, and the user sees the whole code, with a button to copy it and a sentence asking to report it: the code leads to the log line with the real cause.

    this._message.error('COMMON.OPERATION_FAILED', { requestId: error.requestId });
  • Common. Messages that stay. With persistent, a message stays until the user closes it, with its own closeText and an onClose callback. The app-status announcements use it instead of their own toast.

  • Common. A loading that blocks at once, never flashes, never gets stuck. IDEALoadingService keeps its API but counts the waits, so the app is free at the last hide():

    • nested show()/hide() work, and a hide() that comes early cancels the wait;
    • the app is blocked from the call, but the wait shows only after 250 ms and stays at least 500 ms;
    • from 8.14.1, a notice that comes during the wait, or once it is over, takes its place: the wait doesn't stay its 500 ms next to it (e.g. a quick save and its success);
    • after 8 seconds, a second line says it's taking longer than usual.
  • Common. The panel of a long task. show(options) returns a task that shows its steps (step(), with their duration), its progress (progress()), an error with the code to copy (fail()), and a Cancel button. Cancel triggers task.cancelled, an AbortSignal that IDEAApiService now accepts as signal.

Behaviour changes for older versions

No code change is required, but:

  • messages and waits look different, and the module no longer uses ion-toast and ion-loading: app CSS aimed at them (e.g. ion-toast.toastWithServerMessage) no longer applies;
  • the waits are counted: an extra hide() inside a nested block now closes the outer wait early, where it used to leave an overlay on screen;
  • IDEAAppStatusService.check()'s toastColor and toastPosition are deprecated and ignored;
  • a cancelled request (signal) doesn't count as a back-end failure for the app status.

How to adopt the new version

  1. Update @idea-ionic/common to 8.14.0 and copy the IDEA_COMMON translations again: there are new terms in MESSAGE.* and LOADING.*.

  2. Wherever you show the error of an API request, pass requestId: error.requestId. Keep serverMessage only where the back-end explains something the user can act on: with a requestId it isn't shown, being the back-end's generic message.

  3. Optional. Show long tasks with the panel:

    const task = await this._loading.show({ message: 'IMPORT.TITLE', steps: ['IMPORT.READ', 'IMPORT.SAVE'], cancelable: true });
    try {
      task.step(0);
      const rows = await this._api.getResource(['imports', id], { signal: task.cancelled });
      task.step(1);
      // ...
    } catch (error) {
      if (!task.cancelled.aborted) task.fail('COMMON.OPERATION_FAILED', { requestId: error.requestId });
    } finally {
      await this._loading.hide();
    }

Notes

  • The code appears only with a back-end on idea-aws >= 4.8.0: with an older one there's no requestId, and errors look as before, in the new style.
  • The legacy IDEAAWSAPIService (uncommon) carries the requestId too, and the module's own components (common, uncommon, teams, agenda) pass it in their errors.
  • The notices' icons come from ionicons, already installed with @ionic/angular.