Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/ix-bug-fixes' into testing
Browse files Browse the repository at this point in the history
  • Loading branch information
konzz committed Sep 9, 2024
2 parents ea26785 + adc2dde commit 0debfc8
Show file tree
Hide file tree
Showing 20 changed files with 438 additions and 179 deletions.
6 changes: 4 additions & 2 deletions .github/workflows/ci_unit_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ jobs:
run: node --expose-gc -no-compilation-cache ./node_modules/.bin/jest app/api app/shared --coverage --coverageDirectory coverage/api --maxWorkers=2 --logHeapUsage
- run: ./cc-test-reporter format-coverage -t lcov -o tmp/codeclimate.api.json coverage/api/lcov.info
- name: Archive code coverage results
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: api-coverage-report
path: tmp/codeclimate.api.json
Expand Down Expand Up @@ -102,7 +102,7 @@ jobs:
run: node --max-http-header-size 20000 ./node_modules/.bin/jest app/react --coverage --coverageDirectory coverage/react --maxWorkers=2
- run: ./cc-test-reporter format-coverage -t lcov -o tmp/codeclimate.react.json coverage/react/lcov.info
- name: Archive code coverage results
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: react-coverage-report
path: tmp/codeclimate.react.json
Expand All @@ -115,6 +115,8 @@ jobs:
steps:
- name: Download tests results
uses: actions/[email protected]
with:
pattern: '*-coverage-report'
- name: Download codeclimate binay
run: curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
- run: chmod +x ./cc-test-reporter
Expand Down
38 changes: 23 additions & 15 deletions app/react/V2/Components/Forms/MultiselectList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,30 @@ const MultiselectList = ({
const [externalSearch, setExternalSearch] = useState(search);
const [filteredItems, setFilteredItems] = useState(items);
const [openGroups, setOpenGroups] = useState<string[]>([]);
const [selectedOrSuggestedItems, setSelectedOrSuggestedItems] = useState<Set<string>>(
new Set(selectedItems)
);
const optionsRef = useRef<HTMLUListElement>(null);

useEffect(() => {
const newSet = new Set<string>(selectedItems);
items.forEach(item => {
if (item.suggested) {
newSet.add(item.value);
}

if (item.items) {
item.items.forEach(subItem => {
if (subItem.suggested) {
newSet.add(subItem.value);
}
});
}
});

setSelectedOrSuggestedItems(newSet);
}, [items, selectedItems]);

useEffect(() => {
if (startOnSelected) {
const groupsToExpand = items
Expand Down Expand Up @@ -261,20 +283,6 @@ const MultiselectList = ({

const renderSelectedLabel = () => {
if (suggestions) {
const selectedOrSuggestedItems = new Set<string>(selectedItems);
items.forEach(item => {
if (item.suggested) {
selectedOrSuggestedItems.add(item.value);
}

if (item.items) {
item.items.forEach(subItem => {
if (subItem.suggested) {
selectedOrSuggestedItems.add(subItem.value);
}
});
}
});
return (
<>
<Translate>Selected or suggested</Translate>{' '}
Expand Down Expand Up @@ -318,7 +326,7 @@ const MultiselectList = ({
{
label: renderSelectedLabel(),
value: 'false',
disabled: selectedItems.length === 0,
disabled: selectedOrSuggestedItems.size === 0,
defaultChecked: startOnSelected,
},
]}
Expand Down
6 changes: 4 additions & 2 deletions app/react/V2/Components/UI/Card.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';

interface CardProps {
title: string | React.ReactNode;
title?: string | React.ReactNode;
children: React.ReactNode;
className?: string;
color?: 'default' | 'yellow';
Expand All @@ -20,7 +20,9 @@ const Card = ({ title, children, className, color = 'default' }: CardProps) => {

return (
<div className={`border rounded-md border-gray-50 shadow-sm ${className}`}>
<div className={`block w-full font-semibold text-base p-4 ${headerColor}`}>{title}</div>
{title && (
<div className={`block w-full font-semibold text-base p-4 ${headerColor}`}>{title}</div>
)}
<div className="p-4">{children}</div>
</div>
);
Expand Down
4 changes: 2 additions & 2 deletions app/react/V2/Routes/Settings/IX/IXSuggestions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { ClientPropertySchema, ClientTemplateSchema } from 'app/istore';
import { notificationAtom } from 'app/V2/atoms';
import { socket } from 'app/socket';
import { SuggestionsTitle } from './components/SuggestionsTitle';
import { FiltersSidepanel } from './components/FiltersSidepanel';
import { FiltersSidepanel } from './components/FiltersSidepanel.old';
import { suggestionsTableColumnsBuilder } from './components/TableElements';
import { PDFSidepanel } from './components/PDFSidepanel';
import {
Expand Down Expand Up @@ -187,7 +187,7 @@ const IXSuggestions = () => {
});

await suggestionsAPI.accept(preparedSuggestions);
setCurrentSuggestions(updateSuggestions(currentSuggestions, acceptedSuggestions));
setCurrentSuggestions(current => updateSuggestions(current, acceptedSuggestions));
setNotifications({
type: 'success',
text: <Translate>Suggestion accepted.</Translate>,
Expand Down
231 changes: 231 additions & 0 deletions app/react/V2/Routes/Settings/IX/components/FiltersSidepanel.old.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,231 @@
/* eslint-disable react/no-multi-comp */
/* eslint-disable max-statements */
/* eslint-disable react/jsx-props-no-spreading */
import React from 'react';
import { Translate, t } from 'app/I18N';
import { Button, Card, Sidepanel } from 'V2/Components/UI';
import { Checkbox } from 'app/V2/Components/Forms';
import { useForm } from 'react-hook-form';
import { useSearchParams } from 'react-router-dom';
import { SuggestionCustomFilter } from 'shared/types/suggestionType';

interface FiltersSidepanelProps {
showSidepanel: boolean;
setShowSidepanel: React.Dispatch<React.SetStateAction<boolean>>;
aggregation: any;
}

const Header = ({ label, total }: { label: string; total: number }) => (
<div className="flex items-center space-x-2 text-indigo-700">
<div className="flex-none">{label}</div>
<div className="flex-1 border-t border-dashed border-t-gray-200" />
<div className="flex-none">{total}</div>
</div>
);

const getPercentage = (match: number, total: number): string => {
const percentage = (match / total) * 100;

if (Number.isNaN(percentage)) {
return '-';
}

return `${Math.round(percentage)}%`;
};

const FiltersSidepanel = ({
showSidepanel,
setShowSidepanel,
aggregation,
}: FiltersSidepanelProps) => {
const [searchParams, setSearchParams] = useSearchParams();

const defaultFilter: SuggestionCustomFilter = {
labeled: {
match: false,
mismatch: false,
},
nonLabeled: {
noContext: false,
withSuggestion: false,
noSuggestion: false,
obsolete: false,
others: false,
},
};

let initialFilters: SuggestionCustomFilter = defaultFilter;

try {
if (searchParams.has('filter')) {
initialFilters = JSON.parse(searchParams.get('filter')!);
}
} catch (e) {}

const { register, handleSubmit, reset, setValue } = useForm({
values: initialFilters,
defaultValues: defaultFilter,
});

const submitFilters = async (filters: SuggestionCustomFilter) => {
setSearchParams((prev: URLSearchParams) => {
prev.set('page', '1');
prev.set('filter', JSON.stringify(filters));
return prev;
});
setShowSidepanel(false);
};

const checkOption = (e: any, optionName: any) => {
const { checked } = e.target;
setValue(optionName, checked);
};

const clearFilters = () => {
setSearchParams(prev => {
prev.delete('filter');
return prev;
});
setShowSidepanel(false);
reset();
};

return (
<Sidepanel
isOpen={showSidepanel}
withOverlay
closeSidepanelFunction={() => setShowSidepanel(false)}
title={
<span className="text-base font-semibold uppercase">
<Translate>Stats & Filters</Translate>
</span>
}
>
<form onSubmit={handleSubmit(submitFilters)} className="flex flex-col h-full">
<Sidepanel.Body className="flex flex-col flex-grow gap-4">
<Card
title={<Header label={t('System', 'Labeled')} total={aggregation.labeled._count} />}
>
<div className="mx-4 mb-3 space-y-1 text-black">
<div className="flex items-center space-x-1 bg-green-200">
<div className="flex-none">
<Translate>Accuracy</Translate>
</div>
<div className="flex-1 border-t border-dashed border-t-gray-200" />
<div className="flex-none font-mono">
{getPercentage(aggregation.labeled.match, aggregation.labeled._count)}
</div>
</div>
<div className="flex items-center space-x-1">
<Checkbox
label="Match"
{...register('labeled.match')}
onChange={e => {
checkOption(e, 'labeled.match');
}}
/>
<div className="flex-1 border-t border-dashed border-t-gray-200" />
<div className="flex-none">{aggregation.labeled.match}</div>
</div>
<div className="flex items-center space-x-1">
<Checkbox
label="Mismatch"
{...register('labeled.mismatch')}
onChange={e => {
checkOption(e, 'labeled.mismatch');
}}
/>
<div className="flex-1 border-t border-dashed border-t-gray-200" />
<div className="flex-none">{aggregation.labeled.mismatch}</div>
</div>
</div>
</Card>
<Card
title={
<Header label={t('System', 'Non-labeled')} total={aggregation.nonLabeled._count} />
}
>
<div className="mx-4 mb-3 space-y-1">
<div className="flex items-center space-x-1 bg-yellow-100">
<div className="flex-none">
<Translate>Pending</Translate>
</div>
<div className="flex-1 border-t border-dashed border-t-gray-200" />
<div className="flex-none font-mono">
{getPercentage(aggregation.nonLabeled._count, aggregation.total)}
</div>
</div>
<div className="flex items-center space-x-1">
<Checkbox
label={<Translate>With suggestion</Translate>}
{...register('nonLabeled.withSuggestion')}
onChange={e => {
checkOption(e, 'nonLabeled.withSuggestion');
}}
/>
<div className="flex-1 border-t border-dashed border-t-gray-200" />
<div className="flex-none">{aggregation.nonLabeled.withSuggestion}</div>
</div>
<div className="flex items-center space-x-1">
<Checkbox
label={<Translate>No suggestion</Translate>}
{...register('nonLabeled.noSuggestion')}
onChange={e => {
checkOption(e, 'nonLabeled.noSuggestion');
}}
/>
<div className="flex-1 border-t border-dashed border-t-gray-200" />
<div className="flex-none">{aggregation.nonLabeled.noSuggestion}</div>
</div>
<div className="flex items-center space-x-1">
<Checkbox
label={<Translate>No context</Translate>}
{...register('nonLabeled.noContext')}
onChange={e => {
checkOption(e, 'nonLabeled.noContext');
}}
/>
<div className="flex-1 border-t border-dashed border-t-gray-200" />
<div className="flex-none">{aggregation.nonLabeled.noContext}</div>
</div>
<div className="flex items-center space-x-1">
<Checkbox
label={<Translate>Obsolete</Translate>}
{...register('nonLabeled.obsolete')}
onChange={e => {
checkOption(e, 'nonLabeled.obsolete');
}}
/>
<div className="flex-1 border-t border-dashed border-t-gray-200" />
<div className="flex-none">{aggregation.nonLabeled.obsolete}</div>
</div>
<div className="flex items-center space-x-1">
<Checkbox
label={<Translate>Others</Translate>}
{...register('nonLabeled.others')}
onChange={e => {
checkOption(e, 'nonLabeled.others');
}}
/>
<div className="flex-1 border-t border-dashed border-t-gray-200" />
<div className="flex-none">{aggregation.nonLabeled.others}</div>
</div>
</div>
</Card>
</Sidepanel.Body>
<Sidepanel.Footer className="px-4 py-3">
<div className="flex gap-2">
<Button className="flex-grow" type="button" styling="outline" onClick={clearFilters}>
<Translate>Clear all</Translate>
</Button>
<Button className="flex-grow" type="submit">
<Translate>Apply</Translate>
</Button>
</div>
</Sidepanel.Footer>
</form>
</Sidepanel>
);
};

export { FiltersSidepanel };
Loading

0 comments on commit 0debfc8

Please sign in to comment.