Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Displays relationships tab on side panel #5041

Merged
merged 51 commits into from
Sep 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
080f121
Added relationships tab on side panel
grafitto Aug 26, 2022
1b37ba6
Added small UI
grafitto Aug 26, 2022
396064a
Updated tests
grafitto Sep 1, 2022
32a2eff
Added relationships tab on side panel
grafitto Aug 26, 2022
4e72bd8
Added small UI
grafitto Aug 26, 2022
515ddc1
Updated tests
grafitto Sep 1, 2022
0246613
Merge branch '1441-sidepanel-connections' of github.com:huridocs/uwaz…
grafitto Sep 1, 2022
bd2689d
Updated an action name
grafitto Sep 1, 2022
576989f
Merge branch 'development' into 1441-sidepanel-connections
grafitto Sep 2, 2022
e418081
Merge branch 'development' into 1441-sidepanel-connections
grafitto Sep 2, 2022
e36e8fe
Merge branch 'development' into 1441-sidepanel-connections
grafitto Sep 2, 2022
6762b30
Added collapsible component
grafitto Sep 5, 2022
fbd8793
Added footer
grafitto Sep 5, 2022
7b60bff
Refactored a little bit
grafitto Sep 5, 2022
f2df38f
Updated scroll event
grafitto Sep 5, 2022
acf1d9f
Fixed sticky component to stick correctly
grafitto Sep 7, 2022
8ba7781
Improved sticky header implementation
grafitto Sep 8, 2022
f45d73b
Merge branch 'development' into 1441-sidepanel-connections
grafitto Sep 8, 2022
d03966b
Fixed collapsible tes
grafitto Sep 8, 2022
b81192f
Fixed error in collapsible test
grafitto Sep 8, 2022
cea8bf0
Fixed a few codeclimate issues
grafitto Sep 8, 2022
5c04ff6
Added load more button, and filter limit
grafitto Sep 9, 2022
0070ab7
Merge branch 'development' into 1441-sidepanel-connections
grafitto Sep 9, 2022
c963e04
Updated tests
grafitto Sep 9, 2022
54b524f
Refactored sticky header
grafitto Sep 9, 2022
6359d85
Refactored sticky header
grafitto Sep 9, 2022
45bdf02
Added a key translations migration
grafitto Sep 9, 2022
25685d9
Translate
grafitto Sep 9, 2022
5288278
Refactored sticky header
grafitto Sep 9, 2022
ab53125
Removed comment
grafitto Sep 9, 2022
cacc374
Added a test for LibraryViewRelationships
grafitto Sep 9, 2022
34c01db
Merge branch 'development' into 1441-sidepanel-connections
grafitto Sep 9, 2022
c71b9c1
Merge branch 'development' into 1441-sidepanel-connections
grafitto Sep 12, 2022
af3b28c
Fixed collapse and expand all bug
grafitto Sep 12, 2022
78fd60e
Refactored a little
grafitto Sep 12, 2022
21209d7
Merge branch 'development' into 1441-sidepanel-connections
grafitto Sep 12, 2022
3676494
Replaced t function with Translate component
konzz Sep 13, 2022
d05c9a8
css tweaks for sidepanel relationships
konzz Sep 13, 2022
e609a21
Showing View button and hidding edit/delete for the metadata panel of…
konzz Sep 13, 2022
b59e96e
Propper iccons for the view buttons
konzz Sep 13, 2022
9f584c7
Merge branch 'development' into 1441-sidepanel-connections
grafitto Sep 14, 2022
218943e
Fixed tests
grafitto Sep 14, 2022
c870764
Fixed a few CSS issues
grafitto Sep 15, 2022
f1874b5
Merge branch 'development' into 1441-sidepanel-connections
grafitto Sep 15, 2022
f3ce7b6
Fixed some e2e tests
grafitto Sep 15, 2022
a73a55e
Fixed react keys on map functions
grafitto Sep 16, 2022
4c07c7a
Merge branch 'development' into 1441-sidepanel-connections
grafitto Sep 16, 2022
604eada
Fixed a test
grafitto Sep 16, 2022
f03aad8
Merge branch '1441-sidepanel-connections' of github.com:huridocs/uwaz…
grafitto Sep 16, 2022
f08b011
Fixed e2e
grafitto Sep 16, 2022
f70529e
Merge branch 'development' into 1441-sidepanel-connections
grafitto Sep 16, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
This migration is meant to be repeatable.
After copy pasting:
- change the contents of system_keys.csv to the new keyset
- change the file location in the readCsvToSystemKeys call
- change the tests, if necessary
*/

async function insertSystemKeys(db, newKeys) {
const translations = await db.collection('translations').find().toArray();
const locales = translations.map(tr => tr.locale);

const locToSystemContext = {};
translations.forEach(tr => {
locToSystemContext[tr.locale] = tr.contexts.find(c => c.id === 'System');
});
const locToKeys = {};
Object.entries(locToSystemContext).forEach(([loc, context]) => {
locToKeys[loc] = new Set(context.values.map(v => v.key));
});

newKeys.forEach(row => {
const { key, value: optionalValue } = row;

locales.forEach(loc => {
if (!locToKeys[loc].has(key)) {
const newValue = optionalValue || key;
locToSystemContext[loc].values.push({ key, value: newValue });
locToKeys[loc].add(key);
}
});
});

await Promise.all(
translations.map(tr => db.collection('translations').replaceOne({ _id: tr._id }, tr))
);
}

export default {
delta: 107,

reindex: false,

name: 'add_system_key_translations',

description: 'Adding missing translations for system keys.',

async up(db) {
process.stdout.write(`${this.name}...\r\n`);
const systemKeys = [
{
key: 'Collapse all',
},
{
key: 'Expand all',
},
];
await insertSystemKeys(db, systemKeys);
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { testingDB } from 'api/utils/testing_db';
import migration from '../index.js';
import { fixtures, templateId, defaultTemplateName, defaultTemplateTitle } from './fixtures.js';

const locales = ['en', 'es', 'hu'];
const newKeyValues = [
{
key: 'Collapse all',
value: 'Collapse all',
},
{ key: 'Expand all', value: 'Expand all' },
];
const alreadyInAllContexts = {
key: 'Duplicated label',
en: 'Duplicated label',
es: 'Nombre duplicado',
hu: 'Ismétlődő címke',
};

describe('migration add_system_key_translations', () => {
beforeEach(async () => {
spyOn(process.stdout, 'write');
await testingDB.setupFixturesAndContext(fixtures);
});

afterAll(async () => {
await testingDB.disconnect();
});

it('should have a delta number', () => {
expect(migration.delta).toBe(107);
});

it('should append new keys, leave existing keys intact.', async () => {
await migration.up(testingDB.mongodb);

const allTranslations = await testingDB.mongodb.collection('translations').find().toArray();
function testKeyValue(key, value, locale, contextId) {
expect(
allTranslations
.find(tr => tr.locale === locale)
.contexts.find(c => c.id === contextId)
.values.find(v => v.key === key).value
).toBe(value);
}

newKeyValues.forEach(({ key, value }) => {
locales.forEach(loc => {
testKeyValue(key, value, loc, 'System');
});
});
locales.forEach(loc => {
testKeyValue(alreadyInAllContexts.key, alreadyInAllContexts[loc], loc, 'System');
});
locales.forEach(loc => {
expect(
allTranslations
.find(tr => tr.locale === loc)
.contexts.find(c => c.id === templateId.toString()).values
).toHaveLength(2);
testKeyValue(defaultTemplateName, defaultTemplateName, loc, templateId.toString());
testKeyValue(defaultTemplateTitle, defaultTemplateTitle, loc, templateId.toString());
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import db from 'api/utils/testing_db';

const templateId = db.id();
const defaultTemplateName = 'default template';
const defaultTemplateTitle = 'Title';

//contexts
const commonContext = {
id: 'System',
label: 'User Interface',
type: 'Uwazi UI',
values: [
{
key: 'existing-key-in-system',
value: 'existing-key-in-system',
},
],
};
const templateContext = {
id: templateId.toString(),
label: defaultTemplateName,
type: 'Entity',
values: [
{
key: defaultTemplateName,
value: defaultTemplateName,
},
{
key: defaultTemplateTitle,
value: defaultTemplateTitle,
},
],
};

const fixtures = {
templates: [
//default template name - correct
{
_id: templateId,
name: defaultTemplateName,
commonProperties: [{ name: 'title', label: defaultTemplateTitle, type: 'text' }],
properties: [],
},
],
translations: [
{
_id: db.id(),
locale: 'es',
contexts: [
{
...commonContext,
values: commonContext.values.concat([
{ key: 'Drag properties here', value: 'Arrastra propiedades aquí' },
{ key: 'Duplicated label', value: 'Nombre duplicado' },
]),
},
templateContext,
],
},
{
_id: db.id(),
locale: 'en',
contexts: [
{
...commonContext,
values: commonContext.values.concat([
{ key: 'Priority sorting', value: 'Priority sort' },
{ key: 'Duplicated label', value: 'Duplicated label' },
]),
},
templateContext,
],
},
{
_id: db.id(),
locale: 'hu',
contexts: [
{
...commonContext,
values: commonContext.values.concat([
{ key: 'Duplicated label', value: 'Ismétlődő címke' },
]),
},
templateContext,
],
},
],
};

export { fixtures, templateId, defaultTemplateName, defaultTemplateTitle };
31 changes: 31 additions & 0 deletions app/react/App/Collapsible.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { Icon } from 'UI';
import React, { ReactElement, useEffect, useState } from 'react';

interface CollapsibleProps {
className?: string;
header: string | HTMLElement;
headerInfo?: string;
children: ReactElement<any, any>;
collapse?: boolean;
}

const Collapsible = ({ header, children, className, headerInfo, collapse }: CollapsibleProps) => {
const [collapsed, setCollapsed] = useState(collapse);
useEffect(() => {
setCollapsed(collapse);
}, [collapse]);
return (
<div className={className}>
<div className="header" onClick={() => setCollapsed(!collapsed)}>
<span className="header-icon">
<Icon icon={collapsed ? 'caret-right' : 'caret-down'} />
</span>
<span>{header}</span>
{headerInfo && <span className="header-info">{headerInfo}</span>}
</div>
{!collapsed && <div className="content">{children}</div>}
</div>
);
};

export { Collapsible };
60 changes: 60 additions & 0 deletions app/react/App/StickyHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import React, { LegacyRef, ReactElement, useEffect } from 'react';

interface StickyHeaderProps {
children: ReactElement;
scrollElementSelector: string;
stickyElementSelector: string;
}

const getMeasurements = (target: HTMLElement, current: HTMLElement) => {
const parentTop = target.getBoundingClientRect().top;
const scrollerTop = target.scrollTop;
const stickyTop = current.offsetTop || 0;
const stickyBottom = stickyTop + current.offsetHeight;
return {
scrollerTop,
stickyTop,
stickyBottom,
parentTop,
};
};

const eventHandler = (self: any, stickyElementSelector: string, event: Event) => {
if (self && self.current && event.target && event.target instanceof Element) {
const { current } = self;
const stickyElement: HTMLElement = current.querySelector(stickyElementSelector);
current.classList.remove('sticky');
const { scrollerTop, stickyTop, stickyBottom, parentTop } = getMeasurements(
event.target as HTMLElement,
current
);

if (stickyTop < scrollerTop && stickyBottom > scrollerTop) {
current.classList.add('sticky');
if (stickyElement) {
stickyElement.style.top = `${parentTop}px`;
}
}
}
};

const StickyHeader = (props: StickyHeaderProps) => {
const { children, scrollElementSelector, stickyElementSelector } = props;
const self: LegacyRef<HTMLDivElement> = React.createRef();
const body = document.querySelector<HTMLDivElement>(scrollElementSelector);
useEffect(() => {
body?.addEventListener('scroll', event => {
eventHandler(self, stickyElementSelector, event);
});

return () => {
body?.removeEventListener('scroll', event =>
eventHandler(self, stickyElementSelector, event)
);
};
});

return <div ref={self}>{children}</div>;
};

export { StickyHeader };
12 changes: 12 additions & 0 deletions app/react/App/scss/layout/_footer.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
@mixin relationshipsFooterButtons {
.relationships-right-buttons {
float: right;
}
.relationships-left-buttons {
width: 50%;
}
}

footer {
margin: 30px 0 0;
padding: 20px 0 15px;
Expand Down Expand Up @@ -237,6 +246,8 @@ footer {
.btn:disabled .btn-label {
color: $c-grey !important;
}

@include relationshipsFooterButtons();
}

@media (max-width: 1023px) {
Expand All @@ -259,6 +270,7 @@ footer {

.sidepanel-footer {
width: 400px;
@include relationshipsFooterButtons();
}

.entity-footer,
Expand Down
Loading