diff --git a/package-lock.json b/package-lock.json index 050e1821..ac2adc47 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9024,9 +9024,9 @@ } }, "node_modules/madwizard": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/madwizard/-/madwizard-1.2.0.tgz", - "integrity": "sha512-hUqxJ9JNPkKTKcmQjEp+fF2uCc1W8poaJ+SmdI6XEJQQ6MFqrC6YLymiOemZZ/Me6Cz3DWvGBX/J9BmThPIv/g==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/madwizard/-/madwizard-1.3.1.tgz", + "integrity": "sha512-c8gu2DCEFDWtCiHN9Kka8KRg1fvNAoqNZ1tE1EaBSgInr97+w574LwL3whUoC8S6R0G0Izr6GCtIvJugOF1+Mg==", "dependencies": { "chalk": "^5.0.1", "cli-highlight": "^2.1.11", @@ -16143,7 +16143,7 @@ "license": "Apache-2.0", "dependencies": { "@guidebooks/store": "^0.14.3", - "madwizard": "^1.2.0" + "madwizard": "^1.3.1" } } }, @@ -16850,7 +16850,7 @@ "version": "file:plugins/plugin-madwizard", "requires": { "@guidebooks/store": "^0.14.3", - "madwizard": "^1.2.0" + "madwizard": "^1.3.1" } }, "@kui-shell/plugin-patternfly4-themes": { @@ -22932,9 +22932,9 @@ } }, "madwizard": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/madwizard/-/madwizard-1.2.0.tgz", - "integrity": "sha512-hUqxJ9JNPkKTKcmQjEp+fF2uCc1W8poaJ+SmdI6XEJQQ6MFqrC6YLymiOemZZ/Me6Cz3DWvGBX/J9BmThPIv/g==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/madwizard/-/madwizard-1.3.1.tgz", + "integrity": "sha512-c8gu2DCEFDWtCiHN9Kka8KRg1fvNAoqNZ1tE1EaBSgInr97+w574LwL3whUoC8S6R0G0Izr6GCtIvJugOF1+Mg==", "requires": { "chalk": "^5.0.1", "cli-highlight": "^2.1.11", diff --git a/plugins/plugin-codeflare/src/components/ProfileExplorer.tsx b/plugins/plugin-codeflare/src/components/ProfileExplorer.tsx index b41acea8..fa5a9c11 100644 --- a/plugins/plugin-codeflare/src/components/ProfileExplorer.tsx +++ b/plugins/plugin-codeflare/src/components/ProfileExplorer.tsx @@ -44,7 +44,7 @@ import ProfileSelect from "./ProfileSelect" import ProfileWatcher from "../tray/watchers/profile/list" import ProfileStatusWatcher from "../tray/watchers/profile/status" import UpdateFunction from "../tray/update" -import { handleReset } from "../controller/profile/actions" +import { handleNew, handleDelete, handleReset } from "../controller/profile/actions" import "../../web/scss/components/Dashboard/Description.scss" import "../../web/scss/components/ProfileExplorer/_index.scss" @@ -91,16 +91,37 @@ export default class ProfileExplorer extends React.PureComponent { })) } - private readonly _handleProfileSelection = (selectedProfile: string) => { - this.setState({ selectedProfile }) + /** If given `null`, then we will attempt to use the lastUsed profile */ + private readonly _handleProfileSelection = (selectedProfile: string | null) => { + if (!selectedProfile && this.state.profiles) { + // last used, excluding the currently selected profile + const lastUsed = this.lastUsed(this.state.profiles.filter((_) => _.name !== this.state.selectedProfile)) + if (lastUsed) { + selectedProfile = lastUsed.name + } + } + + if (selectedProfile) { + this.setState({ selectedProfile }) - if (this.props.onSelectProfile) { - this.props.onSelectProfile(selectedProfile) + if (this.props.onSelectProfile) { + this.props.onSelectProfile(selectedProfile) + } } } private updateDebouncer: null | ReturnType = null + private lastUsed(profiles: Profiles.Profile[]) { + return profiles.slice(1).reduce((lastUsed, profile) => { + if (lastUsed.lastUsedTime < profile.lastUsedTime) { + return profile + } else { + return lastUsed + } + }, profiles[0]) + } + private readonly profileWatcherUpdateFn = () => { if (this.updateDebouncer) { clearTimeout(this.updateDebouncer) @@ -122,13 +143,7 @@ export default class ProfileExplorer extends React.PureComponent { let selectedProfile = curState.selectedProfile if (!curState || !curState.profiles || curState.profiles.length === 0) { // use the last-used profile by default - const newSelectedProfile = profiles.slice(1).reduce((lastUsed, profile) => { - if (lastUsed.lastUsedTime < profile.lastUsedTime) { - return profile - } else { - return lastUsed - } - }, profiles[0]) + const newSelectedProfile = this.lastUsed(profiles) // also emit an initial profile selection event if (newSelectedProfile) { @@ -223,7 +238,7 @@ type ProfileCardProps = Partial & Pick & { profile: string profiles: Profiles.Profile[] - onSelectProfile: (profile: string) => void + onSelectProfile: (profile: string | null) => void profileReadiness: string profileStatus: ProfileStatusWatcher @@ -231,9 +246,6 @@ type ProfileCardProps = Partial & type ProfileCardState = { isOpen: boolean - - /** Clear any "just changed" indicators after a brief delay */ - // clearDiff?: ReturnType } class ProfileCard extends React.PureComponent { @@ -243,7 +255,24 @@ class ProfileCard extends React.PureComponent handleReset(this.props.profile) + + /** Create new profile */ + private readonly _handleNew = async () => { + if (this.props.profile) { + const newProfile = await handleNew(this.props.profile, this.props.profiles) + this.props.onSelectProfile(newProfile) + } + } + + /** Delete selected profile */ + private readonly _handleDelete = async () => { + if (this.props.profile) { + await handleDelete(this.props.profile) + this.props.onSelectProfile(null) + } + } + + private readonly _handleReset = () => this.props.profile && handleReset(this.props.profile) // private readonly _handleBoot = () => handleBoot(this.props.profile) // private readonly _handleShutdown = () => handleShutdown(this.props.profile) private readonly _onToggle = () => this.setState({ isOpen: !this.state.isOpen }) @@ -454,7 +483,7 @@ class ProfileCard extends React.PureComponent } - return "Internal Error" + return } private sort(data: TreeViewDataItem[]) { @@ -472,11 +501,24 @@ class ProfileCard extends React.PureComponent - + + + + + - + + + + + + {/*