This is an automated email from the ASF dual-hosted git repository. marat pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/camel-karavan.git
commit 168a14fb53229f93381fc78384e70cbb6790f033 Author: Marat Gubaidullin <[email protected]> AuthorDate: Fri Sep 23 14:16:33 2022 -0400 Fix issue with Create project Modal --- karavan-app/src/main/webapp/src/Main.tsx | 86 ++-------------------- karavan-app/src/main/webapp/src/api/KaravanApi.tsx | 2 +- .../src/main/webapp/src/projects/ProjectsPage.tsx | 83 ++++++++++++++++++--- 3 files changed, 77 insertions(+), 94 deletions(-) diff --git a/karavan-app/src/main/webapp/src/Main.tsx b/karavan-app/src/main/webapp/src/Main.tsx index 6a2aa8e..ebf34f4 100644 --- a/karavan-app/src/main/webapp/src/Main.tsx +++ b/karavan-app/src/main/webapp/src/Main.tsx @@ -8,7 +8,6 @@ import { AlertActionCloseButton, Flex, FlexItem, - Avatar, Tooltip, Divider, Spinner, Bullseye, Popover, Badge } from '@patternfly/react-core'; @@ -65,7 +64,6 @@ interface Props { interface State { config: any, - isNavOpen: boolean, pageId: string, projects: Project[], project?: Project, @@ -83,7 +81,6 @@ export class Main extends React.Component<Props, State> { public state: State = { config: {}, - isNavOpen: true, pageId: "projects", projects: [], isModalOpen: false, @@ -133,22 +130,10 @@ export class Main extends React.Component<Props, State> { KaravanApi.getComponentNames(names => names.forEach(name => { KaravanApi.getComponent(name, json => ComponentApi.saveComponent(json)) })); - this.onGetProjects(); } - onNavToggle = () => { - this.setState({ - isNavOpen: !this.state.isNavOpen - }); - }; - - onNavSelect = (result: any) => { - if (result.itemId === 'integrations') { - this.onGetProjects(); - } - this.setState({ - pageId: result.itemId, - }); + deleteErrorMessage = (id: string) => { + this.setState({alerts: this.state.alerts.filter(a => a.id !== id)}) } pageNav = () => { @@ -204,26 +189,6 @@ export class Main extends React.Component<Props, State> { </Flex>) } - onProjectDelete = (project: Project) => { - this.setState({isModalOpen: true, projectToDelete: project}) - }; - - deleteErrorMessage = (id: string) => { - this.setState({alerts: this.state.alerts.filter(a => a.id !== id)}) - } - deleteProject = () => { - if (this.state.projectToDelete) - KaravanApi.deleteProject(this.state.projectToDelete, res => { - if (res.status === 204) { - this.toast("Success", "Project deleted", "success"); - this.onGetProjects(); - } else { - this.toast("Error", res.statusText, "danger"); - } - }); - this.setState({isModalOpen: false}) - } - toast = (title: string, text: string, variant: 'success' | 'danger' | 'warning' | 'info' | 'default') => { const mess = []; mess.push(...this.state.alerts, new ToastMessage(title, text, variant)); @@ -231,32 +196,9 @@ export class Main extends React.Component<Props, State> { } onProjectSelect = (project: Project) => { - this.setState({isNavOpen: true, pageId: 'project', project: project}); + this.setState({pageId: 'project', project: project}); }; - onProjectCreate = (project: Project) => { - KaravanApi.postProject(project, res => { - console.log(res.status) - if (res.status === 200 || res.status === 201) { - this.toast("Success", "Project created", "success"); - this.setState({isNavOpen: true, pageId: 'project', project: project}); - } else { - this.toast("Error", res.status + ", " + res.statusText, "danger"); - } - }); - }; - - onGetProjects = () => { - KaravanApi.getConfiguration((config: any) => { - KaravanApi.getProjects((projects: Project[]) => { - this.setState({ - projects: projects, request: uuidv4(), config: config - }) - }); - }); - - } - getMain() { return ( <> @@ -267,14 +209,9 @@ export class Main extends React.Component<Props, State> { <FlexItem flex={{default:"flex_2"}} style={{height:"100%"}}> {this.state.pageId === 'projects' && <ProjectsPage key={this.state.request} - projects={this.state.projects} - config={this.state.config} - onDelete={this.onProjectDelete} onSelect={this.onProjectSelect} - onRefresh={() => { - this.onGetProjects(); - }} - onCreate={this.onProjectCreate}/>} + toast={this.toast} + config={this.state.config}/>} {this.state.pageId === 'project' && this.state.project && <ProjectPage project={this.state.project} config={this.state.config}/>} {this.state.pageId === 'configuration' && <ConfigurationPage/>} {this.state.pageId === 'kamelets' && <KameletsPage dark={false}/>} @@ -282,19 +219,6 @@ export class Main extends React.Component<Props, State> { {this.state.pageId === 'eip' && <EipPage dark={false}/>} </FlexItem> </Flex> - <Modal - title="Confirmation" - variant={ModalVariant.small} - isOpen={this.state.isModalOpen} - onClose={() => this.setState({isModalOpen: false})} - actions={[ - <Button key="confirm" variant="primary" onClick={e => this.deleteProject()}>Delete</Button>, - <Button key="cancel" variant="link" - onClick={e => this.setState({isModalOpen: false})}>Cancel</Button> - ]} - onEscapePress={e => this.setState({isModalOpen: false})}> - <div>{"Are you sure you want to delete the project " + this.state.projectToDelete?.projectId + "?"}</div> - </Modal> </> ) } diff --git a/karavan-app/src/main/webapp/src/api/KaravanApi.tsx b/karavan-app/src/main/webapp/src/api/KaravanApi.tsx index e15a2ad..a7031e9 100644 --- a/karavan-app/src/main/webapp/src/api/KaravanApi.tsx +++ b/karavan-app/src/main/webapp/src/api/KaravanApi.tsx @@ -190,7 +190,7 @@ export class KaravanApi { } static async deleteProject(project: Project, after: (res: AxiosResponse<any>) => void) { - instance.delete('/project/' + encodeURI(project.projectId), + instance.delete('/api/project/' + encodeURI(project.projectId), {headers: {'username': 'cameleer'}}) .then(res => { after(res); diff --git a/karavan-app/src/main/webapp/src/projects/ProjectsPage.tsx b/karavan-app/src/main/webapp/src/projects/ProjectsPage.tsx index 24c72ed..1c2fb53 100644 --- a/karavan-app/src/main/webapp/src/projects/ProjectsPage.tsx +++ b/karavan-app/src/main/webapp/src/projects/ProjectsPage.tsx @@ -35,21 +35,21 @@ import DeleteIcon from "@patternfly/react-icons/dist/js/icons/times-icon"; import SearchIcon from '@patternfly/react-icons/dist/esm/icons/search-icon'; import CopyIcon from "@patternfly/react-icons/dist/esm/icons/copy-icon"; import {CamelUi} from "../designer/utils/CamelUi"; +import {KaravanApi} from "../api/KaravanApi"; interface Props { - projects: Project[], config: any, onSelect: (project: Project) => void - onCreate: (project: Project) => void - onDelete: (project: Project) => void - onRefresh: any + toast: (title: string, text: string, variant: 'success' | 'danger' | 'warning' | 'info' | 'default') => void } interface State { projects: Project[], isCreateModalOpen: boolean, + isDeleteModalOpen: boolean, isCopy: boolean, projectToCopy?: Project, + projectToDelete?: Project, filter: string, name: string, description: string, @@ -59,8 +59,9 @@ interface State { export class ProjectsPage extends React.Component<Props, State> { public state: State = { - projects: this.props.projects, + projects: [], isCreateModalOpen: false, + isDeleteModalOpen: false, isCopy: false, filter: '', name: '', @@ -70,13 +71,51 @@ export class ProjectsPage extends React.Component<Props, State> { interval: any; componentDidMount() { - this.interval = setInterval(() => this.props.onRefresh.call(this), 500); + this.interval = setInterval(() => this.onGetProjects(), 700); } componentWillUnmount() { clearInterval(this.interval); } + onProjectDelete = (project: Project) => { + this.setState({isDeleteModalOpen: true, projectToDelete: project}) + }; + + + deleteProject = () => { + if (this.state.projectToDelete) + KaravanApi.deleteProject(this.state.projectToDelete, res => { + if (res.status === 204) { + this.props.toast?.call(this, "Success", "Project deleted", "success"); + this.onGetProjects(); + } else { + this.props.toast?.call(this,"Error", res.statusText, "danger"); + } + }); + this.setState({isDeleteModalOpen: false}) + } + + onProjectCreate = (project: Project) => { + KaravanApi.postProject(project, res => { + console.log(res.status) + if (res.status === 200 || res.status === 201) { + this.props.toast?.call(this,"Success", "Project created", "success"); + } else { + this.props.toast?.call(this,"Error", res.status + ", " + res.statusText, "danger"); + } + }); + }; + + onGetProjects = () => { + KaravanApi.getConfiguration((config: any) => { + KaravanApi.getProjects((projects: Project[]) => { + this.setState({ projects: projects }) + }); + }); + + } + tools = () => (<Toolbar id="toolbar-group-types"> <ToolbarContent> <ToolbarItem> @@ -87,7 +126,7 @@ export class ProjectsPage extends React.Component<Props, State> { </ToolbarItem> <ToolbarItem> <Button variant="secondary" icon={<RefreshIcon/>} - onClick={e => this.props.onRefresh.call(this)}>Refresh</Button> + onClick={e => this.onGetProjects()}>Refresh</Button> </ToolbarItem> <ToolbarItem> <Button icon={<PlusIcon/>} onClick={e => this.setState({isCreateModalOpen: true, isCopy: false})}>Create</Button> @@ -101,13 +140,13 @@ export class ProjectsPage extends React.Component<Props, State> { closeModal = () => { this.setState({isCreateModalOpen: false, isCopy: false, name: this.props.config.groupId, description:'', projectId: ''}); - this.props.onRefresh.call(this); + this.onGetProjects(); } saveAndCloseCreateModal = () => { const {name, description, projectId} = this.state; const p = new Project(projectId, name, description, ''); - this.props.onCreate.call(this, p); + this.onProjectCreate(p); this.setState({isCreateModalOpen: false, isCopy: false, name: this.props.config.groupId, description: '', projectId: ''}); } @@ -118,12 +157,12 @@ export class ProjectsPage extends React.Component<Props, State> { } createModalForm() { - const {isCopy, projectToCopy, projectId, name} = this.state; + const {isCopy, projectToCopy, projectId, name, isCreateModalOpen} = this.state; return ( <Modal title={!isCopy ? "Create new project" : "Copy project from " + projectToCopy?.projectId} variant={ModalVariant.small} - isOpen={this.state.isCreateModalOpen} + isOpen={isCreateModalOpen} onClose={this.closeModal} onKeyDown={this.onKeyDown} actions={[ @@ -153,6 +192,25 @@ export class ProjectsPage extends React.Component<Props, State> { ) } + deleteModalForm() { + const {isCopy, projectToCopy, projectId, name, isCreateModalOpen} = this.state; + return ( + <Modal + title="Confirmation" + variant={ModalVariant.small} + isOpen={this.state.isDeleteModalOpen} + onClose={() => this.setState({isDeleteModalOpen: false})} + actions={[ + <Button key="confirm" variant="primary" onClick={e => this.deleteProject()}>Delete</Button>, + <Button key="cancel" variant="link" + onClick={e => this.setState({isDeleteModalOpen: false})}>Cancel</Button> + ]} + onEscapePress={e => this.setState({isDeleteModalOpen: false})}> + <div>{"Are you sure you want to delete the project " + this.state.projectToDelete?.projectId + "?"}</div> + </Modal> + ) + } + render() { const runtime = this.props.config?.runtime ? this.props.config.runtime : "QUARKUS"; const projects = this.state.projects.filter(p => p.name.includes(this.state.filter) || p.description.includes(this.state.filter)); @@ -214,7 +272,7 @@ export class ProjectsPage extends React.Component<Props, State> { </OverflowMenuItem> <OverflowMenuItem> <Tooltip content={"Delete project"} position={"bottom"}> - <Button variant={"plain"} icon={<DeleteIcon/>} onClick={e=>this.props.onDelete?.call(this, project)}></Button> + <Button variant={"plain"} icon={<DeleteIcon/>} onClick={e=>this.onProjectDelete(project)}></Button> </Tooltip> </OverflowMenuItem> </OverflowMenuGroup> @@ -241,6 +299,7 @@ export class ProjectsPage extends React.Component<Props, State> { </TableComposable> </PageSection> {this.createModalForm()} + {this.deleteModalForm()} </PageSection> ) }
