Add initial reporter
This commit is contained in:
parent
673453e08e
commit
925773ddd7
@ -28,20 +28,6 @@
|
|||||||
margin-left: 4px;
|
margin-left: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.issueDetails > .topActions .styledSelect > .dropDown > .options > .option > .type {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.issueDetails > .topActions .styledSelect > .dropDown > .options > .option > .type > .styledIcon {
|
|
||||||
font-size: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.issueDetails > .topActions .styledSelect > .dropDown > .options > .option > .type > .typeLabel {
|
|
||||||
padding: 0 5px 0 7px;
|
|
||||||
font-size: 15px
|
|
||||||
}
|
|
||||||
|
|
||||||
.issueDetails > .topActions .styledSelect > .valueContainer > .value {
|
.issueDetails > .topActions .styledSelect > .valueContainer > .value {
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
letter-spacing: 0.5px;
|
letter-spacing: 0.5px;
|
||||||
|
@ -52,6 +52,10 @@
|
|||||||
color: var(--textMedium);
|
color: var(--textMedium);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.styledSelect > .valueContainer > .placeholder {
|
||||||
|
color: var(--textLight);
|
||||||
|
}
|
||||||
|
|
||||||
.styledSelectTip {
|
.styledSelectTip {
|
||||||
padding-top: 6px;
|
padding-top: 6px;
|
||||||
color: var(--textMedium);
|
color: var(--textMedium);
|
||||||
@ -134,3 +138,21 @@
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* issue type */
|
||||||
|
|
||||||
|
.styledSelect > .dropDown > .options > .option > .type {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.styledSelect > .dropDown > .options > .option > .type > .styledIcon {
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.styledSelect > .dropDown > .options > .option > .type > .typeLabel {
|
||||||
|
padding: 0 5px 0 7px;
|
||||||
|
font-size: 15px
|
||||||
|
}
|
||||||
|
|
||||||
|
/* issue priority */
|
||||||
|
@ -36,6 +36,7 @@ pub enum FieldId {
|
|||||||
IssueTypeAddIssueModal,
|
IssueTypeAddIssueModal,
|
||||||
SummaryAddIssueModal,
|
SummaryAddIssueModal,
|
||||||
DescriptionAddIssueModal,
|
DescriptionAddIssueModal,
|
||||||
|
ReporterAddIssueModal,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Display for FieldId {
|
impl std::fmt::Display for FieldId {
|
||||||
@ -47,6 +48,7 @@ impl std::fmt::Display for FieldId {
|
|||||||
FieldId::IssueTypeAddIssueModal => f.write_str("issueTypeAddIssueModal"),
|
FieldId::IssueTypeAddIssueModal => f.write_str("issueTypeAddIssueModal"),
|
||||||
FieldId::SummaryAddIssueModal => f.write_str("summaryAddIssueModal"),
|
FieldId::SummaryAddIssueModal => f.write_str("summaryAddIssueModal"),
|
||||||
FieldId::DescriptionAddIssueModal => f.write_str("descriptionAddIssueModal"),
|
FieldId::DescriptionAddIssueModal => f.write_str("descriptionAddIssueModal"),
|
||||||
|
FieldId::ReporterAddIssueModal => f.write_str("reporterAddIssueModal"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
use seed::{prelude::*, *};
|
use seed::{prelude::*, *};
|
||||||
|
|
||||||
use jirs_data::IssueType;
|
use jirs_data::{IssueType, User};
|
||||||
|
|
||||||
|
use crate::model::Page;
|
||||||
use crate::model::{AddIssueModal, ModalType, Model};
|
use crate::model::{AddIssueModal, ModalType, Model};
|
||||||
use crate::shared::styled_button::StyledButton;
|
use crate::shared::styled_button::StyledButton;
|
||||||
use crate::shared::styled_field::StyledField;
|
use crate::shared::styled_field::StyledField;
|
||||||
@ -55,7 +56,7 @@ pub fn update(msg: &Msg, model: &mut crate::model::Model, _orders: &mut impl Ord
|
|||||||
log!(modal);
|
log!(modal);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn view(_model: &Model, modal: &AddIssueModal) -> Node<Msg> {
|
pub fn view(model: &Model, modal: &AddIssueModal) -> Node<Msg> {
|
||||||
let select_type = StyledSelect::build(FieldId::IssueTypeAddIssueModal)
|
let select_type = StyledSelect::build(FieldId::IssueTypeAddIssueModal)
|
||||||
.name("type")
|
.name("type")
|
||||||
.normal()
|
.normal()
|
||||||
@ -89,7 +90,6 @@ pub fn view(_model: &Model, modal: &AddIssueModal) -> Node<Msg> {
|
|||||||
.into_node();
|
.into_node();
|
||||||
|
|
||||||
let description = StyledTextarea::build()
|
let description = StyledTextarea::build()
|
||||||
.on_change(input_ev(Ev::Change, |_| Msg::NoOp))
|
|
||||||
.height(110)
|
.height(110)
|
||||||
.build(FieldId::DescriptionAddIssueModal)
|
.build(FieldId::DescriptionAddIssueModal)
|
||||||
.into_node();
|
.into_node();
|
||||||
@ -100,15 +100,48 @@ pub fn view(_model: &Model, modal: &AddIssueModal) -> Node<Msg> {
|
|||||||
.build()
|
.build()
|
||||||
.into_node();
|
.into_node();
|
||||||
|
|
||||||
|
let reporter_id = modal
|
||||||
|
.reporter_id
|
||||||
|
.or_else(|| model.user.as_ref().map(|u| u.id))
|
||||||
|
.unwrap_or_default();
|
||||||
|
let reporter = StyledSelect::build(FieldId::ReporterAddIssueModal)
|
||||||
|
.options(model.users.iter().map(|u| UserOption(u)).collect())
|
||||||
|
.selected(
|
||||||
|
model
|
||||||
|
.users
|
||||||
|
.iter()
|
||||||
|
.filter_map(|user| {
|
||||||
|
if user.id == reporter_id {
|
||||||
|
Some(UserOption(user))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect(),
|
||||||
|
)
|
||||||
|
.valid(true)
|
||||||
|
.build()
|
||||||
|
.into_node();
|
||||||
|
let reporter_field = StyledField::build()
|
||||||
|
.input(reporter)
|
||||||
|
.label("Reporter")
|
||||||
|
.tip("")
|
||||||
|
.build()
|
||||||
|
.into_node();
|
||||||
|
|
||||||
let submit = StyledButton::build()
|
let submit = StyledButton::build()
|
||||||
.primary()
|
.primary()
|
||||||
.text("Create Issue")
|
.text("Create Issue")
|
||||||
.add_class("action")
|
.add_class("action")
|
||||||
|
.add_class("submit")
|
||||||
|
.add_class("ActionButton")
|
||||||
.build()
|
.build()
|
||||||
.into_node();
|
.into_node();
|
||||||
let cancel = StyledButton::build()
|
let cancel = StyledButton::build()
|
||||||
.empty()
|
.empty()
|
||||||
.add_class("action")
|
.add_class("action")
|
||||||
|
.add_class("cancel")
|
||||||
|
.add_class("actionButton")
|
||||||
.text("Cancel")
|
.text("Cancel")
|
||||||
.build()
|
.build()
|
||||||
.into_node();
|
.into_node();
|
||||||
@ -120,12 +153,14 @@ pub fn view(_model: &Model, modal: &AddIssueModal) -> Node<Msg> {
|
|||||||
.add_field(crate::shared::divider())
|
.add_field(crate::shared::divider())
|
||||||
.add_field(short_summary_field)
|
.add_field(short_summary_field)
|
||||||
.add_field(description_field)
|
.add_field(description_field)
|
||||||
|
.add_field(reporter_field)
|
||||||
.add_field(actions)
|
.add_field(actions)
|
||||||
.build()
|
.build()
|
||||||
.into_node();
|
.into_node();
|
||||||
|
|
||||||
StyledModal::build()
|
StyledModal::build()
|
||||||
.width(800)
|
.width(800)
|
||||||
|
.add_class("add-issue")
|
||||||
.variant(ModalVariant::Center)
|
.variant(ModalVariant::Center)
|
||||||
.children(vec![form])
|
.children(vec![form])
|
||||||
.build()
|
.build()
|
||||||
@ -140,7 +175,7 @@ impl crate::shared::styled_select::SelectOption for IssueTypeOption {
|
|||||||
let name = self.0.to_label().to_owned();
|
let name = self.0.to_label().to_owned();
|
||||||
|
|
||||||
let icon = StyledIcon::build(self.0.into())
|
let icon = StyledIcon::build(self.0.into())
|
||||||
.add_class("issueTypeIcon".to_string())
|
.add_class("issueTypeIcon")
|
||||||
.build()
|
.build()
|
||||||
.into_node();
|
.into_node();
|
||||||
|
|
||||||
@ -174,3 +209,34 @@ impl crate::shared::styled_select::SelectOption for IssueTypeOption {
|
|||||||
self.0.clone().into()
|
self.0.clone().into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq)]
|
||||||
|
pub struct UserOption<'opt>(pub &'opt User);
|
||||||
|
|
||||||
|
impl<'opt> crate::shared::styled_select::SelectOption for UserOption<'opt> {
|
||||||
|
fn into_option(self) -> Node<Msg> {
|
||||||
|
let user = self.0;
|
||||||
|
|
||||||
|
div![
|
||||||
|
attrs![At::Class => "type"],
|
||||||
|
div![attrs![At::Class => "typeLabel"], user.name]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn into_value(self) -> Node<Msg> {
|
||||||
|
let user = self.0;
|
||||||
|
|
||||||
|
div![
|
||||||
|
attrs![At::Class => "selectItem"],
|
||||||
|
div![attrs![At::Class => "selectItemLabel"], user.name]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn match_text_filter(&self, _text_filter: &str) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_value(&self) -> u32 {
|
||||||
|
self.0.id as u32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -39,10 +39,17 @@ pub struct AddIssueModal {
|
|||||||
pub time_remaining: Option<i32>,
|
pub time_remaining: Option<i32>,
|
||||||
pub project_id: i32,
|
pub project_id: i32,
|
||||||
pub user_ids: Vec<i32>,
|
pub user_ids: Vec<i32>,
|
||||||
|
pub reporter_id: Option<i32>,
|
||||||
|
|
||||||
// modal fields
|
// modal fields
|
||||||
pub type_select_filter: String,
|
pub type_select_filter: String,
|
||||||
pub type_select_opened: bool,
|
pub type_select_opened: bool,
|
||||||
|
|
||||||
|
pub reporter_select_filter: String,
|
||||||
|
pub reporter_select_opened: bool,
|
||||||
|
|
||||||
|
pub assignees_select_filter: String,
|
||||||
|
pub assignees_select_opened: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialOrd, PartialEq)]
|
#[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialOrd, PartialEq)]
|
||||||
|
@ -78,8 +78,11 @@ impl StyledModalBuilder {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_class(mut self, name: String) -> Self {
|
pub fn add_class<S>(mut self, name: S) -> Self
|
||||||
self.class_list.push(name);
|
where
|
||||||
|
S: Into<String>,
|
||||||
|
{
|
||||||
|
self.class_list.push(name.into());
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
|
use seed::{prelude::*, *};
|
||||||
|
|
||||||
use crate::shared::ToNode;
|
use crate::shared::ToNode;
|
||||||
use crate::{FieldId, Msg};
|
use crate::{FieldId, Msg};
|
||||||
use seed::{prelude::*, *};
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct StyledTextarea {
|
pub struct StyledTextarea {
|
||||||
id: FieldId,
|
id: FieldId,
|
||||||
height: usize,
|
height: usize,
|
||||||
on_change: Option<EventHandler<Msg>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToNode for StyledTextarea {
|
impl ToNode for StyledTextarea {
|
||||||
@ -33,16 +33,10 @@ impl StyledTextareaBuilder {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn on_change(mut self, on_change: EventHandler<Msg>) -> Self {
|
|
||||||
self.on_change = Some(on_change);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn build(self, id: FieldId) -> StyledTextarea {
|
pub fn build(self, id: FieldId) -> StyledTextarea {
|
||||||
StyledTextarea {
|
StyledTextarea {
|
||||||
id,
|
id,
|
||||||
height: self.height.unwrap_or(110),
|
height: self.height.unwrap_or(110),
|
||||||
on_change: self.on_change,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -61,20 +55,13 @@ const ADDITIONAL_HEIGHT: f64 = PADDING_TOP_BOTTOM + BORDER_TOP_BOTTOM;
|
|||||||
// * 17 is padding top + bottom
|
// * 17 is padding top + bottom
|
||||||
// * 2 is border top + bottom
|
// * 2 is border top + bottom
|
||||||
pub fn render(values: StyledTextarea) -> Node<Msg> {
|
pub fn render(values: StyledTextarea) -> Node<Msg> {
|
||||||
let StyledTextarea {
|
let StyledTextarea { id, height } = values;
|
||||||
id,
|
|
||||||
height,
|
|
||||||
on_change,
|
|
||||||
} = values;
|
|
||||||
let mut style_list = vec![];
|
let mut style_list = vec![];
|
||||||
style_list.push(format!("min-height: {}px", height));
|
style_list.push(format!("min-height: {}px", height));
|
||||||
|
|
||||||
let mut handlers = vec![];
|
let mut handlers = vec![];
|
||||||
if let Some(handler) = on_change {
|
|
||||||
handlers.push(handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
let resize_handler = ev(Ev::KeyPress, move |event| {
|
let resize_handler = ev(Ev::KeyUp, move |event| {
|
||||||
use wasm_bindgen::JsCast;
|
use wasm_bindgen::JsCast;
|
||||||
|
|
||||||
let target = match event.target() {
|
let target = match event.target() {
|
||||||
@ -98,7 +85,7 @@ pub fn render(values: StyledTextarea) -> Node<Msg> {
|
|||||||
Msg::NoOp
|
Msg::NoOp
|
||||||
});
|
});
|
||||||
handlers.push(resize_handler);
|
handlers.push(resize_handler);
|
||||||
let text_input_handler = input_ev(Ev::KeyPress, move |value| Msg::InputChanged(id, value));
|
let text_input_handler = input_ev(Ev::KeyUp, move |value| Msg::InputChanged(id, value));
|
||||||
handlers.push(text_input_handler);
|
handlers.push(text_input_handler);
|
||||||
|
|
||||||
div![
|
div![
|
||||||
|
@ -306,7 +306,7 @@ pub struct Comment {
|
|||||||
pub user: Option<User>,
|
pub user: Option<User>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct User {
|
pub struct User {
|
||||||
pub id: i32,
|
pub id: i32,
|
||||||
|
@ -11,6 +11,7 @@ import {
|
|||||||
import toast from '../../shared/utils/toast';
|
import toast from '../../shared/utils/toast';
|
||||||
import api from '../../shared/utils/api';
|
import api from '../../shared/utils/api';
|
||||||
import { Avatar, Form, Icon, IssuePriorityIcon, IssueTypeIcon } from '../../shared/components';
|
import { Avatar, Form, Icon, IssuePriorityIcon, IssueTypeIcon } from '../../shared/components';
|
||||||
|
import { Field } from "../../shared/components/Form";
|
||||||
|
|
||||||
import { ActionButton, Actions, Divider, FormElement, FormHeading, SelectItem, SelectItemLabel, } from './Styles';
|
import { ActionButton, Actions, Divider, FormElement, FormHeading, SelectItem, SelectItemLabel, } from './Styles';
|
||||||
|
|
||||||
@ -68,7 +69,7 @@ class ProjectIssueCreate extends React.Component {
|
|||||||
<FormHeading>
|
<FormHeading>
|
||||||
Create issue
|
Create issue
|
||||||
</FormHeading>
|
</FormHeading>
|
||||||
<Form.Field.Select
|
<Field.Select
|
||||||
name="type"
|
name="type"
|
||||||
label="Issue Type"
|
label="Issue Type"
|
||||||
tip="Start typing to get a list of possible matches."
|
tip="Start typing to get a list of possible matches."
|
||||||
@ -77,19 +78,19 @@ class ProjectIssueCreate extends React.Component {
|
|||||||
renderValue={ renderType }
|
renderValue={ renderType }
|
||||||
/>
|
/>
|
||||||
<Divider/>
|
<Divider/>
|
||||||
<Form.Field.Input
|
<Field.Input
|
||||||
name="title"
|
name="title"
|
||||||
label="Short Summary"
|
label="Short Summary"
|
||||||
tip="Concisely summarize the issue in one or two sentences."
|
tip="Concisely summarize the issue in one or two sentences."
|
||||||
onChange={ this.onInputChange }
|
onChange={ this.onInputChange }
|
||||||
/>
|
/>
|
||||||
<Form.Field.TextEditor
|
<Field.TextEditor
|
||||||
name="description"
|
name="description"
|
||||||
label="Description"
|
label="Description"
|
||||||
tip="Describe the issue in as much detail as you'd like."
|
tip="Describe the issue in as much detail as you'd like."
|
||||||
onChange={ this.onInputChange }
|
onChange={ this.onInputChange }
|
||||||
/>
|
/>
|
||||||
<Form.Field.Select
|
<Field.Select
|
||||||
name="reporterId"
|
name="reporterId"
|
||||||
label="Reporter"
|
label="Reporter"
|
||||||
options={ userOptions(project) }
|
options={ userOptions(project) }
|
||||||
@ -97,7 +98,7 @@ class ProjectIssueCreate extends React.Component {
|
|||||||
renderValue={ renderUser(project) }
|
renderValue={ renderUser(project) }
|
||||||
onChange={ this.onInputChange }
|
onChange={ this.onInputChange }
|
||||||
/>
|
/>
|
||||||
<Form.Field.Select
|
<Field.Select
|
||||||
isMulti
|
isMulti
|
||||||
name="userIds"
|
name="userIds"
|
||||||
label="Assignees"
|
label="Assignees"
|
||||||
@ -107,7 +108,7 @@ class ProjectIssueCreate extends React.Component {
|
|||||||
renderOption={ renderUser(project) }
|
renderOption={ renderUser(project) }
|
||||||
renderValue={ renderUser(project) }
|
renderValue={ renderUser(project) }
|
||||||
/>
|
/>
|
||||||
<Form.Field.Select
|
<Field.Select
|
||||||
name="priority"
|
name="priority"
|
||||||
label="Priority"
|
label="Priority"
|
||||||
tip="Priority in relation to other issues."
|
tip="Priority in relation to other issues."
|
||||||
|
@ -1,12 +1,20 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { Field as FormikField, Form as FormikForm, Formik } from 'formik';
|
import { Field as FormikField, Form as FormikForm, Formik } from 'formik';
|
||||||
import { get, mapValues } from 'lodash';
|
import { get } from 'lodash';
|
||||||
|
|
||||||
import toast from 'shared/utils/toast';
|
import toast from 'shared/utils/toast';
|
||||||
import { generateErrors, is } from 'shared/utils/validation';
|
import { generateErrors, is } from 'shared/utils/validation';
|
||||||
|
|
||||||
import Field from './Field';
|
import FieldComponents from './Field';
|
||||||
|
|
||||||
|
const {
|
||||||
|
Input,
|
||||||
|
Select,
|
||||||
|
Textarea,
|
||||||
|
TextEditor,
|
||||||
|
DatePicker,
|
||||||
|
} = FieldComponents;
|
||||||
|
|
||||||
const propTypes = {
|
const propTypes = {
|
||||||
validate: PropTypes.func,
|
validate: PropTypes.func,
|
||||||
@ -31,14 +39,16 @@ const Form = ({ validate, validations, ...otherProps }) => (
|
|||||||
return generateErrors(values, validations);
|
return generateErrors(values, validations);
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
}}
|
} }
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
Form.Element = props => <FormikForm noValidate {...props} />;
|
export const Element = props => <FormikForm noValidate { ...props } />;
|
||||||
|
|
||||||
Form.Field = mapValues(Field, FieldComponent => ({ name, validate, ...props }) => {
|
Form.Element = Element;
|
||||||
return (
|
|
||||||
|
export const Field = {
|
||||||
|
Input: ({ name, validate, ...props }) => (
|
||||||
<FormikField name={ name } validate={ validate }>
|
<FormikField name={ name } validate={ validate }>
|
||||||
{ ({ field, form: { touched, errors, setFieldValue } }) => {
|
{ ({ field, form: { touched, errors, setFieldValue } }) => {
|
||||||
const onChange = value => {
|
const onChange = value => {
|
||||||
@ -49,7 +59,7 @@ Form.Field = mapValues(Field, FieldComponent => ({ name, validate, ...props }) =
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FieldComponent
|
<Input
|
||||||
{ ...field }
|
{ ...field }
|
||||||
{ ...props }
|
{ ...props }
|
||||||
name={ name }
|
name={ name }
|
||||||
@ -59,8 +69,98 @@ Form.Field = mapValues(Field, FieldComponent => ({ name, validate, ...props }) =
|
|||||||
)
|
)
|
||||||
} }
|
} }
|
||||||
</FormikField>
|
</FormikField>
|
||||||
|
),
|
||||||
|
Select: ({ name, validate, ...props }) => (
|
||||||
|
<FormikField name={ name } validate={ validate }>
|
||||||
|
{ ({ field, form: { touched, errors, setFieldValue } }) => {
|
||||||
|
const onChange = value => {
|
||||||
|
if (props.onChange) {
|
||||||
|
props.onChange(name, value)
|
||||||
|
}
|
||||||
|
setFieldValue(name, value)
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Select
|
||||||
|
{ ...field }
|
||||||
|
{ ...props }
|
||||||
|
name={ name }
|
||||||
|
error={ get(touched, name) && get(errors, name) }
|
||||||
|
onChange={ onChange }
|
||||||
|
/>
|
||||||
)
|
)
|
||||||
});
|
} }
|
||||||
|
</FormikField>
|
||||||
|
),
|
||||||
|
Textarea: ({ name, validate, ...props }) => (
|
||||||
|
<FormikField name={ name } validate={ validate }>
|
||||||
|
{ ({ field, form: { touched, errors, setFieldValue } }) => {
|
||||||
|
const onChange = value => {
|
||||||
|
if (props.onChange) {
|
||||||
|
props.onChange(name, value)
|
||||||
|
}
|
||||||
|
setFieldValue(name, value)
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Textarea
|
||||||
|
{ ...field }
|
||||||
|
{ ...props }
|
||||||
|
name={ name }
|
||||||
|
error={ get(touched, name) && get(errors, name) }
|
||||||
|
onChange={ onChange }
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
} }
|
||||||
|
</FormikField>
|
||||||
|
),
|
||||||
|
TextEditor: ({ name, validate, ...props }) => (
|
||||||
|
<FormikField name={ name } validate={ validate }>
|
||||||
|
{ ({ field, form: { touched, errors, setFieldValue } }) => {
|
||||||
|
const onChange = value => {
|
||||||
|
if (props.onChange) {
|
||||||
|
props.onChange(name, value)
|
||||||
|
}
|
||||||
|
setFieldValue(name, value)
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TextEditor
|
||||||
|
{ ...field }
|
||||||
|
{ ...props }
|
||||||
|
name={ name }
|
||||||
|
error={ get(touched, name) && get(errors, name) }
|
||||||
|
onChange={ onChange }
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
} }
|
||||||
|
</FormikField>
|
||||||
|
),
|
||||||
|
DatePicker: ({ name, validate, ...props }) => (
|
||||||
|
<FormikField name={ name } validate={ validate }>
|
||||||
|
{ ({ field, form: { touched, errors, setFieldValue } }) => {
|
||||||
|
const onChange = value => {
|
||||||
|
if (props.onChange) {
|
||||||
|
props.onChange(name, value)
|
||||||
|
}
|
||||||
|
setFieldValue(name, value)
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DatePicker
|
||||||
|
{ ...field }
|
||||||
|
{ ...props }
|
||||||
|
name={ name }
|
||||||
|
error={ get(touched, name) && get(errors, name) }
|
||||||
|
onChange={ onChange }
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
} }
|
||||||
|
</FormikField>
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
|
Form.Field = Field;
|
||||||
|
|
||||||
Form.initialValues = (data, getFieldValues) =>
|
Form.initialValues = (data, getFieldValues) =>
|
||||||
getFieldValues((key, defaultValue = '') => {
|
getFieldValues((key, defaultValue = '') => {
|
||||||
|
Loading…
Reference in New Issue
Block a user