import React, { useState, useEffect, useCallback, useMemo } from 'react'; import { useFormik } from 'formik'; import { FormattedMessage as T, useIntl } from 'react-intl'; import {useHistory } from 'react-router-dom'; import { InputGroup, FormGroup, Intent, Button, MenuItem, Classes, HTMLSelect, Menu, H5, H6, } from '@blueprintjs/core'; import { Row, Col } from 'react-grid-system'; import { ReactSortable } from 'react-sortablejs'; import * as Yup from 'yup'; import { pick, get } from 'lodash'; import Icon from 'components/Icon'; import ErrorMessage from 'components/ErrorMessage'; import AppToaster from 'components/AppToaster'; import { If } from 'components'; import ViewFormContainer from 'containers/Views/ViewForm.container.js'; function ViewForm({ requestSubmitView, requestEditView, onDelete, viewId, viewMeta, resourceName, resourceColumns, resourceFields, resourceMetadata, changePageSubtitle, }) { const intl = useIntl(); const history = useHistory(); useEffect(() => { changePageSubtitle(resourceMetadata.label); return () => { changePageSubtitle(''); }; }, [changePageSubtitle,resourceMetadata.label]); const [draggedColumns, setDraggedColumn] = useState([ ...(viewMeta && viewMeta.columns ? viewMeta.columns : []), ]); const draggedColumnsIds = useMemo(() => draggedColumns.map((c) => c.id), [ draggedColumns, ]); const [availableColumns, setAvailableColumns] = useState([ ...(viewMeta && viewMeta.columns ? resourceColumns.filter( (column) => draggedColumnsIds.indexOf(column.id) === -1 ) : resourceColumns), ]); const defaultViewRole = useMemo( () => ({ field_key: '', comparator: '', value: '', index: 1, }), [] ); const validationSchema = Yup.object().shape({ resource_name: Yup.string().required(), name: Yup.string().required(), logic_expression: Yup.string().required(), roles: Yup.array().of( Yup.object().shape({ comparator: Yup.string().required(), value: Yup.string().required(), field_key: Yup.string().required(), index: Yup.number().required(), }) ), columns: Yup.array().of( Yup.object().shape({ key: Yup.string().required(), index: Yup.string().required(), }) ), }); const initialEmptyForm = useMemo( () => ({ resource_name: resourceName || '', name: '', logic_expression: '', roles: [defaultViewRole], columns: [], }), [defaultViewRole, resourceName] ); const initialForm = useMemo( () => ({ ...initialEmptyForm, ...(viewMeta ? { ...viewMeta, resource_name: viewMeta.resource?.name || resourceName, } : {}), }), [initialEmptyForm, viewMeta, resourceName] ); const { values, errors, touched, setFieldValue, getFieldProps, handleSubmit, isSubmitting, } = useFormik({ enableReinitialize: true, validationSchema: validationSchema, initialValues: { roles: [], ...pick(initialForm, Object.keys(initialEmptyForm)), logic_expression: initialForm.roles_logic_expression || '', roles: [ ...initialForm.roles.map((role) => { return { ...pick(role, Object.keys(defaultViewRole)), field_key: role.field ? role.field.key : '', }; }), ], }, onSubmit: (values, { setSubmitting }) => { if (viewMeta && viewMeta.id) { requestEditView(viewMeta.id, values).then((response) => { AppToaster.show({ message: 'the_view_has_been_edited', intent: Intent.SUCCESS, }); history.push( `${resourceMetadata.baseRoute}/${viewMeta.id}/custom_view` ); setSubmitting(false); }); } else { requestSubmitView(values).then((response) => { AppToaster.show({ message: 'the_view_has_been_submit', intent: Intent.SUCCESS, }); history.push( `${resourceMetadata.baseRoute}/${viewMeta.id}/custom_view` ); setSubmitting(false); }); } }, }); useEffect(() => { setFieldValue( 'columns', draggedColumns.map((column, index) => ({ index, key: column.key, })) ); }, [setFieldValue, draggedColumns]); const conditionalsItems = useMemo( () => [ { value: 'and', label: 'AND' }, { value: 'or', label: 'OR' }, ], [] ); const whenConditionalsItems = useMemo( () => [{ value: '', label: 'When' }], [] ); // Compatotors items. const compatatorsItems = useMemo( () => [ { value: '', label: 'Compatator' }, { value: 'equals', label: 'Equals' }, { value: 'not_equal', label: 'Not Equal' }, { value: 'contain', label: 'Contain' }, { value: 'not_contain', label: 'Not Contain' }, ], [] ); // Resource fields. const resourceFieldsOptions = useMemo( () => [ { value: '', label: 'Select a field' }, ...resourceFields.map((field) => ({ value: field.key, label: field.label_name, })), ], [resourceFields] ); // Account item of select accounts field. const selectItem = (item, { handleClick, modifiers, query }) => { return ; }; // Handle click new condition button. const onClickNewRole = useCallback(() => { setFieldValue('roles', [ ...values.roles, { ...defaultViewRole, index: values.roles.length + 1, }, ]); }, [defaultViewRole, setFieldValue, values]); // Handle click remove view role button. const onClickRemoveRole = useCallback( (viewRole, index) => { let viewRoles = [...values.roles]; // Can't continue if view roles equals or less than 1. if (viewRoles.length > 1) { viewRoles.splice(index, 1); setFieldValue( 'roles', viewRoles.map((role) => { return role; }) ); } }, [values, setFieldValue] ); const onClickDeleteView = useCallback(() => { onDelete && onDelete(viewMeta); }, [onDelete, viewMeta]); const hasError = (path) => get(errors, path) && get(touched, path); const handleClickCancelBtn = () => { history.goBack(); }; return (