Skip to content

Commit

Permalink
adds validation
Browse files Browse the repository at this point in the history
  • Loading branch information
tiagoapolo committed Feb 20, 2025
1 parent 9050239 commit 5d0e175
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 19 deletions.
20 changes: 17 additions & 3 deletions frontend/web/components/DateSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,35 @@ import { useState, FC } from 'react'

export interface DateSelectProps
extends Pick<DatePickerProps, 'dateFormat' | 'selected' | 'value'> {
className?: string
isValid?: boolean
onChange?: (
date: Date | null,
event?: React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLElement>,
) => void
}

const DateSelect: FC<DateSelectProps> = ({
className,
dateFormat,
isValid,
onChange,
selected,
value,
}) => {
const [isMonthPicker, setIsMonthPicker] = useState(false)
const [isYearPicker, setIsYearPicker] = useState(false)
const [touched, setTouched] = useState(false)
const [isOpen, setIsOpen] = useState(false)

return (
<Flex style={{ position: 'relative' }}>
<DatePicker
className={`input-lg ${className} ${
!isValid && touched ? 'invalid' : ''
}`}
dateFormat={dateFormat}
onFocus={() => setTouched(true)}
renderCustomHeader={({
date,
decreaseMonth,
Expand Down Expand Up @@ -79,9 +88,15 @@ const DateSelect: FC<DateSelectProps> = ({
)}
minDate={new Date()}
onChange={(date, e): DatePickerProps['onChange'] => {
if (!date) return
if (date === null) {
setIsMonthPicker(false)
setIsYearPicker(false)
onChange?.(null)
return
}

if (date < new Date()) {
const today = new Date()
if (date < today) {
setIsMonthPicker(false)
setIsYearPicker(false)
onChange?.(new Date())
Expand All @@ -99,7 +114,6 @@ const DateSelect: FC<DateSelectProps> = ({
setIsYearPicker(false)
}
}}
className='input-lg'
formatWeekDay={(nameOfDay) => nameOfDay.substr(0, 1)}
showTimeSelect={!isMonthPicker && !isYearPicker}
showMonthYearPicker={isMonthPicker}
Expand Down
2 changes: 0 additions & 2 deletions frontend/web/components/ExistingChangeRequestAlert.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,6 @@ const ExistingChangeRequestAlert: FC<ExistingChangeRequestAlertType> = ({
!!changeRequests?.length,
)

console.log({ requestChangeInfoText })

if (!requestChangeInfoText?.length) {
return null
}
Expand Down
52 changes: 42 additions & 10 deletions frontend/web/components/modals/ChangeRequestModal.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import React, { useState, useEffect, FC } from 'react'
import React, { useState, useEffect, FC, useMemo } from 'react'
import UserSelect from 'components/UserSelect'
import OrganisationProvider from 'common/providers/OrganisationProvider'
import Button from 'components/base/forms/Button'
import MyGroupsSelect from 'components/MyGroupsSelect'
import { getMyGroups } from 'common/services/useMyGroup'
import { getStore } from 'common/store'
import DateSelect from 'components/DateSelect'
import DateSelect, { DateSelectProps } from 'components/DateSelect'
import { close } from 'ionicons/icons'
import { IonIcon } from '@ionic/react'
import InfoMessage from 'components/InfoMessage'
Expand All @@ -27,25 +27,28 @@ interface ChangeRequestModalProps {
live_from?: string
title: string
}) => void
isScheduledChange?: boolean
showAssignees?: boolean
}

const ChangeRequestModal: FC<ChangeRequestModalProps> = ({
changeRequest,
isScheduledChange,
onSave,
showAssignees,
}) => {
const [approvals, setApprovals] = useState(changeRequest?.approvals || [])
const [description, setDescription] = useState(
changeRequest?.description || '',
changeRequest?.description ?? '',
)
const [groups, setGroups] = useState([])
const [liveFrom, setLiveFrom] = useState(
changeRequest?.feature_states[0].live_from || undefined,
changeRequest?.feature_states[0]?.live_from,
)
const [title, setTitle] = useState(changeRequest?.title || '')
const [title, setTitle] = useState(changeRequest?.title ?? '')
const [showUsers, setShowUsers] = useState(false)
const [showGroups, setShowGroups] = useState(false)
const [currDate, setCurrDate] = useState(new Date())

useEffect(() => {
getMyGroups(getStore(), { orgId: AccountStore.getOrganisation().id }).then(
Expand All @@ -55,6 +58,13 @@ const ChangeRequestModal: FC<ChangeRequestModalProps> = ({
)
}, [])

useEffect(() => {
const currLiveFromDate = changeRequest?.feature_states[0]?.live_from
if (!currLiveFromDate) {
return setLiveFrom(showAssignees ? currDate.toISOString() : undefined)
}
}, [isScheduledChange, showAssignees, changeRequest, currDate])

const addOwner = (id: number, isUser = true) => {
setApprovals((prev) => [...prev, isUser ? { user: id } : { group: id }])
}
Expand All @@ -80,6 +90,20 @@ const ChangeRequestModal: FC<ChangeRequestModalProps> = ({
})
}

const handleClear = () => {
const newCurrDate = new Date()
setCurrDate(newCurrDate)
setLiveFrom(showAssignees ? newCurrDate.toISOString() : undefined)
}

const handleOnDateChange: DateSelectProps['onChange'] = (date) => {
setLiveFrom(date?.toISOString())
}

const isValid = useMemo(() => {
return !!title?.length && !!liveFrom
}, [title, liveFrom])

return (
<OrganisationProvider>
{({ users }) => {
Expand Down Expand Up @@ -123,13 +147,14 @@ const ChangeRequestModal: FC<ChangeRequestModalProps> = ({
component={
<Row>
<DateSelect
isValid={!!liveFrom?.length}
dateFormat='MMMM d, yyyy h:mm aa'
onChange={(e) => setLiveFrom(e?.toISOString())}
selected={moment(liveFrom).toDate()}
onChange={handleOnDateChange}
selected={liveFrom ? moment(liveFrom).toDate() : null}
/>
<Button
className='ml-2'
onClick={() => setLiveFrom(undefined)}
onClick={handleClear}
theme='secondary'
size='large'
>
Expand All @@ -139,7 +164,14 @@ const ChangeRequestModal: FC<ChangeRequestModalProps> = ({
}
/>
</div>
{moment(liveFrom).isAfter(moment()) && (
{showAssignees && moment(liveFrom).isSame(currDate) && (
<InfoMessage>
<strong>
Changes will take effect immediately after approval.
</strong>
</InfoMessage>
)}
{liveFrom && moment(liveFrom).isAfter(moment()) && (
<InfoMessage>
This change will be scheduled to go live at{' '}
<strong>
Expand Down Expand Up @@ -251,7 +283,7 @@ const ChangeRequestModal: FC<ChangeRequestModalProps> = ({
<Button
id='confirm-cancel-plan'
className='btn btn-primary'
disabled={!title}
disabled={!isValid}
onClick={save}
>
{changeRequest ? 'Update' : 'Create'}
Expand Down
5 changes: 1 addition & 4 deletions frontend/web/components/modals/CreateFlag.js
Original file line number Diff line number Diff line change
Expand Up @@ -573,7 +573,6 @@ const CreateFlag = class extends Component {

const date = moment().toISOString()

console.log('data', date)
getChangeRequests(
getStore(),
{
Expand Down Expand Up @@ -623,9 +622,6 @@ const CreateFlag = class extends Component {
let regexValid = true
const metadataEnable = Utils.getPlansPermission('METADATA')

const { changeRequests, scheduledChangeRequests } = this.state
console.log({ changeRequests, out: true, scheduledChangeRequests })

try {
if (!isEdit && name && regex) {
regexValid = name.match(new RegExp(regex))
Expand Down Expand Up @@ -967,6 +963,7 @@ const CreateFlag = class extends Component {
: 'New Change Request',
<ChangeRequestModal
showAssignees={is4Eyes}
isScheduledChange={schedule}
changeRequest={this.props.changeRequest}
onSave={({
approvals,
Expand Down
5 changes: 5 additions & 0 deletions frontend/web/styles/3rdParty/_react-datepicker.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@
right: 12px;
}

.react-datepicker-wrapper .react-datepicker__input-container {
input[type=text].invalid, input[type=password].invalid {
border: 1px solid $danger;
}
}
.react-datepicker__triangle {
display: none;
}
Expand Down

0 comments on commit 5d0e175

Please sign in to comment.