Editor/Window/AwsUserProfilesPage.cs (224 lines of code) (raw):

// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 using System; using System.IO; using System.Collections.Generic; using System.Linq; using System.Diagnostics; using UnityEngine; using UnityEngine.UIElements; using AmazonGameLiftPlugin.Core.CredentialManagement.Models; using BucketErrorCode = AmazonGameLiftPlugin.Core.Shared.ErrorCode; namespace AmazonGameLift.Editor { internal class AwsUserProfilesPage { private List<TextField> AccountDetailTextFields = new(); private readonly AwsCredentialsUpdate _awsCredentialsUpdateModel; private readonly BootstrapSettings _bootstrapSettings; private readonly ElementLocalizer _elementLocalizer; private VisualElement _currentElement; private const string hiddenClassName = "hidden"; private readonly StateManager _stateManager; private readonly VisualElement _container; private readonly UserProfileCreation _userProfileCreation; private readonly HelpfulResources _helpfulResources; private readonly List<VisualElement> _allMenus; private readonly VisualElement _noAccountMenu; private readonly VisualElement _createMenu; private readonly VisualElement _profilesTableMenu; private readonly Button _bootstrapButton; private readonly Button _selectProfileButton; private readonly Button _openCredentialsFileButton; private TextField _configFilePathInput; private StatusBox _statusBox; public AwsUserProfilesPage(VisualElement container, StateManager stateManager) { var awsCredentials = AwsCredentialsFactory.Create(); _awsCredentialsUpdateModel = awsCredentials.Update; _container = container; var mVisualTreeAsset = Resources.Load<VisualTreeAsset>("EditorWindow/Pages/AwsUserProfilesPage"); var uxml = mVisualTreeAsset.Instantiate(); _container.Add(uxml); _elementLocalizer = new ElementLocalizer(_container); SetupStatusBoxes(); LocalizeText(); _noAccountMenu = _container.Q<VisualElement>("UserProfilePageNoAccountMenu"); _createMenu = _container.Q<VisualElement>("UserProfilePageCreateMenu"); _profilesTableMenu = _container.Q<VisualElement>("UserProfilesTableMenu"); _allMenus = new List<VisualElement>() { _noAccountMenu, _createMenu, _profilesTableMenu, }; AccountDetailTextFields = _createMenu.Query<TextField>().ToList(); _stateManager = stateManager; _stateManager.OnUserProfileUpdated += () => { _awsCredentialsUpdateModel.Refresh(); _awsCredentialsUpdateModel.Update(); }; var createProfileContainer = _container.Q("UserProfilePageCreateMenu"); _userProfileCreation = new UserProfileCreation(createProfileContainer, _stateManager); _userProfileCreation.OnProfileCreated += () => { ShowProfileMenu(_profilesTableMenu); }; _bootstrapSettings = BootstrapSettingsFactory.Create(_stateManager); var helpfulResourcesContainer = _container.Q<Foldout>("HelpfulResourcesFoldout"); _helpfulResources = new HelpfulResources(helpfulResourcesContainer); helpfulResourcesContainer.value = false; RefreshProfiles(); container.Q<DropdownField>("UserProfilePageAccountNewProfileRegionDropdown").choices = _stateManager.CoreApi.ListAvailableRegions().ToList(); _configFilePathInput = _container.Q<TextField>("UserProfilePageAwsConfigurationFileInput"); _configFilePathInput.SetEnabled(false); _selectProfileButton = _container.Q<Button>(Strings.UserProfilePageSetProfileButton); _bootstrapButton = _container.Q<Button>(Strings.UserProfilePageBootstrapButton); _openCredentialsFileButton = _container.Q<Button>("UserProfilePageAwsConfigurationFileButton"); UpdateGui(); _stateManager.OnUserProfileUpdated += UpdateGui; _stateManager.OnUserProfileUpdated += EnableDisableButtons; _stateManager.OnAddAnotherProfile += () => ShowProfileMenu(_createMenu); _stateManager.OnProfileRadioButtonChanged += EnableDisableButtons; ChooseProfileMenu(); SetupButtonCallbacks(); EnableDisableButtons(); } private void UpdateGui() { if (!_stateManager.IsBootstrapped()) { _statusBox.Show(StatusBox.StatusBoxType.Warning, Strings.UserProfilePageStatusBoxWarningText); } else { _statusBox.Close(); } GetCredentialsFileResponse response = _stateManager.CoreApi.GetCredentialsFile(); if (!response.Success) { UnityEngine.Debug.LogError(_elementLocalizer.GetError(response.ErrorCode)); _openCredentialsFileButton.SetEnabled(false); return; } _configFilePathInput.value = response.FilePath; _openCredentialsFileButton.SetEnabled(true); } private void LocalizeText() { var strings = new[] { Strings.UserProfilePageTitle, Strings.UserProfilePageDescription, Strings.UserProfilePageAccountCardNoAccountTitle, Strings.UserProfilePageAccountCardNoAccountDescription, Strings.UserProfilePageAccountCardNoAccountButtonLabel, Strings.UserProfilePageAccountCardHasAccountTitle, Strings.UserProfilePageAccountCardHasAccountDescription, Strings.UserProfilePageAccountCardHasAccountButton, Strings.UserProfilePageTableTitle, Strings.UserProfilePageTableDescription, Strings.UserProfilePageAwsConfigurationFileLabel, Strings.UserProfilePageBootstrapButton, Strings.UserProfilePageCompletedBootstrapHelpLink, Strings.UserProfilePageSetProfileButton }; foreach (var s in strings) { _elementLocalizer.SetElementText(s, s); } _elementLocalizer.SetElementTooltip(Strings.UserProfilePageAwsConfigurationFileLabel, Strings.UserProfilePageAwsConfigurationFileTooltip); } private void SetupButtonCallbacks() { _container.Q<Button>("UserProfilePageAccountCardNoAccountButton") .RegisterCallback<ClickEvent>(_ => Application.OpenURL(Urls.CreateAwsAccountLearnMore)); _container.Q<VisualElement>("UserProfilePageAccountNewProfileHelpLinkParent") .RegisterCallback<ClickEvent>(_ => Application.OpenURL(Urls.AwsIamDocumentation)); _container.Q<Button>("UserProfilePageAccountCardHasAccountButton").RegisterCallback<ClickEvent>(_ => { var targetWizard = _container.Q<VisualElement>("UserProfilePageCreateMenu"); ShowProfileMenu(targetWizard); }); _container.Q<Button>("UserProfilePageAccountNewProfileCancelButton").RegisterCallback<ClickEvent>(_ => { _userProfileCreation.Reset(); ChooseProfileMenu(); }); _selectProfileButton.RegisterCallback<ClickEvent>(_ => { _stateManager.SetProfile(_stateManager.SelectedRadioButton); }); _bootstrapButton.RegisterCallback<ClickEvent>(_ => { _bootstrapSettings.RefreshBucketName(); OpenS3Popup(_bootstrapSettings.BucketName); }); _container.Q<VisualElement>("WhatIsBootstrappingLink").RegisterCallback<ClickEvent>(_ => Application.OpenURL(Urls.S3BootstrapHelp)); _openCredentialsFileButton.RegisterCallback<ClickEvent>(_ => { Process.Start($"\"{_configFilePathInput.value}\""); }); } private void EnableDisableButtons() { var selectedProfile = _stateManager.SelectedProfile; var selectedButton = _stateManager.SelectedRadioButton; _bootstrapButton.SetEnabled(selectedProfile != null && selectedProfile.Name == selectedButton && !_stateManager.IsBootstrapped(selectedProfile)); _selectProfileButton.SetEnabled(selectedProfile != null && selectedButton != null && selectedProfile.Name != selectedButton); } private void ChooseProfileMenu() { if (_stateManager.AllProfiles.Count == 0) { ShowProfileMenu(_noAccountMenu); } else if (_stateManager.SelectedProfile == null) { ShowProfileMenu(_createMenu); } else { ShowProfileMenu(_profilesTableMenu); } } private void ShowProfileMenu(VisualElement targetMenu) { _allMenus.ForEach(menu => menu.AddToClassList(hiddenClassName)); if (targetMenu != null) { targetMenu.RemoveFromClassList(hiddenClassName); } } private void RefreshProfiles() { _awsCredentialsUpdateModel.Refresh(); } private void BootstrapAccount(string bucketName) { var bucketResponse = _bootstrapSettings.CreateBucket(bucketName); if (bucketResponse.Success || bucketResponse.ErrorCode == BucketErrorCode.BucketNameAlreadyExists) { _stateManager.SetBucketBootstrap(bucketName); _statusBox.Show(StatusBox.StatusBoxType.Success, Strings.UserProfilePageStatusBoxSuccessText); } else { _statusBox.Show(StatusBox.StatusBoxType.Error, Strings.UserProfilePageBootstrapErrorText, bucketResponse.ErrorMessage, Urls.AwsS3Console, Strings.ViewS3LogsStatusBoxUrlTextButton); } } private void OpenS3Popup(string bucketName) { var popup = ScriptableObject.CreateInstance<GameLiftPluginBucketPopup>(); popup.Init(bucketName); popup.OnConfirm += BootstrapAccount; popup.ShowModalUtility(); } private void SetupStatusBoxes() { _statusBox = _container.Q<StatusBox>("UserProfilePageStatusBox"); } } }