Feat: entry sorting (#3494)

* refactor: typescript search actions, add tests avoid duplicate search

* refactor: switch from promise chain to async/await in loadEntries

* feat: add sorting, initial commit

* fix: set isFetching to true on entries request

* fix: ui improvments and bug fixes

* test: fix tests

* feat(backend-gitlab): cache local tree)

* fix: fix prop type warning

* refactor: code cleanup

* feat(backend-bitbucket): add local tree caching support

* feat: swtich to orderBy and support multiple sort keys

* fix: backoff function

* fix: improve backoff

* feat: infer sortable fields

* feat: fetch file commit metadata - initial commit

* feat: extract file author and date, finalize GitLab & Bitbucket

* refactor: code cleanup

* feat: handle github rate limit errors

* refactor: code cleanup

* fix(github): add missing author and date when traversing cursor

* fix: add missing author and date when traversing cursor

* refactor: code cleanup

* refactor: code cleanup

* refactor: code cleanup

* test: fix tests

* fix: rebuild local tree when head doesn't exist in remote branch

* fix: allow sortable fields to be an empty array

* fix: allow translation of built in sort fields

* build: fix proxy server build

* fix: hide commit author and date fields by default on non git backends

* fix(algolia): add listAllEntries method for alogolia integration

* fix: handle sort fields overflow

* test(bitbucket): re-record some bitbucket e2e tests

* test(bitbucket): fix media library test

* refactor(gitgateway-gitlab): share request code and handle 404 errors

* fix: always show commit date by default

* docs: add sortableFields

* refactor: code cleanup

* improvement: drop multi-sort, rework sort UI

* chore: force main package bumps

Co-authored-by: Shawn Erquhart <shawn@erquh.art>
This commit is contained in:
Erez Rokah
2020-04-01 06:13:27 +03:00
committed by GitHub
parent cbb3927101
commit 174d86f0a0
82 changed files with 15128 additions and 12621 deletions

View File

@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import { css } from '@emotion/core';
import styled from '@emotion/styled';
import { Wrapper, Button as DropdownButton, Menu, MenuItem } from 'react-aria-menubutton';
import { buttons, components, zIndex } from './styles';
import { colors, buttons, components, zIndex } from './styles';
import Icon from './Icon';
const StyledWrapper = styled(Wrapper)`
@ -18,6 +18,7 @@ const StyledDropdownButton = styled(DropdownButton)`
display: block;
padding-left: 20px;
padding-right: 40px;
position: relative;
&:after {
${components.caretDown};
@ -25,7 +26,7 @@ const StyledDropdownButton = styled(DropdownButton)`
display: block;
position: absolute;
top: 16px;
right: 16px;
right: 10px;
color: currentColor;
}
`;
@ -47,18 +48,35 @@ const DropdownList = styled.ul`
`};
`;
const StyledMenuItem = styled(MenuItem)`
${components.dropdownItem};
`;
const StyledMenuItem = ({ isActive, ...props }) => (
<MenuItem
css={css`
${components.dropdownItem};
&:focus,
&:active,
&:not(:focus),
&:not(:active) {
background-color: ${isActive ? colors.activeBackground : 'inherit'};
color: ${isActive ? colors.active : 'inherit'};
}
&:hover {
color: ${colors.active};
background-color: ${colors.activeBackground};
}
`}
{...props}
/>
);
const MenuItemIconContainer = styled.div`
flex: 1 0 32px;
text-align: right;
position: relative;
top: 2px;
top: ${props => (props.iconSmall ? '0' : '2px')};
`;
const Dropdown = ({
closeOnSelection = true,
renderButton,
dropdownWidth = 'auto',
dropdownPosition = 'left',
@ -67,7 +85,11 @@ const Dropdown = ({
children,
}) => {
return (
<StyledWrapper onSelection={handler => handler()} className={className}>
<StyledWrapper
closeOnSelection={closeOnSelection}
onSelection={handler => handler()}
className={className}
>
{renderButton()}
<Menu>
<DropdownList width={dropdownWidth} top={dropdownTopOverlap} position={dropdownPosition}>
@ -87,12 +109,12 @@ Dropdown.propTypes = {
children: PropTypes.node,
};
const DropdownItem = ({ label, icon, iconDirection, onClick, className }) => (
<StyledMenuItem value={onClick} className={className}>
const DropdownItem = ({ label, icon, iconDirection, iconSmall, isActive, onClick, className }) => (
<StyledMenuItem value={onClick} isActive={isActive} className={className}>
<span>{label}</span>
{icon ? (
<MenuItemIconContainer>
<Icon type={icon} direction={iconDirection} size="small" />
<MenuItemIconContainer iconSmall={iconSmall}>
<Icon type={icon} direction={iconDirection} size={iconSmall ? 'xsmall' : 'small'} />
</MenuItemIconContainer>
) : null}
</StyledMenuItem>

View File

@ -94,7 +94,7 @@ export class Loader extends React.Component {
return (
<LoaderText>
<CSSTransition
classNames={{
className={{
enter: styles.enter,
enterActive: styles.enterActive,
exit: styles.exit,

View File

@ -213,6 +213,10 @@ const buttons = {
background-color: #555a65;
}
`,
grayText: css`
background-color: transparent;
color: ${colorsRaw.gray};
`,
green: css`
background-color: #aae31f;
color: ${colorsRaw.green};
@ -317,7 +321,7 @@ const components = {
color: ${colorsRaw.gray};
font-weight: 500;
border-bottom: 1px solid #eaebf1;
padding: 10px 14px;
padding: 8px 14px;
display: flex;
justify-content: space-between;
align-items: center;
@ -335,6 +339,12 @@ const components = {
background-color: ${colors.activeBackground};
}
`,
viewControlsText: css`
font-size: 14px;
color: ${colors.text};
margin-right: 12px;
white-space: nowrap;
`,
};
const reactSelectStyles = {