diff --git a/Passepartout/App/macOS/Base.lproj/Service.storyboard b/Passepartout/App/macOS/Base.lproj/Service.storyboard index 1a558601..0b6bda26 100644 --- a/Passepartout/App/macOS/Base.lproj/Service.storyboard +++ b/Passepartout/App/macOS/Base.lproj/Service.storyboard @@ -726,107 +726,160 @@ DQ - + - - + + - - - - - - - - NSAllRomanInputSourcesLocaleIdentifier - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + NSAllRomanInputSourcesLocaleIdentifier + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + - - - + + + + + + + - - - - - - - - - - - - - + + + + - - - + + + + + + + + + + + + + + + + + + - - - - - - - - - - + + + + + + + + + diff --git a/Passepartout/App/macOS/CHANGELOG.md b/Passepartout/App/macOS/CHANGELOG.md index 6d1f18e2..6a0da9d4 100644 --- a/Passepartout/App/macOS/CHANGELOG.md +++ b/Passepartout/App/macOS/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Added + +- Website guidance in provider account screen. + ### Changed - Improved debug log appearance. diff --git a/Passepartout/App/macOS/Global/Theme.swift b/Passepartout/App/macOS/Global/Theme.swift index b3bc87bd..b3c0b449 100644 --- a/Passepartout/App/macOS/Global/Theme.swift +++ b/Passepartout/App/macOS/Global/Theme.swift @@ -58,6 +58,15 @@ extension Infrastructure.Metadata { } return image } + + var guidanceString: String? { + let key = "account.sections.guidance.footer.infrastructure.\(name)" + let format = NSLocalizedString(key, tableName: "Core", bundle: Bundle(for: AppDelegate.self), comment: "") + guard format != key else { + return nil + } + return String(format: format, locale: .current, description) + } } extension ConnectionProfile { diff --git a/Passepartout/App/macOS/Scenes/Service/AccountViewController.swift b/Passepartout/App/macOS/Scenes/Service/AccountViewController.swift index 39c0e8de..8cad0d14 100644 --- a/Passepartout/App/macOS/Scenes/Service/AccountViewController.swift +++ b/Passepartout/App/macOS/Scenes/Service/AccountViewController.swift @@ -44,6 +44,10 @@ class AccountViewController: NSViewController { @IBOutlet private weak var textPassword: NSSecureTextField! + @IBOutlet private weak var labelGuidance: NSTextField! + + @IBOutlet private weak var buttonGuidance: NSButton! + @IBOutlet private weak var buttonOK: NSButton! @IBOutlet private weak var buttonCancel: NSButton! @@ -67,14 +71,30 @@ class AccountViewController: NSViewController { } labelPasswordCaption.stringValue = L10n.Core.Account.Cells.Password.caption.asCaption textPassword.placeholderString = L10n.Core.Account.Cells.Password.placeholder + buttonGuidance.title = L10n.Core.Account.Cells.OpenGuide.caption buttonOK.title = L10n.Core.Global.ok buttonCancel.title = L10n.Core.Global.cancel let credentials = service.credentials(for: profile) textUsername.stringValue = credentials?.username ?? "" textPassword.stringValue = credentials?.password ?? "" + + if let guidanceString = guidanceString, !guidanceString.isEmpty { + labelGuidance.stringValue = guidanceString + buttonGuidance.isHidden = (guidanceURL == nil) + } else { + labelGuidance.isHidden = true + buttonGuidance.isHidden = true + } } - + + @IBAction private func openGuidance(_ sender: Any?) { + guard let url = guidanceURL else { + return + } + NSWorkspace.shared.open(url) + } + @IBAction private func confirm(_ sender: Any?) { let username = textUsername.stringValue let password = textPassword.stringValue @@ -104,3 +124,29 @@ class AccountViewController: NSViewController { delegateAndDismiss(sender) } } + +extension AccountViewController { + private var infrastructureName: Infrastructure.Name? { + guard let providerProfile = profile as? ProviderConnectionProfile else { + return nil + } + return providerProfile.name + } + + private var guidanceString: String? { + guard let name = infrastructureName, let metadata = InfrastructureFactory.shared.metadata(forName: name) else { + return nil + } + return metadata.guidanceString + } + + private var guidanceURL: URL? { + guard let name = infrastructureName else { + return nil + } + guard let string = AppConstants.URLs.guidances[name] else { + return nil + } + return URL(string: string) + } +}