Skip to content

Commit

Permalink
Merge branch '3989-review-comments-visible-in-review-status' of githu…
Browse files Browse the repository at this point in the history
…b.com:openforis/fra-platform into 3989-review-comments-visible-in-review-status
  • Loading branch information
sorja committed Oct 7, 2024
2 parents 0f3c73b + d671e0c commit 41ac12d
Show file tree
Hide file tree
Showing 304 changed files with 1,214 additions and 65,370 deletions.
16 changes: 16 additions & 0 deletions .run/db_backup-import.run.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="db:backup-import" type="ShConfigurationType">
<option name="SCRIPT_TEXT" value="(cd src/tools/db/importBackup &amp;&amp; ./exec.sh) &amp;&amp; ts-node src/tools/generateCache/index.ts" />
<option name="INDEPENDENT_SCRIPT_PATH" value="true" />
<option name="SCRIPT_OPTIONS" value="" />
<option name="INDEPENDENT_SCRIPT_WORKING_DIRECTORY" value="true" />
<option name="SCRIPT_WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="INDEPENDENT_INTERPRETER_PATH" value="true" />
<option name="INTERPRETER_PATH" value="/bin/zsh" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="EXECUTE_IN_TERMINAL" value="true" />
<option name="EXECUTE_SCRIPT_FILE" value="false" />
<envs />
<method v="2" />
</configuration>
</component>
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,16 @@
"heroku-cleanup": "cd node_modules/bcrypt && node-pre-gyp install --fallback-to-build",
"migration-public:create": "src/tools/migrations/public/create-migration-step.sh",
"migration-public:run": "ts-node src/tools/migrations/public",
"migration-steps:create": "src/test/migrations/create-migration-step.sh",
"migration-steps:create": "ts-node src/test/migrations/createMigrationStep.ts",
"migration-steps:reset": "ts-node src/test/migrations/reset.ts",
"migration-steps:run": "ts-node src/test/migrations/",
"migration-steps:watch": "ts-node-dev --respawn --transpile-only --exit-child --watch src/test/migrations/ src/test/migrations/ -- --watch",
"run:dev": "run-p run:dev:client run:dev:server",
"run:dev:client": "cross-env NODE_ENV=development webpack serve --config webpack.config.babel.js",
"run:dev:server": "yarn migration-public:run && ts-node-dev --exit-child src/server/start",
"run:prod": "run-s build start",
"run:prod:server": "node dist/server/start",
"start": "yarn run:prod:server",
"start": "run-s migration-public:run run:prod:server",
"metacache:generate": "ts-node src/tools/generateMetaCache/",
"//test": "mochapack --webpack-config webpack.config.babel.test.js",
"test": "run-s test:integration",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useMemo } from 'react'
import { useTranslation } from 'react-i18next'

import { Assessments, Cycles } from 'meta/assessment'
import { Assessments, Cycle, Cycles } from 'meta/assessment'
import { Users } from 'meta/user'

import { useAssessments } from 'client/store/assessment'
Expand All @@ -12,6 +12,27 @@ import { PopoverItem } from 'client/components/PopoverControl'

import { useNavigateTo } from './useNavigateTo'

const _cyclesSorter = (cycleA: Cycle, cycleB: Cycle): number => {
const dateEditingA = cycleA.props.dateEditing
const dateEditingB = cycleB.props.dateEditing
if (dateEditingA && dateEditingB) {
return new Date(dateEditingB).getTime() - new Date(dateEditingA).getTime()
}

const dateCreatedA = cycleA.props.dateCreated
const dateCreatedB = cycleB.props.dateCreated
if (dateCreatedA && dateCreatedB) {
return new Date(dateCreatedB).getTime() - new Date(dateCreatedA).getTime()
}
if (dateCreatedA) {
return -1
}
if (dateCreatedB) {
return 1
}
return 0
}

export const usePopoverItems = (): Array<PopoverItem> => {
const { t } = useTranslation()
const routeParams = useCycleRouteParams()
Expand All @@ -26,7 +47,8 @@ export const usePopoverItems = (): Array<PopoverItem> => {

if (!isDataExportView && user) {
assessments.forEach((assessment) => {
assessment.cycles.forEach((cycle) => {
const sortedCycles = assessment.cycles.slice().sort(_cyclesSorter)
sortedCycles.forEach((cycle) => {
const hasRoleInAssessment = Users.hasRoleInAssessment({ user, assessment })
const hasRoleInCycle = Users.hasRoleInCycle({ user, cycle })
const canViewCycle = (hasRoleInAssessment && Cycles.isPublished(cycle)) || hasRoleInCycle
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
@import 'src/client/style/partials';

.table-paginated-empty-list {
color: $text-disabled;
font-weight: bold;
grid-column: 1 / -1;
padding: $spacing-xxl 0;
text-align: center;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import './DefaultEmptyList.scss'
import React from 'react'
import { useTranslation } from 'react-i18next'

const DefaultEmptyList: React.FC = () => {
const { t } = useTranslation()

return <div className="table-paginated-empty-list">{t('common.noItemsFound')}</div>
}

export default DefaultEmptyList
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './DefaultEmptyList'
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import './ExportButton.scss'
import React from 'react'
import { Link } from 'react-router-dom'

import { useTablePaginatedCount } from 'client/store/ui/tablePaginated'
import { useButtonClassName } from 'client/components/Buttons/Button'
import Icon from 'client/components/Icon'

Expand All @@ -16,7 +17,11 @@ const ExportButton: React.FC<Props> = (props) => {

const exportUrl = useExportUrl({ path })

const className = useButtonClassName({ iconName: 'hit-down' })
const count = useTablePaginatedCount(path)
const disabled = count?.total === 0

const className = useButtonClassName({ disabled, iconName: 'hit-down' })

return (
<div className="table-paginated-export-button">
<Link className={className} target="_blank" to={exportUrl}>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { useMemo } from 'react'

import { TablePaginateds } from 'meta/tablePaginated'

import { useTablePaginatedOrderBy } from 'client/store/ui/tablePaginated'
import { useTablePaginatedFilters } from 'client/store/ui/tablePaginated/hooks'
import { useSectionRouteParams } from 'client/hooks/useRouteParams'

type Props = {
Expand All @@ -12,18 +15,21 @@ export const useExportUrl = (props: Props): string => {

const { assessmentName, countryIso, cycleName, sectionName } = useSectionRouteParams()
const orderBy = useTablePaginatedOrderBy(path)
const filters = useTablePaginatedFilters(path)

return useMemo<string>(() => {
const encodedFilters = TablePaginateds.encodeFilters(filters)
const queryParams = new URLSearchParams(
Object.entries({
assessmentName,
countryIso,
cycleName,
filters: encodedFilters,
orderBy: orderBy?.property,
orderByDirection: orderBy?.direction,
sectionName,
}).filter(([, value]) => value !== undefined)
)
return `${path}/export?${queryParams.toString()}`
}, [assessmentName, countryIso, cycleName, orderBy, path, sectionName])
}, [assessmentName, countryIso, cycleName, filters, orderBy, path, sectionName])
}
12 changes: 12 additions & 0 deletions src/client/components/TablePaginated/Filters/Filters.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
@import 'src/client/style/partials';

.table-paginated-filters {
align-items: center;
display: flex;
gap: $spacing-xxs;
width: 100%;

svg.icon_filter {
color: $ui-accent-dark;
}
}
45 changes: 45 additions & 0 deletions src/client/components/TablePaginated/Filters/Filters.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import './Filters.scss'
import React from 'react'

import { TablePaginatedFilterType } from 'meta/tablePaginated'

import Icon from 'client/components/Icon'
import Text from 'client/components/TablePaginated/Filters/Text/Text'
import { TablePaginatedFilter } from 'client/components/TablePaginated/types'

const componentsByFilterType: Record<
TablePaginatedFilterType,
React.FC<TablePaginatedFilter<TablePaginatedFilterType> & { path: string }>
> = {
[TablePaginatedFilterType.TEXT]: Text,
[TablePaginatedFilterType.SWITCH]: () => null,
}

type Props = {
filters: Array<TablePaginatedFilter<TablePaginatedFilterType>>
path: string
}

const Filters: React.FC<Props> = (props: Props) => {
const { filters, path } = props

return (
<div className="table-paginated-filters">
<Icon name="filter" />
{filters.map((filter) => {
if (filter.hidden) return null
const Component = componentsByFilterType[filter.type]
return (
<Component
key={filter.fieldName}
// eslint-disable-next-line react/jsx-props-no-spreading
{...filter}
path={path}
/>
)
})}
</div>
)
}

export default Filters
48 changes: 48 additions & 0 deletions src/client/components/TablePaginated/Filters/Text/Text.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
@import 'src/client/style/partials';

.table-paginated-filter-input {
display: inline-block;
position: relative;

input {
border: 1px solid $ui-border;
border-radius: 2px;
font-size: $font-xxs;
padding: 6px;
transition: all 0.2s ease;
}

button.clear-button {
background-color: #ffffff;
border: none;
height: $spacing-xs;
padding: 0;
position: absolute;
right: $spacing-xxxs;
top: 50%;
transform: translateY(-50%);
width: $spacing-xs;

svg {
height: 14px;
width: 14px;
}

&:hover {
svg {
color: $ui-destructive;
}
}

&.disabled {
opacity: 0.6;
pointer-events: none;
}
}

&.active {
input {
border: 1px solid $ui-accent;
}
}
}
55 changes: 55 additions & 0 deletions src/client/components/TablePaginated/Filters/Text/Text.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import './Text.scss'
import React from 'react'

import classNames from 'classnames'
import { Objects } from 'utils/objects'

import { TablePaginatedFilterType } from 'meta/tablePaginated'

import { useAppDispatch } from 'client/store'
import { TablePaginatedActions } from 'client/store/ui/tablePaginated'
import { useTablePaginatedFilterValue } from 'client/store/ui/tablePaginated/hooks'
import Icon from 'client/components/Icon'
import InputText from 'client/components/Inputs/InputText'
import { TablePaginatedFilter } from 'client/components/TablePaginated/types'

type Props = TablePaginatedFilter<TablePaginatedFilterType.TEXT> & {
path: string
}

const Text = (props: Props) => {
const { fieldName, label, path } = props
const dispatch = useAppDispatch()

const filterValue = useTablePaginatedFilterValue<string>(path, fieldName)

const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const { value } = event.target
dispatch(
TablePaginatedActions.setFilterValue({
fieldName,
path,
value,
})
)
}

const handleClearInput = () => {
dispatch(TablePaginatedActions.resetFilter({ fieldName, path }))
}

return (
<div className={classNames('table-paginated-filter-input', { active: !Objects.isEmpty(filterValue) })}>
<InputText onChange={handleChange} placeholder={label} value={filterValue ?? ''} />
<button
className={classNames('clear-button icon', { disabled: Objects.isEmpty(filterValue) })}
onClick={handleClearInput}
type="button"
>
<Icon className="icon-sub" name="remove" />
</button>
</div>
)
}

export default Text
14 changes: 14 additions & 0 deletions src/client/components/TablePaginated/TablePaginated.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@
grid-row-gap: $spacing-xs;
}

.table-paginated-actions {
align-items: center;
display: flex;
gap: $spacing-xs;
height: $spacing-l;
padding: $spacing-xxxs;
}

.table-paginated-datagrid {
.data-grid-column {
border: none;
Expand Down Expand Up @@ -49,3 +57,9 @@
}
}
}

.table-paginated-actions-sep {
background: radial-gradient($ui-accent-dark, $ui-bg);
height: $spacing-s;
width: 1px;
}
Loading

0 comments on commit 41ac12d

Please sign in to comment.