Skip to content

Commit

Permalink
v1.177.0
Browse files Browse the repository at this point in the history
  • Loading branch information
varovaro committed Jul 29, 2024
2 parents 61bdab3 + 4c7496e commit 0edca68
Show file tree
Hide file tree
Showing 14 changed files with 162 additions and 61 deletions.
2 changes: 1 addition & 1 deletion SELF_HOSTED_INSTRUCTIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ mv prod latest && rm uwazi.tgz

You should now be able to run an Uwazi instance in production mode:

`DATABASE_NAME=my_db_name INDEX_NAME=my_db_name NODE_ENV=production FILES_ROOT_PATH=/xxxx/yyyy/uwazi/ node server.js`
`DATABASE_NAME=my_db_name INDEX_NAME=my_db_name NODE_ENV=production FILES_ROOT_PATH=/xxxx/yyyy/uwazi/ node server.js --no-experimental-fetch`

By default, Uwazi runs on `localhost` port 3000, so point your browser to http://localhost:3000 and authenticate yourself with the default username "admin" and password "change this password now".

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -399,9 +399,12 @@ class InformationExtraction {

if (propertyTypeIsSelectOrMultiSelect(property.type)) {
const thesauri = await dictionatiesModel.getById(property.content);
const [groups, rootValues] = _.partition(thesauri?.values || [], r => r.values);
const groupedValues = groups.map(group => group.values || []).flat();
const allValues = rootValues.concat(groupedValues);

params.options =
thesauri?.values?.map(value => ({ label: value.label, id: value.id as string })) || [];
allValues.map(value => ({ label: value.label, id: value.id as string })) || [];
}
if (property.type === 'relationship') {
const candidates = await fetchCandidates(property);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,14 @@ describe('InformationExtraction', () => {
id: 'C',
label: 'C',
},
{
id: '1A',
label: '1A',
},
{
id: '1B',
label: '1B',
},
],
},
tenant: 'tenant1',
Expand Down
2 changes: 1 addition & 1 deletion app/api/services/informationextraction/specs/fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -765,7 +765,7 @@ const fixtures: DBFixture = {
}),
]),
],
dictionaries: [factory.thesauri('thesauri1', ['A', 'B', 'C'])],
dictionaries: [factory.nestedThesauri('thesauri1', ['A', 'B', 'C', { 1: ['1A', '1B'] }])],
};

export { fixtures, factory };
2 changes: 2 additions & 0 deletions app/api/suggestions/specs/fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1400,6 +1400,8 @@ const selectAcceptanceFixtureBase: DBFixture = {
factory.v2.database.translationDBO('A', 'Aes', 'es', dictionaryTranslationContext),
factory.v2.database.translationDBO('B', 'B', 'en', dictionaryTranslationContext),
factory.v2.database.translationDBO('B', 'Bes', 'es', dictionaryTranslationContext),
factory.v2.database.translationDBO('1', '1', 'en', dictionaryTranslationContext),
factory.v2.database.translationDBO('1', '1es', 'es', dictionaryTranslationContext),
factory.v2.database.translationDBO('1A', '1A', 'en', dictionaryTranslationContext),
factory.v2.database.translationDBO('1A', '1Aes', 'es', dictionaryTranslationContext),
factory.v2.database.translationDBO('1B', '1B', 'en', dictionaryTranslationContext),
Expand Down
47 changes: 29 additions & 18 deletions app/api/suggestions/specs/suggestions.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -922,12 +922,23 @@ describe('suggestions', () => {
const { acceptedSuggestion, metadataValues, allFiles } =
await prepareAndAcceptSelectSuggestion('A', 'en', 'property_select', 'select_extractor');
expect(acceptedSuggestion.state).toEqual(matchState());
expect(metadataValues).toMatchObject([
expect(metadataValues).toEqual([
[{ value: 'A', label: 'A' }],
[{ value: 'A', label: 'Aes' }],
]);
expect(allFiles).toEqual(selectAcceptanceFixtureBase.files);
});

it('should handle grouped values', async () => {
const { acceptedSuggestion, metadataValues, allFiles } =
await prepareAndAcceptSelectSuggestion('1A', 'en', 'property_select', 'select_extractor');
expect(acceptedSuggestion.state).toEqual(matchState());
expect(metadataValues).toEqual([
[{ value: '1A', label: '1A', parent: { value: '1', label: '1' } }],
[{ value: '1A', label: '1Aes', parent: { value: '1', label: '1es' } }],
]);
expect(allFiles).toEqual(selectAcceptanceFixtureBase.files);
});
});

describe('multiselect', () => {
Expand Down Expand Up @@ -1022,14 +1033,14 @@ describe('suggestions', () => {
'multiselect_extractor'
);
expect(acceptedSuggestion.state).toEqual(matchState());
expect(metadataValues).toMatchObject([
expect(metadataValues).toEqual([
[
{ value: '1A', label: '1A' },
{ value: '1B', label: '1B' },
{ value: '1A', label: '1A', parent: { value: '1', label: '1' } },
{ value: '1B', label: '1B', parent: { value: '1', label: '1' } },
],
[
{ value: '1A', label: '1Aes' },
{ value: '1B', label: '1Bes' },
{ value: '1A', label: '1Aes', parent: { value: '1', label: '1es' } },
{ value: '1B', label: '1Bes', parent: { value: '1', label: '1es' } },
],
]);
expect(allFiles).toEqual(selectAcceptanceFixtureBase.files);
Expand All @@ -1047,15 +1058,15 @@ describe('suggestions', () => {
}
);
expect(acceptedSuggestion.state).toEqual(matchState(false));
expect(metadataValues).toMatchObject([
expect(metadataValues).toEqual([
[
{ value: 'A', label: 'A' },
{ value: '1A', label: '1A' },
{ value: '1A', label: '1A', parent: { value: '1', label: '1' } },
{ value: 'B', label: 'B' },
],
[
{ value: 'A', label: 'Aes' },
{ value: '1A', label: '1Aes' },
{ value: '1A', label: '1Aes', parent: { value: '1', label: '1es' } },
{ value: 'B', label: 'Bes' },
],
]);
Expand All @@ -1074,14 +1085,14 @@ describe('suggestions', () => {
}
);
expect(acceptedSuggestion.state).toEqual(matchState(false));
expect(metadataValues).toMatchObject([
expect(metadataValues).toEqual([
[
{ value: 'A', label: 'A' },
{ value: '1A', label: '1A' },
{ value: '1A', label: '1A', parent: { value: '1', label: '1' } },
],
[
{ value: 'A', label: 'Aes' },
{ value: '1A', label: '1Aes' },
{ value: '1A', label: '1Aes', parent: { value: '1', label: '1es' } },
],
]);
expect(allFiles).toEqual(selectAcceptanceFixtureBase.files);
Expand All @@ -1099,9 +1110,9 @@ describe('suggestions', () => {
}
);
expect(acceptedSuggestion.state).toEqual(matchState(false));
expect(metadataValues).toMatchObject([
[{ value: '1A', label: '1A' }],
[{ value: '1A', label: '1Aes' }],
expect(metadataValues).toEqual([
[{ value: '1A', label: '1A', parent: { value: '1', label: '1' } }],
[{ value: '1A', label: '1Aes', parent: { value: '1', label: '1es' } }],
]);
expect(allFiles).toEqual(selectAcceptanceFixtureBase.files);
});
Expand All @@ -1118,14 +1129,14 @@ describe('suggestions', () => {
}
);
expect(acceptedSuggestion.state).toEqual(matchState());
expect(metadataValues).toMatchObject([
expect(metadataValues).toEqual([
[
{ value: 'A', label: 'A' },
{ value: '1A', label: '1A' },
{ value: '1A', label: '1A', parent: { value: '1', label: '1' } },
],
[
{ value: 'A', label: 'Aes' },
{ value: '1A', label: '1Aes' },
{ value: '1A', label: '1Aes', parent: { value: '1', label: '1es' } },
],
]);
expect(allFiles).toEqual(selectAcceptanceFixtureBase.files);
Expand Down
17 changes: 15 additions & 2 deletions app/react/V2/Components/Forms/MultiselectList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ interface MultiselectListProps {
foldableGroups?: boolean;
singleSelect?: boolean;
allowSelelectAll?: boolean;
startOnSelected?: boolean;
}

const SelectedCounter = ({ selectedItems }: { selectedItems: string[] }) => (
Expand All @@ -46,13 +47,24 @@ const MultiselectList = ({
foldableGroups = false,
singleSelect = false,
allowSelelectAll = false,
startOnSelected = false,
}: MultiselectListProps) => {
const [selectedItems, setSelectedItems] = useState<string[]>(value || []);
const [showAll, setShowAll] = useState<boolean>(true);
const [showAll, setShowAll] = useState<boolean>(!(startOnSelected && selectedItems.length));
const [searchTerm, setSearchTerm] = useState('');
const [filteredItems, setFilteredItems] = useState(items);
const [openGroups, setOpenGroups] = useState<string[]>([]);

useEffect(() => {
if (startOnSelected) {
const groupsToExpand = items
.filter(item => item.items?.some(childItem => value?.includes(childItem.value)))
.map(item => item.value);

setOpenGroups(groupsToExpand);
}
}, [items, value, startOnSelected]);

useEffect(() => {
if (value) {
setSelectedItems(value);
Expand Down Expand Up @@ -251,12 +263,13 @@ const MultiselectList = ({
{
label: <Translate>All</Translate>,
value: 'true',
defaultChecked: true,
defaultChecked: !startOnSelected,
},
{
label: <SelectedCounter selectedItems={selectedItems} />,
value: 'false',
disabled: selectedItems.length === 0,
defaultChecked: startOnSelected,
},
]}
onChange={applyFilter}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ const ExtractorModal = ({
checkboxes
foldableGroups
allowSelelectAll={values.length > 0}
startOnSelected={values.length > 0}
/>
</div>
<div className={`${step !== 2 && 'hidden'} mt-6`}>
Expand Down
14 changes: 7 additions & 7 deletions app/react/V2/Routes/Settings/IX/components/Icons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ import {
} from 'V2/Components/CustomIcons';

const propertyIcons = {
text: <TextPropertyIcon />,
date: <DatePropertyIcon />,
numeric: <NumericPropertyIcon />,
markdown: <MarkdownPropertyIcon />,
select: <SelectPropertyIcon />,
multiselect: <SelectPropertyIcon />,
relationship: <RelationshipPropertyIcon />,
text: <TextPropertyIcon className="w-5 h-5" />,
date: <DatePropertyIcon className="w-5 h-5" />,
numeric: <NumericPropertyIcon className="w-5 h-5" />,
markdown: <MarkdownPropertyIcon className="w-5 h-5" />,
select: <SelectPropertyIcon className="w-5 h-5" />,
multiselect: <SelectPropertyIcon className="w-5 h-5" />,
relationship: <RelationshipPropertyIcon className="w-5 h-5" />,
};

export { propertyIcons };
22 changes: 20 additions & 2 deletions app/react/V2/Routes/Settings/IX/components/SuggestedValue.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { EntitySuggestionType } from 'shared/types/suggestionType';
import { ClientTemplateSchema } from 'app/istore';
import { Translate } from 'app/I18N';
import { thesauriAtom } from 'V2/atoms';
import { ClientThesaurus, ClientThesaurusValue } from 'app/apiResponseTypes';

const SuggestedValue = ({
value,
Expand Down Expand Up @@ -44,6 +45,23 @@ const SuggestedValue = ({
const { content, type } = property || {};
const thesaurus = thesauris.find(t => t._id === content);

const getLabelFromThesaurus = (id: string, _thesaurus: ClientThesaurus | undefined) => {
if (!_thesaurus) {
return '';
}

const flattenedValues = _thesaurus.values.reduce((acc: any, v) => {
if (v.values) {
return [...acc, ...v.values];
}
return [...acc, v];
}, []);

const thesaurusValue = flattenedValues.find((v: ClientThesaurusValue) => v.id === id);

return thesaurusValue?.label || '';
};

const getCurrentValue = () => {
if (value === '' || value === undefined) {
return '-';
Expand All @@ -53,7 +71,7 @@ const SuggestedValue = ({
}

if (type === 'select' || type === 'multiselect' || type === 'relationship') {
const label = thesaurus?.values.find(v => v.id === value)?.label;
const label = getLabelFromThesaurus(value as string, thesaurus);
return <Translate context={content}>{label}</Translate>;
}

Expand All @@ -68,7 +86,7 @@ const SuggestedValue = ({
return secondsToDate((suggestion.suggestedValue as string | number) || '', locale);
}
if (type === 'select' || type === 'multiselect' || type === 'relationship') {
const label = thesaurus?.values.find(v => v.id === suggestion.suggestedValue)?.label;
const label = getLabelFromThesaurus(suggestion.suggestedValue as string, thesaurus);
return <Translate context={content}>{label}</Translate>;
}
return suggestion.suggestedValue!.toString();
Expand Down
48 changes: 46 additions & 2 deletions app/react/stories/Forms/MultiselectList.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const Primary: Story = {
render: args => (
<Provider store={createStore()}>
<div className="tw-content">
<div className="p-4 m-auto w-full md:w-1/2">
<div className="w-full p-4 m-auto md:w-1/2">
<MultiselectList
label={args.label}
items={args.items}
Expand All @@ -24,6 +24,8 @@ const Primary: Story = {
checkboxes={args.checkboxes}
foldableGroups={args.foldableGroups}
allowSelelectAll={args.allowSelelectAll}
startOnSelected={args.startOnSelected}
value={args.value}
/>
</div>
</div>
Expand All @@ -39,6 +41,7 @@ const Basic: Story = {
foldableGroups: true,
hasErrors: false,
allowSelelectAll: false,
startOnSelected: false,
items: [
{ searchLabel: 'Someone', label: 'Someone', value: 'someone' },
{ searchLabel: 'Another', label: 'Another', value: 'another' },
Expand Down Expand Up @@ -121,6 +124,47 @@ const WithGroups: Story = {
},
};

export { Basic, WithError, WithGroups };
const InitialState: Story = {
...Primary,
args: {
...Basic.args,
value: ['red', 'orange', 'banana'],
startOnSelected: true,
items: [
{
searchLabel: 'Colors',
label: 'Colors',
value: 'colors',
items: [
{ searchLabel: 'Red', label: 'Red', value: 'red' },
{ searchLabel: 'Blue', label: 'Blue', value: 'blue' },
{ searchLabel: 'Green', label: 'Green', value: 'green' },
],
},
{
searchLabel: 'Animals',
label: 'Animals',
value: 'animals',
items: [
{ searchLabel: 'Dog', label: 'Dog', value: 'dog' },
{ searchLabel: 'Cat', label: 'Cat', value: 'cat' },
{ searchLabel: 'Bird', label: 'Bird', value: 'bird' },
],
},
{
searchLabel: 'Fruits',
label: 'Fruits',
value: 'fruits',
items: [
{ searchLabel: 'Apple', label: 'Apple', value: 'apple' },
{ searchLabel: 'Banana', label: 'Banana', value: 'banana' },
{ searchLabel: 'Orange', label: 'Orange', value: 'orange' },
],
},
],
},
};

export { Basic, WithError, WithGroups, InitialState };

export default meta;
3 changes: 2 additions & 1 deletion cypress/e2e/settings/information-extraction.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,8 +157,9 @@ describe('Information Extraction', () => {
cy.contains('button', 'Edit Extractor').click();
cy.getByTestId('modal').within(() => {
cy.get('input[id="extractor-name"]').type(' edited', { delay: 0 });
cy.get('label[for="filter_true"]').click();
editPropertyForExtractor('ordenesDeLaCorte', 'Ordenes de la corte', 'Title');
editPropertyForExtractor('causa', 'Causa', 'Title');
editPropertyForExtractor('causa', 'Causa', 'Title', false);
cy.contains('button', 'Next').click();
checkTemplatesList(['Ordenes de la corte', 'Ordenes del presidente']);
cy.contains('button', 'Update').click();
Expand Down
Loading

0 comments on commit 0edca68

Please sign in to comment.