fix(import): consistent add-source forms with masked passwords and URL errors (#1796)

* fix(import): consistent add-source forms with masked passwords and URL errors

- Mask the Xtream password in add and edit (and the Stalker one in edit)
  behind a shared PasswordVisibilityToggleDirective: one translated
  "Show password" label, state in aria-pressed, type="button".
- Give the Xtream server URL its own mat-error and a neutral hint instead
  of the EPG file error; give the M3U URL a mat-error.
- Use "Playlist title" in every add form, "MAC address" casing, a single
  ellipsis in "Validating portal…" and one "Add playlist" submit label;
  translate the method radiogroup's aria-label.
- Show Stalker refusals inline under the portal URL (role="status", like
  the Xtream connection test), translated in the template and cleared by
  edits; translate the snackbars for outcomes that close the dialog.
- Translate new strings into all locales; reuse the identical Stalker URL
  error translations; fix MAC casing and ellipses; drop unused keys.
- Unit specs per form, edit-dialog spec, new add-source-forms web E2E;
  update E2E locators; UI guidelines Forms section; Stalker contract.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(import): mask the password again when an add form is cleared

Clear erased the password but left the visibility toggle on, so the next
password typed in the Xtream or Stalker form showed in plain text.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
4grayandClaude Opus 5.5 authored and GitHub committed 2026-10-03 13:13:54 +02:00
1 parent 8e1cb05913
commit a8dd1eaa97
56 files changed
+1278 -252

No files matched your search

@@ -714,6 +714,28 @@ Settings use the same system but are flatter than content-heavy views.
alike. `theme-tokens.e2e.ts` checks the label and the error fill in both
themes.
## Forms
The add-source forms (M3U URL, Xtream, Stalker) and the edit dialog share one
vocabulary, so a field reads the same wherever it appears:
- **Name.** The source name is labelled "Playlist title"
(`HOME.XTREAM_PLAYLIST.TITLE`) in every add form. Every add form submits
with "Add playlist" (`HOME.URL_UPLOAD.ADD_PLAYLIST`).
- **Passwords.** A password input is masked and has a `mat-icon-button`
suffix with `PasswordVisibilityToggleDirective`
(`@iptvnator/ui/components/password-visibility-toggle`). The input binds
`[type]="toggle.inputType()"`; the button keeps one translated label
("Show password", `HOME.SHOW_PASSWORD`) and exposes its state through
`aria-pressed`, as an ARIA toggle button does.
- **URLs.** A URL field has a neutral `mat-hint` where the format is not
obvious, and its own `mat-error`. Never borrow another field's message.
- **Feedback.** While the dialog stays open, a check or refusal is shown
inline under the URL field in a `role="status"` paragraph. The message is
translated in the template and cleared by any edit. Use a snackbar only for
outcomes that close the dialog. `add-source-forms.e2e.ts` in `web-e2e`
covers the shared labels, the toggle and the URL errors.
## Source Type Icons
`SOURCE_TYPE_ICONS` in `@iptvnator/shared/interfaces` is the only source of
+7 -2
View File
@@ -743,8 +743,13 @@ otherwise throws `StalkerPortalError('auth-failed')` carrying the body.
### Error surfacing
`StalkerPortalError.portalText` holds the portal's own words. The import
dialog shows them in its failure snackbar (with kind-specific i18n headlines,
`HOME.STALKER_PORTAL.*`); the workspace context panel replaces the generic
dialog shows them inline under the portal URL, in the same `role="status"`
paragraph the Xtream form uses for its connection test, after a kind-specific
i18n headline (`HOME.STALKER_PORTAL.*`, mapped by `toStalkerImportFeedback`).
The template translates both parts, and any edit clears the message. Outcomes
that close the dialog (validated with an expiry date, or added without
validation) use translated snackbars instead. The workspace context panel
replaces the generic
"could not load categories" hint with the portal text (or the login-required
guidance) when category loading failed with a portal refusal
(`stalkerCategoryErrorDescription` in `workspace-context-panel.component.ts`).