/* * Copyright OpenSearch Contributors * SPDX-License-Identifier: Apache-2.0 */ import React, { ChangeEvent, Component } from "react"; import { RouteComponentProps } from "react-router-dom"; import moment from "moment"; import queryString from "query-string"; import { EuiFlexItem, EuiFlexGroup, EuiButton, EuiTitle, EuiSpacer, EuiButtonEmpty } from "@elastic/eui"; import ConfigureRollup from "../../CreateRollup/components/ConfigureRollup"; import Schedule from "../../CreateRollup/components/Schedule"; import { getErrorMessage } from "../../../utils/helpers"; import { BREADCRUMBS, ROUTES } from "../../../utils/constants"; import { Rollup } from "../../../../models/interfaces"; import { RollupService } from "../../../services"; import { EMPTY_ROLLUP } from "../../CreateRollup/utils/constants"; import { CoreServicesContext } from "../../../components/core_services"; import { delayTimeUnitToMS, msToDelayTimeUnit } from "../../CreateRollup/utils/helpers"; interface EditRollupProps extends RouteComponentProps { rollupService: RollupService; } interface EditRollupState { rollupId: string; rollupIdError: string; rollupSeqNo: number | null; rollupPrimaryTerm: number | null; submitError: string; isSubmitting: boolean; hasSubmitted: boolean; description: string; jobEnabledByDefault: boolean; continuousJob: string; continuousDefinition: string; interval: number; intervalError: string; intervalTimeunit: string; cronExpression: string; cronTimezone: string; pageSize: number; delayTime: number | string; delayTimeunit: string; rollupJSON: any; } export default class EditRollup extends Component { static contextType = CoreServicesContext; constructor(props: EditRollupProps) { super(props); this.state = { rollupId: "", rollupIdError: "", rollupSeqNo: null, rollupPrimaryTerm: null, submitError: "", isSubmitting: false, hasSubmitted: false, description: "", jobEnabledByDefault: false, continuousJob: "no", continuousDefinition: "fixed", interval: 2, intervalError: "", intervalTimeunit: "MINUTES", cronExpression: "", cronTimezone: "UTC", pageSize: 1000, delayTime: "", delayTimeunit: "MINUTES", rollupJSON: EMPTY_ROLLUP, }; } componentDidMount = async (): Promise => { const { id } = queryString.parse(this.props.location.search); if (typeof id === "string" && !!id) { this.context.chrome.setBreadcrumbs([BREADCRUMBS.INDEX_MANAGEMENT, BREADCRUMBS.ROLLUPS, BREADCRUMBS.EDIT_ROLLUP, { text: id }]); await this.getRollupToEdit(id); } else { this.context.notifications.toasts.addDanger(`Invalid rollup id: ${id}`); this.props.history.push(ROUTES.ROLLUPS); } }; getRollupToEdit = async (rollupId: string): Promise => { try { const { rollupService } = this.props; const response = await rollupService.getRollup(rollupId); if (response.ok) { let newJSON = JSON.parse(this.state.rollupJSON); newJSON.rollup = response.response.rollup; this.setState({ rollupSeqNo: response.response._seqNo, rollupPrimaryTerm: response.response._primaryTerm, rollupId: response.response._id, description: response.response.rollup.description, jobEnabledByDefault: response.response.rollup.enabled, pageSize: response.response.rollup.page_size, delayTime: !response.response.rollup.delay ? "" : msToDelayTimeUnit(response.response.rollup.delay, this.state.delayTimeunit), rollupJSON: newJSON, }); if (response.response.rollup.schedule.cron == undefined) { this.setState({ interval: response.response.rollup.schedule.interval.period, intervalTimeunit: response.response.rollup.schedule.interval.unit, continuousDefinition: "fixed", }); } else { this.setState({ cronExpression: response.response.rollup.schedule.cron.expression, continuousDefinition: "cron" }); } } else { this.context.notifications.toasts.addDanger(`Could not load the rollup job: ${response.error}`); this.props.history.push(ROUTES.ROLLUPS); } } catch (err) { this.context.notifications.toasts.addDanger(getErrorMessage(err, "Could not load the rollup job")); this.props.history.push(ROUTES.ROLLUPS); } }; onCancel = (): void => { this.props.history.push(ROUTES.ROLLUPS); }; onChangeDescription = (e: ChangeEvent): void => { const description = e.target.value; let newJSON = this.state.rollupJSON; newJSON.rollup.description = description; this.setState({ description: description, rollupJSON: newJSON }); }; onChangeName = (e: ChangeEvent): void => { const { hasSubmitted } = this.state; const rollupId = e.target.value; let newJSON = this.state.rollupJSON; newJSON.rollup.rollupId = rollupId; if (hasSubmitted) this.setState({ rollupId, rollupIdError: rollupId ? "" : "Required" }); else this.setState({ rollupId: rollupId, rollupJSON: newJSON }); }; onChangeJobEnabledByDefault = (): void => { const checked = this.state.jobEnabledByDefault; let newJSON = this.state.rollupJSON; newJSON.rollup.enabled = checked; this.setState({ jobEnabledByDefault: !checked, rollupJSON: newJSON }); }; onChangeCron = (e: ChangeEvent): void => { this.setState({ cronExpression: e.target.value }); }; onChangeCronTimezone = (e: ChangeEvent): void => { this.setState({ cronTimezone: e.target.value }); }; onChangeDelayTime = (e: ChangeEvent): void => { let newJSON = this.state.rollupJSON; newJSON.rollup.delay = e.target.value; this.setState({ delayTime: e.target.valueAsNumber, rollupJSON: newJSON }); }; onChangeIntervalTime = (e: ChangeEvent): void => { this.setState({ interval: e.target.valueAsNumber }); if (e.target.value == "") { const intervalErrorMsg = "Interval value is required."; this.setState({ submitError: intervalErrorMsg, intervalError: intervalErrorMsg }); } else { this.setState({ intervalError: "" }); } }; onChangePage = (e: ChangeEvent): void => { let newJSON = this.state.rollupJSON; newJSON.rollup.page_size = e.target.value; this.setState({ pageSize: e.target.valueAsNumber, rollupJSON: newJSON }); }; onChangeContinuousDefinition = (e: ChangeEvent): void => { this.setState({ continuousDefinition: e.target.value }); }; onChangeContinuousJob = (optionId: string): void => { let newJSON = this.state.rollupJSON; newJSON.rollup.continuous = optionId == "yes"; this.setState({ continuousJob: optionId, rollupJSON: newJSON }); }; //Update delay field in JSON if delay value is defined. onChangeDelayTimeunit = (e: ChangeEvent): void => { this.setState({ delayTimeunit: e.target.value }); }; onChangeIntervalTimeunit = (e: ChangeEvent): void => { this.setState({ intervalTimeunit: e.target.value }); }; // convert from delayTimeunit to ms for internal processing updateDelay = (): void => { const { delayTime, delayTimeunit } = this.state; let newJSON = this.state.rollupJSON; newJSON.rollup.delay = delayTimeUnitToMS(delayTime as number, delayTimeunit).toString(); this.setState({ rollupJSON: newJSON }); }; updateSchedule = (): void => { const { continuousDefinition, cronExpression, interval, intervalTimeunit, cronTimezone } = this.state; let newJSON = this.state.rollupJSON; if (continuousDefinition == "cron") { newJSON.rollup.schedule.cron = { expression: `${cronExpression}`, timezone: `${cronTimezone}` }; delete newJSON.rollup.schedule["interval"]; } else { newJSON.rollup.schedule.interval = { start_time: moment().unix(), unit: intervalTimeunit, period: interval, }; delete newJSON.rollup.schedule["cron"]; } this.setState({ rollupJSON: newJSON }); }; onSubmit = async (): Promise => { const { rollupId, rollupJSON } = this.state; this.setState({ submitError: "", isSubmitting: true, hasSubmitted: true }); try { if (!rollupId) { this.setState({ rollupIdError: "Required" }); } else { //Build JSON string here this.updateSchedule(); this.updateDelay(); await this.onUpdate(rollupId, rollupJSON); } } catch (err) { this.context.notifications.toasts.addDanger("Invalid Rollup JSON"); console.error(err); } this.setState({ isSubmitting: false }); }; onUpdate = async (rollupId: string, rollup: Rollup): Promise => { try { const { rollupService } = this.props; const { rollupPrimaryTerm, rollupSeqNo } = this.state; if (rollupSeqNo == null || rollupPrimaryTerm == null) { this.context.notifications.toasts.addDanger("Could not update rollup without seqNo and primaryTerm"); return; } const response = await rollupService.putRollup(rollup, rollupId, rollupSeqNo, rollupPrimaryTerm); if (response.ok) { this.context.notifications.toasts.addSuccess(`Changes to "${response.response._id}" saved!`); this.props.history.push(ROUTES.ROLLUPS); } else { this.context.notifications.toasts.addDanger(response.error); this.setState({ submitError: response.error }); } } catch (err) { this.setState({ submitError: getErrorMessage(err, "There was a problem updating the rollup") }); } }; render() { const { rollupId, rollupIdError, isSubmitting, description, jobEnabledByDefault, continuousJob, continuousDefinition, interval, intervalError, intervalTimeunit, cronExpression, cronTimezone, pageSize, delayTime, delayTimeunit, } = this.state; return (

Edit rollup job

Cancel Save changes
); } }