Skip to content

Commit

Permalink
3654 - History (#3668)
Browse files Browse the repository at this point in the history
* 3654 - History: User interface, part 1 (#3657)

* 3654 - pt1 ui and placeholder

* use flex

* remove extra comments

* deepscan

* update button History display logic

* add DataSelector.History

* update toggle history

* 3654 - History: User interface, part 2 [RFC] (#3670)

* add NavigationHistory component

* add nav component

* 3654 - History: Refactor folder structure and separate concerns (#3683)

* 3654 - NavigationHistory -> History

* 3654 - useHistoryActive -> useIsHistoryActive

* 3654 - separate concerns for History (Hooks, Items)

* 3654 - move history to NavAssessment

* remove unnecessary filter

* fix imports

* 3654 - History: Minimal History layout (#3688)

* 3654 - return type

* 3654 - fix History Navigation classes

* 3654 - minimal history layout

* 3654 History: Add Endpoint for History (#3689)

* 3654 - initial commit for history backend

* use req.params for sectionName and target

* 3654 - use history endpoint

* 3654 - include user

* 3654 - History: Show selected history entry (#3694)

* 3654 - show history data on selecting history item

* remove unused comment string

* 3654 - reset to original state (#3695)

* requireViewHistory (#3699)

* fix old activity log for datasources (#3703)

* 3696 - reset history on navigate (#3704)

* 3654 - Update History UI (#3708)

* 3654 -Remove sectionName from HistoryTarget + Rename ButtonType blackMap -> black (#3722)

* 3654 - Remove sectionName from HistoryTarget

* 3654 - Rename ButtonType black -> blackMap

* 3654 - History: Fix old data source entries migration step (#3724)

* fix migration data-sources-reference-to-text-only

* use processEnv and nullcheck appUri

* 3654 - History: Use TablePaginated (#3727)

* 3654 - History: Use TablePaginated

* 3654 - fix deepscan

* 3654 - Add state history compare item + button ui (#3732)

* 3654 - History: compare data sources (#3734)

* 3654 - History: compare data sources

* 3654 - History: reset table paginated data

* 3654 - Fix deepscan

* 3654 - Fix deepscan

* 3654 - Update comments

* 3654 - update UI

* 3654 - History: Skeleton loader + Custom Counter (#3741)

* 3654 - History: Skeleton loader + Custom Counter

* 3654 - History: change/s en

* 3654 - History: Update translations + refactor/cleanup Select (#3749)

* 3654 - History: refactor/cleanup Select

* 3654 - update navigation border right style

* 3654 - update translations

---------

Co-authored-by: Mino Togna <minotogna@users.noreply.github.com>
Co-authored-by: minotogna <mino.togna@gmail.com>
  • Loading branch information
3 people authored Apr 19, 2024
1 parent 497a1d7 commit af88835
Show file tree
Hide file tree
Showing 125 changed files with 1,710 additions and 262 deletions.
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
"@types/d3": "^7.0.0",
"@types/d3-interpolate-path": "^2.0.0",
"@types/d3-tip": "^3.5.5",
"@types/diff": "^5.0.9",
"@types/express": "^4.17.13",
"@types/google.maps": "^3.48.3",
"@types/jest": "^27.4.1",
Expand Down Expand Up @@ -189,6 +190,7 @@
"date-fns": "^2.28.0",
"db-migrate": "^0.11.12",
"db-migrate-pg": "^1.2.2",
"diff": "^5.2.0",
"dotenv": "^16.0.0",
"downshift": "^6.1.12",
"emoji-mart-lite": "^0.6.1",
Expand Down Expand Up @@ -241,6 +243,7 @@
"react-dom": "^18.1.0",
"react-dropzone": "^14.2.3",
"react-i18next": "^11.16.2",
"react-loading-skeleton": "^3.4.0",
"react-paginate": "^8.1.4",
"react-redux": "^8.0.2",
"react-responsive": "^9.0.0-beta.6",
Expand Down
6 changes: 3 additions & 3 deletions src/client/components/Buttons/Button/Button.scss
Original file line number Diff line number Diff line change
Expand Up @@ -146,14 +146,14 @@
}
}

.button__type-blackMap {
@include withTheme($ui-black-map, 80%);
.button__type-black {
@include withTheme($ui-black-map, 90%);
}

.button__type-danger {
@include withTheme($ui-destructive, 58%);
}

.button__type-primary {
@include withTheme($ui-accent, 62%);
@include withTheme($ui-accent, 60%);
}
2 changes: 1 addition & 1 deletion src/client/components/Buttons/Button/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export enum ButtonSize {

export enum ButtonType {
anonymous = 'anonymous',
blackMap = 'blackMap',
black = 'black',
danger = 'danger',
primary = 'primary',
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { useMemo } from 'react'
import { OptionProps } from 'react-select'

import { Option, OptionsGroup, selectAllOptionValue } from 'client/components/Inputs/Select/types'
import { ToggleAllOptions } from 'client/components/Inputs/Select/toggleAllOptions'
import { Option, OptionsGroup } from 'client/components/Inputs/Select/types'

type Props = OptionProps<Option>

Expand All @@ -14,7 +15,7 @@ type Returned = {
export const useMultiSelectOptionConfig = (props: Props): Returned => {
const { data, isSelected, options, selectProps } = props

const isSelectAllOption = data.value === selectAllOptionValue
const isSelectAllOption = data.value === ToggleAllOptions.VALUE
const allOptionsCount = useMemo<number>(() => {
if (!isSelectAllOption) return 0
return options.reduce((acc, optionOrGroup) => {
Expand Down
50 changes: 11 additions & 39 deletions src/client/components/Inputs/Select/Select.tsx
Original file line number Diff line number Diff line change
@@ -1,54 +1,26 @@
import './Select.scss'
import React from 'react'
import ReactSelect, { GroupBase, SelectComponentsConfig } from 'react-select'

import classNames from 'classnames'

import { ClearIndicator, DropdownIndicator, IndicatorsContainer } from 'client/components/Inputs/Select/Indicators'
import ReactSelect from 'react-select'

import { useClassNames } from './hooks/useClassNames'
import { useComponents } from './hooks/useComponents'
import { useOnChange } from './hooks/useOnChange'
import { useToggleAllConfig } from './hooks/useToggleAllConfig'
import { useOptions } from './hooks/useOptions'
import { useValue } from './hooks/useValue'
import { SelectProps } from './types'

const Select: React.FC<SelectProps> = (props) => {
const { classNames: classes, disabled, isClearable, isMulti, options, placeholder, toggleAll } = props
const { disabled, isClearable, isMulti, placeholder } = props

const value = useValue(props)
const classNames = useClassNames(props)
const components = useComponents(props)
const onChange = useOnChange(props)

const components: Partial<SelectComponentsConfig<unknown, boolean, GroupBase<unknown>>> = {
ClearIndicator,
DropdownIndicator,
IndicatorsContainer,
IndicatorSeparator: null,
}

const { optionComponent, options: augmentedOptions } = useToggleAllConfig({ isMulti, options, toggleAll, value })

if (optionComponent) {
components.Option = optionComponent
}
const options = useOptions(props)
const value = useValue(props)

return (
<ReactSelect
classNames={{
container: () => classNames('select__container', classes?.container),
control: ({ isDisabled, isFocused }) => classNames('select__control', { isDisabled, isFocused }),
group: () => 'select__group',
groupHeading: () => 'select__groupHeading',
input: ({ isDisabled }) => classNames('select__input', { isDisabled }),
menu: ({ placement }) => classNames('select__menu', placement),
menuList: () => classNames('select__menuList'),
multiValue: ({ isDisabled }) => classNames('select__multiValue', { isDisabled }),
multiValueLabel: ({ isDisabled }) => classNames('select__multiValueLabel', { isDisabled }),
multiValueRemove: ({ isDisabled }) => classNames('select__multiValueRemove', { isDisabled }),
option: ({ isFocused, isMulti, isSelected }) =>
classNames('select__option', { isFocused, isMulti, isSelected }),
placeholder: () => `select__placeholder`,
singleValue: () => 'select__singleValue',
valueContainer: () => 'select__valueContainer',
}}
classNames={classNames}
closeMenuOnSelect={!isMulti}
components={components}
hideSelectedOptions={false}
Expand All @@ -59,7 +31,7 @@ const Select: React.FC<SelectProps> = (props) => {
menuPlacement="auto"
menuPosition="fixed"
onChange={onChange}
options={augmentedOptions}
options={options}
placeholder={placeholder ?? ''}
value={value}
/>
Expand Down
31 changes: 31 additions & 0 deletions src/client/components/Inputs/Select/hooks/useClassNames.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { useMemo } from 'react'
import { Props as ReactSelectProps } from 'react-select'

import classNames from 'classnames'

import { SelectProps } from 'client/components/Inputs/Select/types'

type Returned = ReactSelectProps['classNames']

export const useClassNames = (props: SelectProps): Returned => {
const { classNames: classes } = props

return useMemo<Returned>(() => {
return {
container: () => classNames('select__container', classes?.container),
control: ({ isDisabled, isFocused }) => classNames('select__control', { isDisabled, isFocused }),
group: () => 'select__group',
groupHeading: () => 'select__groupHeading',
input: ({ isDisabled }) => classNames('select__input', { isDisabled }),
menu: ({ placement }) => classNames('select__menu', placement),
menuList: () => classNames('select__menuList'),
multiValue: ({ isDisabled }) => classNames('select__multiValue', { isDisabled }),
multiValueLabel: ({ isDisabled }) => classNames('select__multiValueLabel', { isDisabled }),
multiValueRemove: ({ isDisabled }) => classNames('select__multiValueRemove', { isDisabled }),
option: ({ isFocused, isMulti, isSelected }) => classNames('select__option', { isFocused, isMulti, isSelected }),
placeholder: () => `select__placeholder`,
singleValue: () => 'select__singleValue',
valueContainer: () => 'select__valueContainer',
}
}, [classes?.container])
}
26 changes: 26 additions & 0 deletions src/client/components/Inputs/Select/hooks/useComponents.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { useMemo } from 'react'
import { Props as ReactSelectProps } from 'react-select'

import {
ClearIndicator,
DropdownIndicator,
IndicatorsContainer,
MultiSelectOption,
} from 'client/components/Inputs/Select/Indicators'
import { SelectProps } from 'client/components/Inputs/Select/types'

type Returned = ReactSelectProps['components']

export const useComponents = (props: SelectProps): Returned => {
const { isMulti } = props

return useMemo<Returned>(() => {
return {
ClearIndicator,
DropdownIndicator,
IndicatorsContainer,
IndicatorSeparator: null,
Option: isMulti ? MultiSelectOption : null,
}
}, [isMulti])
}
5 changes: 3 additions & 2 deletions src/client/components/Inputs/Select/hooks/useOnChange.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useCallback } from 'react'

import { Option, OptionsGroup, selectAllOptionValue, SelectProps } from 'client/components/Inputs/Select/types'
import { ToggleAllOptions } from 'client/components/Inputs/Select/toggleAllOptions'
import { Option, OptionsGroup, SelectProps } from 'client/components/Inputs/Select/types'

type Returned = (option?: Option | Array<Option>) => void

Expand All @@ -13,7 +14,7 @@ export const useOnChange = (props: SelectProps): Returned => {
const selectedValues = option.map(({ value }) => value)
if (!toggleAll) return onChange(selectedValues)

const includesSelectAll = selectedValues.includes(selectAllOptionValue)
const includesSelectAll = selectedValues.includes(ToggleAllOptions.VALUE)
// Update with only selected values (excluding "Select All")
if (!includesSelectAll) return onChange(selectedValues)

Expand Down
17 changes: 17 additions & 0 deletions src/client/components/Inputs/Select/hooks/useOptions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { useMemo } from 'react'
import { useTranslation } from 'react-i18next'

import { ToggleAllOptions } from 'client/components/Inputs/Select/toggleAllOptions'
import { OptionsOrGroups, SelectProps } from 'client/components/Inputs/Select/types'

export const useOptions = (props: SelectProps): OptionsOrGroups => {
const { isMulti, options, toggleAll, value } = props

const { t } = useTranslation()

return useMemo<OptionsOrGroups>(() => {
if (!isMulti || !toggleAll) return options

return [ToggleAllOptions.newOption({ value, t }), ...options]
}, [isMulti, options, t, toggleAll, value])
}
38 changes: 0 additions & 38 deletions src/client/components/Inputs/Select/hooks/useToggleAllConfig.ts

This file was deleted.

17 changes: 17 additions & 0 deletions src/client/components/Inputs/Select/toggleAllOptions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { TFunction } from 'i18next'

import { Option, ValueInput } from 'client/components/Inputs/Select/types'

const VALUE = '*'

const newOption = (props: { value: ValueInput; t: TFunction }): Option => {
const { value, t } = props

const label = Array.isArray(value) && value.length === 0 ? t('common.selectAll') : t('common.unselectAll')
return { label, value: VALUE }
}

export const ToggleAllOptions = {
VALUE,
newOption,
}
2 changes: 0 additions & 2 deletions src/client/components/Inputs/Select/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,3 @@ export type SelectProps = SelectBaseProps &
toggleAll?: boolean
value?: ValueInput
}

export const selectAllOptionValue = '*'
22 changes: 22 additions & 0 deletions src/client/components/Navigation/NavAssessment/History/History.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React from 'react'

import { useHistory } from 'client/store/data/hooks/useHistory'
import Items from 'client/components/Navigation/NavAssessment/History/Items'

import { useResetHistory } from './hooks/useResetHistory'

const History: React.FC = () => {
const history = useHistory()

useResetHistory()

return (
<div>
{Object.entries(history.items).map(([key, items]) => {
return <Items key={key} items={items} />
})}
</div>
)
}

export default History
Loading

0 comments on commit af88835

Please sign in to comment.