- Updated the table background color to use Theme.colors.gray900 for better contrast
- Removed the dropdown component and its associated styles, as well as the publishing state indicator and related files, to streamline the codebase and eliminate unused features
This commit is contained in:
@@ -13,7 +13,7 @@ export const Table = styled.default.table`
|
|||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
table-layout: fixed;
|
table-layout: fixed;
|
||||||
background-color: ${Theme.blackWithOpacity};
|
background-color: ${Theme.colors.gray900};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const Thead = styled.default.thead`
|
export const Thead = styled.default.thead`
|
||||||
|
|||||||
@@ -1,209 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright 2024 Phenix Real Time Solutions, Inc. Confidential and Proprietary. All Rights Reserved.
|
|
||||||
*/
|
|
||||||
import {useState, useEffect, useRef} from 'react';
|
|
||||||
|
|
||||||
import {IChannel} from 'interfaces';
|
|
||||||
import {Label} from 'components/label';
|
|
||||||
|
|
||||||
import {DropdownContainer, DropdownInput, DropdownMenu, DropdownMenuItem} from './style';
|
|
||||||
|
|
||||||
const keys = ['ArrowDown', 'ArrowUp', 'Enter', 'Escape'];
|
|
||||||
|
|
||||||
interface IDropdown {
|
|
||||||
itemKey: string;
|
|
||||||
searchTerm?: string;
|
|
||||||
onSelect: (key: string) => void;
|
|
||||||
items: IChannel[];
|
|
||||||
label: string;
|
|
||||||
name: string;
|
|
||||||
className?: string;
|
|
||||||
}
|
|
||||||
const maxNumOfItemsShown = 30;
|
|
||||||
|
|
||||||
export const Dropdown = (props: IDropdown): JSX.Element => {
|
|
||||||
const {itemKey, searchTerm, onSelect, items, label, name, className} = props;
|
|
||||||
const [showDropdownMenu, setShowDropdownMenu] = useState(false);
|
|
||||||
const [input, setInput] = useState(searchTerm || '');
|
|
||||||
const [filteredItems, setFilteredItems] = useState(items);
|
|
||||||
const [selectedIndex, setSelectedIndex] = useState(0);
|
|
||||||
const allItemsRef = useRef([]);
|
|
||||||
const parentElementRef = useRef(null);
|
|
||||||
const scrollSelectedItemInView = index => {
|
|
||||||
if (!parentElementRef.current) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const dropdownMenu = parentElementRef.current;
|
|
||||||
const menuItems = allItemsRef.current;
|
|
||||||
|
|
||||||
if (!menuItems) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const menuItem = menuItems[index];
|
|
||||||
|
|
||||||
if (!menuItem) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const isOutOfUpperView = menuItem.offsetTop < dropdownMenu.scrollTop;
|
|
||||||
const isOutOfLowerView = (menuItem.offsetTop + menuItem.clientHeight) > (dropdownMenu.scrollTop + dropdownMenu.clientHeight);
|
|
||||||
|
|
||||||
if (isOutOfUpperView) {
|
|
||||||
dropdownMenu.scrollTop = menuItem.offsetTop;
|
|
||||||
} else if (isOutOfLowerView) {
|
|
||||||
dropdownMenu.scrollTop = (menuItem.offsetTop + menuItem.clientHeight) - dropdownMenu.clientHeight;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const setSelectInput = value => {
|
|
||||||
setInput(value);
|
|
||||||
onSelect(value);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleClickOutside = event => {
|
|
||||||
if (!parentElementRef.current || parentElementRef.current.contains(event.target)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!filteredItems.length) {
|
|
||||||
setSelectInput('');
|
|
||||||
}
|
|
||||||
|
|
||||||
setShowDropdownMenu(false);
|
|
||||||
onSelect(input);
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
scrollSelectedItemInView(selectedIndex);
|
|
||||||
}, [selectedIndex]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
document.addEventListener('click', handleClickOutside, true);
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
document.removeEventListener('click', handleClickOutside, true);
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const filteredItems = items.filter(item => {
|
|
||||||
if (item[itemKey].toLowerCase().indexOf(input.toLowerCase()) > -1) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (filteredItems.length > 0) {
|
|
||||||
setSelectedIndex(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
setFilteredItems(filteredItems);
|
|
||||||
}, [input, items, itemKey]);
|
|
||||||
|
|
||||||
const selectItemInFocusBy = offset => {
|
|
||||||
const lastIndex = filteredItems.length - 1;
|
|
||||||
const nextIndex = selectedIndex + offset;
|
|
||||||
|
|
||||||
if (nextIndex > lastIndex) {
|
|
||||||
setSelectedIndex(0);
|
|
||||||
} else if (nextIndex < 0) {
|
|
||||||
setSelectedIndex(lastIndex);
|
|
||||||
} else {
|
|
||||||
setSelectedIndex(nextIndex);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleOnKeyDown = event => {
|
|
||||||
if (keys.indexOf(event.key) === -1) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const [arrDown, arrUp, enter, escape] = keys;
|
|
||||||
const moves = {
|
|
||||||
[arrDown]: 1,
|
|
||||||
[arrUp]: -1
|
|
||||||
};
|
|
||||||
const move = moves[event.key];
|
|
||||||
|
|
||||||
if (move !== undefined) {
|
|
||||||
event.preventDefault();
|
|
||||||
selectItemInFocusBy(move);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.key === enter) {
|
|
||||||
if (filteredItems[selectedIndex]) {
|
|
||||||
setSelectInput(filteredItems[selectedIndex][itemKey]);
|
|
||||||
setShowDropdownMenu(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.key === escape) {
|
|
||||||
event.preventDefault();
|
|
||||||
setShowDropdownMenu(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const selectItem = (index: number) => {
|
|
||||||
setSelectInput(filteredItems[index][itemKey]);
|
|
||||||
setSelectedIndex(index);
|
|
||||||
setShowDropdownMenu(false);
|
|
||||||
};
|
|
||||||
|
|
||||||
const generateMenuOptions = () => {
|
|
||||||
return filteredItems.length
|
|
||||||
? filteredItems.slice(0, maxNumOfItemsShown).map((item, index) => {
|
|
||||||
return (
|
|
||||||
<DropdownMenuItem
|
|
||||||
ref={ref => allItemsRef.current[index] = ref}
|
|
||||||
selected={selectedIndex === index}
|
|
||||||
key={`dropdown-menu-item-${index}`}
|
|
||||||
onClick={() => selectItem(index)}
|
|
||||||
>
|
|
||||||
{item[itemKey]}
|
|
||||||
</DropdownMenuItem>
|
|
||||||
);
|
|
||||||
})
|
|
||||||
: (
|
|
||||||
<DropdownMenuItem disabled={true}>
|
|
||||||
No results found
|
|
||||||
</DropdownMenuItem>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleInput = ({target}) => {
|
|
||||||
setInput(target.value);
|
|
||||||
|
|
||||||
if (!showDropdownMenu) {
|
|
||||||
setShowDropdownMenu(true);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const toggleDropdownMenu = () => setShowDropdownMenu(!showDropdownMenu);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<DropdownContainer>
|
|
||||||
<Label
|
|
||||||
htmlFor="autocomplete"
|
|
||||||
text={label}
|
|
||||||
/>
|
|
||||||
<DropdownInput
|
|
||||||
onKeyDown={handleOnKeyDown}
|
|
||||||
showMenu={showDropdownMenu}
|
|
||||||
autoComplete="off"
|
|
||||||
name={name}
|
|
||||||
onChange={handleInput}
|
|
||||||
value={input}
|
|
||||||
onClick={toggleDropdownMenu}
|
|
||||||
className={className}
|
|
||||||
/>
|
|
||||||
{showDropdownMenu && (
|
|
||||||
<DropdownMenu ref={parentElementRef} className="testId-generatedMenuOptions">
|
|
||||||
{generateMenuOptions()}
|
|
||||||
</DropdownMenu>
|
|
||||||
)}
|
|
||||||
</DropdownContainer>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright 2024 Phenix Real Time Solutions, Inc. Confidential and Proprietary. All Rights Reserved.
|
|
||||||
*/
|
|
||||||
import * as styled from 'styled-components';
|
|
||||||
import Input from 'components/forms/Input';
|
|
||||||
import Theme from 'theme';
|
|
||||||
|
|
||||||
const {spacing, colors, typography, primaryBorderRadius} = Theme;
|
|
||||||
|
|
||||||
export const DropdownContainer = styled.default.div`
|
|
||||||
width: 100%;
|
|
||||||
position: relative;
|
|
||||||
margin: ${spacing.xSmall} 0;
|
|
||||||
`;
|
|
||||||
|
|
||||||
export const DropdownInput = styled.default(Input)<{showMenu?: boolean}>`
|
|
||||||
${({showMenu}) => showMenu && styled.css`
|
|
||||||
border-bottom-left-radius: 0px;
|
|
||||||
border-bottom-right-radius: 0px;
|
|
||||||
border-bottom-width: 0;
|
|
||||||
`}
|
|
||||||
`;
|
|
||||||
|
|
||||||
export const DropdownMenu = styled.default.div`
|
|
||||||
width: 100%;
|
|
||||||
overflow-x: hidden;
|
|
||||||
overflow-y: auto;
|
|
||||||
top: calc(100% - 4px);
|
|
||||||
position: absolute;
|
|
||||||
height: auto;
|
|
||||||
max-height: 210px;
|
|
||||||
border: 1px solid ${colors.gray400};
|
|
||||||
border-top-width: 0;
|
|
||||||
z-index: 4;
|
|
||||||
background-color: ${colors.white};
|
|
||||||
border-bottom-left-radius: ${primaryBorderRadius};
|
|
||||||
border-bottom-right-radius: ${primaryBorderRadius};
|
|
||||||
`;
|
|
||||||
|
|
||||||
export const DropdownMenuItem = styled.default.div<{
|
|
||||||
active?: boolean;
|
|
||||||
disabled?: boolean;
|
|
||||||
selected?: boolean;
|
|
||||||
}>`
|
|
||||||
line-height: ${spacing.large};
|
|
||||||
padding: ${spacing.xsmall} ${spacing.medium};
|
|
||||||
font-size: ${typography.fontSizeS};
|
|
||||||
word-wrap: break-word;
|
|
||||||
${({active, selected, disabled}) => styled.css`
|
|
||||||
background-color: ${active || selected ? colors.gray300 : 'transparent'};
|
|
||||||
font-weight: ${selected ? 'bold' : 'normal'};
|
|
||||||
color: ${disabled ? colors.gray500 : colors.gray900}
|
|
||||||
|
|
||||||
:hover{
|
|
||||||
background-color: ${disabled ? colors.white : colors.gray300};
|
|
||||||
cursor: ${disabled ? 'text' : 'pointer'};
|
|
||||||
}
|
|
||||||
`}
|
|
||||||
`;
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright 2024 Phenix Real Time Solutions, Inc. Confidential and Proprietary. All Rights Reserved.
|
|
||||||
*/
|
|
||||||
export * from './indicators';
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright 2024 Phenix Real Time Solutions, Inc. Confidential and Proprietary. All Rights Reserved.
|
|
||||||
*/
|
|
||||||
import React from 'react';
|
|
||||||
import {LoadingWheel as Loader} from 'components';
|
|
||||||
import {SingleStreamSymbol, OfflineSymbol, MultipleStreamSymbol, Indicator} from './style';
|
|
||||||
|
|
||||||
export const OfflineIndicator = (): React.JSX.Element => (
|
|
||||||
<Indicator>
|
|
||||||
<OfflineSymbol />
|
|
||||||
</Indicator>
|
|
||||||
);
|
|
||||||
export const SingleStreamIndicator = (): React.JSX.Element => (
|
|
||||||
<Indicator className="single-stream-indicator">
|
|
||||||
<SingleStreamSymbol className="testId-singleStreamIndicator" />
|
|
||||||
</Indicator>
|
|
||||||
);
|
|
||||||
export const MultiStreamIndicator = (): React.JSX.Element => (
|
|
||||||
<Indicator className="multi-stream-indicator">
|
|
||||||
<MultipleStreamSymbol className="testId-multiStreamIndicator" />
|
|
||||||
</Indicator>
|
|
||||||
);
|
|
||||||
export const LoadingIndicator = (): React.JSX.Element => (
|
|
||||||
<Indicator>
|
|
||||||
<Loader size={'medium'} className="loading-wheel" />
|
|
||||||
</Indicator>
|
|
||||||
);
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright 2024 Phenix Real Time Solutions, Inc. Confidential and Proprietary. All Rights Reserved.
|
|
||||||
*/
|
|
||||||
import * as styled from 'styled-components';
|
|
||||||
|
|
||||||
export const Indicator = styled.default.div`
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
|
|
||||||
/* Target LoadingWheel component by class name */
|
|
||||||
.loading-wheel {
|
|
||||||
flex: 0;
|
|
||||||
margin: 0;
|
|
||||||
|
|
||||||
& span {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
export const IndicatorOutline = styled.default.div`
|
|
||||||
width: 20px;
|
|
||||||
height: 20px;
|
|
||||||
border-radius: 50%;
|
|
||||||
`;
|
|
||||||
|
|
||||||
export const OfflineSymbol = styled.default(IndicatorOutline)`
|
|
||||||
border: 3px solid #707070;
|
|
||||||
background-color: transparent;
|
|
||||||
`;
|
|
||||||
|
|
||||||
export const SingleStreamSymbol = styled.default(IndicatorOutline)`
|
|
||||||
background-color: #08BD0B;
|
|
||||||
`;
|
|
||||||
|
|
||||||
export const MultipleStreamSymbol = styled.default(SingleStreamSymbol)`
|
|
||||||
width: 1rem;
|
|
||||||
height: 1rem;
|
|
||||||
margin-left: -2px;
|
|
||||||
box-shadow: 9px 0 0 0 #08BD0B;
|
|
||||||
`;
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright 2024 Phenix Real Time Solutions, Inc. Confidential and Proprietary. All Rights Reserved.
|
|
||||||
*/
|
|
||||||
import {JSX} from 'react';
|
|
||||||
import {useSelector} from 'react-redux';
|
|
||||||
import {AppStore} from 'store';
|
|
||||||
import {SingleStreamIndicator, OfflineIndicator, MultiStreamIndicator, LoadingIndicator} from './indicators';
|
|
||||||
|
|
||||||
interface IPublishingStateIndicator {
|
|
||||||
row: any;
|
|
||||||
publishingStateKey: string;
|
|
||||||
idKey: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const PublishingStateIndicator = ({row, publishingStateKey, idKey}: IPublishingStateIndicator): JSX.Element => {
|
|
||||||
const id = row[idKey] as string;
|
|
||||||
const publishingState = useSelector((state: AppStore) => publishingStateKey && state[publishingStateKey as keyof AppStore]?.publishingState);
|
|
||||||
const rowPublishingState = publishingState.find((record: any) => record[idKey] === id);
|
|
||||||
|
|
||||||
if (!publishingState) {
|
|
||||||
return <LoadingIndicator />;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!rowPublishingState) {
|
|
||||||
return <LoadingIndicator />;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!rowPublishingState.isOnline) {
|
|
||||||
return <OfflineIndicator />;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rowPublishingState.multipleStreams) {
|
|
||||||
return <MultiStreamIndicator />;
|
|
||||||
}
|
|
||||||
|
|
||||||
return <SingleStreamIndicator />;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default PublishingStateIndicator;
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright 2024 Phenix Real Time Solutions, Inc. Confidential and Proprietary. All Rights Reserved.
|
|
||||||
*/
|
|
||||||
import {createContext} from 'react';
|
|
||||||
|
|
||||||
export const ViewContext = createContext('');
|
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright 2024 Phenix Real Time Solutions, Inc. Confidential and Proprietary. All Rights Reserved.
|
* Copyright 2024 Phenix Real Time Solutions, Inc. Confidential and Proprietary. All Rights Reserved.
|
||||||
*/
|
*/
|
||||||
export * from './contexts';
|
|
||||||
export * from './date';
|
export * from './date';
|
||||||
export * from './sort';
|
export * from './sort';
|
||||||
export * from './validators';
|
export * from './validators';
|
||||||
|
|||||||
Reference in New Issue
Block a user