Skip to content

Commit

Permalink
feat(explorer): select visiblie columns in settings side panel
Browse files Browse the repository at this point in the history
  • Loading branch information
evoiron committed Nov 14, 2024
1 parent c793596 commit 36c20ea
Show file tree
Hide file tree
Showing 11 changed files with 266 additions and 12 deletions.
1 change: 1 addition & 0 deletions libs/ui/src/components/Explorer/DataView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
PropertyValueValueFragment
} from '_ui/_gqlTypes';
import {IItemAction, IItemData, ItemWhoAmI} from './_types';
import styled from 'styled-components';

const USELESS = '';

Expand Down
2 changes: 1 addition & 1 deletion libs/ui/src/components/Explorer/Explorer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export const Explorer: FunctionComponent<IExplorerProps> = ({
refetch
});

const settingsButton = useOpenSettings();
const settingsButton = useOpenSettings(library);

return (
<>
Expand Down
89 changes: 89 additions & 0 deletions libs/ui/src/components/Explorer/edit-settings/ColumnItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import {KitTypography} from 'aristid-ds';
import {FunctionComponent, ReactNode} from 'react';
import {FaChevronRight, FaEye, FaEyeSlash, FaGripLines} from 'react-icons/fa';
import styled from 'styled-components';

const StyledValue = styled(KitTypography.Text)`
color: var(--general-utilities-disabled);
`;

const StyledConfigurationItem = styled.li`
list-style: none;
color: var(--general-utilities-text-primary);
display: flex;
width: 100%;
height: 40px;
padding: 0 calc(var(--general-spacing-xs) * 1px);
align-items: center;
gap: calc(var(--general-spacing-xs) * 1px);
border-radius: calc(var(--general-spacing-xs) * 1px);
text-align: left;
&:first-child {
margin-top: calc(var(--general-spacing-xs) * 1px);
}
&:hover {
background: var(--general-utilities-main-light);
${StyledValue} {
color: var(--general-utilities-text-primary);
}
}
.title {
flex: 1 1 auto;
}
> svg {
flex: 0 0 calc(var(--general-spacing-s) * 1px);
}
> button {
border: none;
background: transparent;
cursor: pointer;
padding: 0;
}
`;

const StyledFaEye = styled(FaEye).attrs<{$disabled: boolean}>({$disabled: false})`
color: ${({$disabled}) => ($disabled ? 'var(--general-utilities-disabled)' : 'currentColor')};
cursor: ${({$disabled}) => ($disabled ? 'default' : 'pointer')};
`;

const StyledEyeSlash = styled(FaEyeSlash)`
color: var(--general-utilities-disabled);
cursor: pointer;
`;

const StyledEmptyIcon = styled.div`
width: calc(var(--general-spacing-s) * 1px);
`;

interface IColumnItemProps {
dragHandler?: ReactNode;
visible: boolean;
title: string;
onVisibilityClick?: () => void;
disabled?: boolean;
value?: string;
}

export const ColumnItem: FunctionComponent<IColumnItemProps> = ({
dragHandler,
title,
disabled,
visible,
onVisibilityClick
}) => (
<StyledConfigurationItem className={`${disabled ? 'disabled' : ''}`}>
{dragHandler || <StyledEmptyIcon />}
<KitTypography.Text size="fontSize5" ellipsis className="title">
{title}
</KitTypography.Text>
<button className={`${disabled ? 'disabled' : ''}`} onClick={onVisibilityClick}>
{visible ? <StyledFaEye /> : <StyledEyeSlash />}
</button>
</StyledConfigurationItem>
);
45 changes: 42 additions & 3 deletions libs/ui/src/components/Explorer/edit-settings/DisplayMode.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,47 @@
import {useGetAttributesByLibQuery} from '_ui/_gqlTypes';
import {useSharedTranslation} from '_ui/hooks/useSharedTranslation';
import {FunctionComponent} from 'react';
import {KitRadio, KitSpace, KitTypography} from 'aristid-ds';
import {RadioChangeEvent} from 'aristid-ds/dist/Kit/DataEntry/Radio';
import {FunctionComponent, useState} from 'react';
import styled from 'styled-components';
import {DisplayModeTable} from './DisplayModeTable';

export const DisplayMode: FunctionComponent = () => {
const StyledWrapper = styled.div`
display: flex;
flex-direction: column;
gap: calc(var(--general-spacing-l) * 1px);
.ant-radio-wrapper {
padding: calc(var(--general-spacing-xs) * 1px);
}
`;

interface IDisplayModeProps {
library: string;
}

export const DisplayMode: FunctionComponent<IDisplayModeProps> = ({library = 'users'}) => {
const {t} = useSharedTranslation();
const [currrentDisplayMode, setCurrentDisplayMode] = useState<string>('table');

const _handleDisplayModeChange = (event: RadioChangeEvent) => {
setCurrentDisplayMode(event.target.value);
};

return <div>DISPLAY MODE</div>;
return (
<StyledWrapper>
<KitRadio.Group value={currrentDisplayMode} onChange={_handleDisplayModeChange}>
<KitSpace direction="vertical" size={0}>
<KitRadio value="list">{t('explorer.display-mode-list')}</KitRadio>
<KitRadio value="table">{t('explorer.display-mode-table')}</KitRadio>
<KitRadio value="mosaic">{t('explorer.display-mode-mosaic')}</KitRadio>
<KitRadio value="planning">{t('explorer.display-mode-planning')}</KitRadio>
</KitSpace>
</KitRadio.Group>
{currrentDisplayMode === 'table' && <DisplayModeTable library={library} />}
{currrentDisplayMode !== 'table' && (
<KitTypography.Text>{t(`explorer.display-mode-${currrentDisplayMode}`)}</KitTypography.Text>
)}
</StyledWrapper>
);
};
111 changes: 111 additions & 0 deletions libs/ui/src/components/Explorer/edit-settings/DisplayModeTable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import {useGetAttributesByLibQuery} from '_ui/_gqlTypes';
import {useDebouncedValue} from '_ui/hooks/useDebouncedValue/useDebouncedValue';
import {useSharedTranslation} from '_ui/hooks/useSharedTranslation';
import {KitInput, KitTypography} from 'aristid-ds';
import {FunctionComponent, useMemo, useState} from 'react';
import styled from 'styled-components';
import {localizedTranslation} from '@leav/utils';
import {useLang} from '../../../hooks';
import {FaGripLines} from 'react-icons/fa';
import {ColumnItem} from './ColumnItem';

const StyledList = styled.ul`
padding: 0;
margin: 0;
list-style: none;
color: var(--general-utilities-text-primary);
`;

const StyledDivider = styled.li`
list-style: none;
border-bottom: 1px solid var(--general-utilities-main-light);
margin: 0 calc(var(--general-spacing-s) * 1px);
`;

interface IDisplayModeTableProps {
library: string;
}

export const DisplayModeTable: FunctionComponent<IDisplayModeTableProps> = ({library}) => {
const {t} = useSharedTranslation();
const {lang: availableLangs} = useLang();
// TOTO Where to stock visible columns list
// TODO when are changes saved (and thus, when is the table updated) ?
const [visibleColumns, setVisibleColumns] = useState<Record<string, boolean>>({
id: true
});
const [searchInput, setSearchInput] = useState('');
const debouncedSearchInput = useDebouncedValue(searchInput, 300);
const {data} = useGetAttributesByLibQuery({
variables: {
library
}
});

const filteredColumns = useMemo(() => {
if (!data) {
return [];
}
if (searchInput === '') {
return data?.attributes?.list ?? [];
}

return data?.attributes?.list?.filter(attribute => attribute.id.includes(debouncedSearchInput)) ?? [];
}, [debouncedSearchInput, data]);

const _onSearchChanged = (event: React.ChangeEvent<HTMLInputElement>) => {
if (event.target.value.length > 2 || event.target.value.length === 0) {
setSearchInput(event.target.value);
}
};

const _toggleColumnVisibility = (columnId: string) => () => {
setVisibleColumns(prev => ({
...prev,
[columnId]: !prev[columnId]
}));
};

return (
<div>
<KitTypography.Title level="h4">{t('items_list.columns')}</KitTypography.Title>
<KitInput placeholder={String(t('global.search'))} onChange={_onSearchChanged}></KitInput>
<div>
<StyledList>
<ColumnItem title={t('record_edition.whoAmI')} visible={false} disabled />
{Object.keys(visibleColumns).map(column => {
const attribute = filteredColumns.find(({id}) => id === column);
if (attribute && visibleColumns[attribute.id]) {
return (
<ColumnItem
key={column}
title={localizedTranslation(attribute.label, availableLangs)}
visible
onVisibilityClick={_toggleColumnVisibility(column)}
dragHandler={<FaGripLines />}
/>
);
}
return null;
})}
</StyledList>
<StyledDivider />
<StyledList>
{filteredColumns.map(attribute => {
if (visibleColumns[attribute.id]) {
return null;
}
return (
<ColumnItem
key={attribute.id}
visible={false}
title={localizedTranslation(attribute.label, availableLangs)}
onVisibilityClick={_toggleColumnVisibility(attribute.id)}
/>
);
})}
</StyledList>
</div>
</div>
);
};
6 changes: 4 additions & 2 deletions libs/ui/src/components/Explorer/edit-settings/SettingItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,14 @@ const StyledConfigurationItem = styled.li`
}
`;

export const SettingItem: FunctionComponent<{
interface ISettingItemProps {
icon: ReactNode;
title: string;
onClick: () => void;
value?: string;
}> = ({icon, title, value = '', onClick}) => (
}

export const SettingItem: FunctionComponent<ISettingItemProps> = ({icon, title, value = '', onClick}) => (
<StyledConfigurationItem>
<button onClick={onClick}>
{icon}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ describe('SettingsPanel', () => {
});

test('should be able to move to advanced setting and come back', async () => {
render(<SettingsPanel />);
render(<SettingsPanel library="users" />);
expect(screen.getByRole('heading', {name: 'explorer.view-configuration'})).toBeVisible();

await userEvent.click(screen.getByRole('button', {name: 'explorer.display-mode'}));
Expand Down
10 changes: 7 additions & 3 deletions libs/ui/src/components/Explorer/edit-settings/SettingsPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@ const ConfigurationStyledMenu = styled.menu`
padding: 0;
`;

export const SettingsPanel: FunctionComponent = () => {
interface ISettingsPanelProps {
library: string;
}

export const SettingsPanel: FunctionComponent<ISettingsPanelProps> = ({library}) => {
const {t} = useSharedTranslation();

const {setActiveSettings, activeSettings} = useEditSettings();
Expand Down Expand Up @@ -91,7 +95,7 @@ export const SettingsPanel: FunctionComponent = () => {
</ConfigurationStyledMenu>
</nav>
)}
{currentPage === 'display-mode' && <DisplayMode />}
</ContentWrapperStyledDiv>
{currentPage === 'display-mode' && <DisplayMode library={library} />}
</StyledSettingsPanelContent>

Check failure on line 99 in libs/ui/src/components/Explorer/edit-settings/SettingsPanel.tsx

View workflow job for this annotation

GitHub Actions / tscheck

Expected corresponding JSX closing tag for 'ContentWrapperStyledDiv'.

Check failure on line 99 in libs/ui/src/components/Explorer/edit-settings/SettingsPanel.tsx

View workflow job for this annotation

GitHub Actions / tscheck

Expected corresponding JSX closing tag for 'ContentWrapperStyledDiv'.

Check failure on line 99 in libs/ui/src/components/Explorer/edit-settings/SettingsPanel.tsx

View workflow job for this annotation

GitHub Actions / tscheck

Expected corresponding JSX closing tag for 'ContentWrapperStyledDiv'.
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ import {useSharedTranslation} from '_ui/hooks/useSharedTranslation';
import {SettingsPanel} from './SettingsPanel';
import {useEditSettings} from './useEditSettings';

export const useOpenSettings = () => {
export const useOpenSettings = (library: string) => {
const {setActiveSettings} = useEditSettings();
const {t} = useSharedTranslation();

const _openSettingsPanel = () =>
setActiveSettings({
content: <SettingsPanel />,
content: <SettingsPanel library={library} />,
title: t('explorer.settings')
});

Expand Down
4 changes: 4 additions & 0 deletions libs/ui/src/locales/en/shared.json
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,10 @@
"back": "Back",
"view-configuration": "View Configuration",
"display-mode": "Display Mode",
"display-mode-list": "List",
"display-mode-table": "Table",
"display-mode-mosaic": "Mosaïc",
"display-mode-planning": "Planning",
"filters": "Filters",
"sort": "Sort"
}
Expand Down
4 changes: 4 additions & 0 deletions libs/ui/src/locales/fr/shared.json
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,10 @@
"back": "Retour",
"view-configuration": "Configuration de la vue",
"display-mode": "Mode d’affichage",
"display-mode-list": "List",
"display-mode-table": "Tableau",
"display-mode-mosaic": "Mosaïque",
"display-mode-planning": "Planning",
"filters": "Filtrer",
"sort": "Trier"
}
Expand Down

0 comments on commit 36c20ea

Please sign in to comment.