Skip to content

Commit

Permalink
Merge pull request #174 from tnc-ca-geo/multi-image-select
Browse files Browse the repository at this point in the history
Multi image select
  • Loading branch information
nathanielrindlaub authored Dec 15, 2023
2 parents d1fb316 + 36261c9 commit ce1f74a
Show file tree
Hide file tree
Showing 41 changed files with 844 additions and 562 deletions.
2 changes: 1 addition & 1 deletion src/app/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import * as Tooltip from '@radix-ui/react-tooltip';
import * as Toast from '@radix-ui/react-toast';
import { initTracking } from '../features/tracking/trackingSlice';
import { selectRouterLocation } from '../features/images/imagesSlice';
import { userAuthStateChanged } from '../features/user/userSlice';
import { userAuthStateChanged } from '../features/auth/authSlice';
import { mouseEventDetected, selectIsDrawingBbox } from '../features/loupe/loupeSlice';
import logo from '../assets/animl-logo.svg';
import { IN_MAINTENANCE_MODE, GA_CONFIG, AWS_AUTH_CONFIG } from '../config';
Expand Down
6 changes: 3 additions & 3 deletions src/app/rootReducer.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
import { combineReducers } from '@reduxjs/toolkit';
import { connectRouter } from 'connected-react-router';
import { undoHistoryReducer } from 'redux-undo-redo';
import userSlice from '../features/user/userSlice';
import authSlice from '../features/auth/authSlice';
import filtersReducer from '../features/filters/filtersSlice';
import imagesReducer from '../features/images/imagesSlice';
import wirelessCamerasReducer from '../features/cameras/wirelessCamerasSlice';
import reviewReducer from '../features/review/reviewSlice';
import loupeReducer from '../features/loupe/loupeSlice';
import projectReducer from '../features/projects/projectsSlice';
import usersReducer from '../features/projects/userSlice';
import usersReducer from '../features/projects/usersSlice';
import trackingReducer from '../features/tracking/trackingSlice';
import uploadReducer from '../features/upload/uploadSlice';

const createRootReducer = (history) => combineReducers({
router: connectRouter(history),
user: userSlice,
auth: authSlice,
projects: projectReducer,
users: usersReducer,
filters: filtersReducer,
Expand Down
98 changes: 98 additions & 0 deletions src/components/CategorySelector.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import React, { forwardRef } from 'react';
import { styled } from '../theme/stitches.config.js';
import { useSelector, useDispatch } from 'react-redux';
import CreatableSelect from 'react-select/creatable';
import { createFilter } from 'react-select';
import { selectAvailLabels } from '../features/filters/filtersSlice.js';
import { addLabelEnd } from '../features/loupe/loupeSlice.js';


const StyledCategorySelector = styled(CreatableSelect, {
width: '155px',
fontFamily: '$mono',
fontSize: '$2',
fontWeight: '$1',
zIndex: '$5',
'.react-select__control': {
boxSizing: 'border-box',
// height: '24px',
minHeight: 'unset',
border: '1px solid',
borderColor: '$border',
borderRadius: '$2',
cursor: 'pointer',
},
'.react-select__single-value': {
// position: 'relative',
},
'.react-select__indicator-separator': {
display: 'none',
},
'.react-select__dropdown-indicator': {
paddingTop: '0',
paddingBottom: '0',
},
'.react-select__control--is-focused': {
transition: 'all 0.2s ease',
boxShadow: '0 0 0 3px $blue200',
borderColor: '$blue500',
'&:hover': {
boxShadow: '0 0 0 3px $blue200',
borderColor: '$blue500',
},
},
'.react-select__menu': {
color: '$textDark',
fontSize: '$3',
'.react-select__option': {
cursor: 'pointer',
},
'.react-select__option--is-selected': {
color: '$blue500',
backgroundColor: '$blue200',
},
'.react-select__option--is-focused': {
backgroundColor: '$gray3',
},
}
});


const CategorySelector = forwardRef(({
css,
handleCategoryChange,
handleCategorySelectorBlur,
menuPlacement='top'
}, ref) => {

// update selector options when new labels become available
const createOption = (category) => ({ value: category.toLowerCase(), label: category });
const availLabels = useSelector(selectAvailLabels);
const options = availLabels.ids.map((id) => createOption(id));
const dispatch = useDispatch();

const defaultHandleBlur = (e) => dispatch(addLabelEnd());

return (
<StyledCategorySelector
ref={ref}
css={css}
autoFocus
isClearable
isSearchable
openMenuOnClick
className='react-select'
classNamePrefix='react-select'
menuPlacement={menuPlacement}
filterOption={createFilter({ matchFrom: 'start' })}
isLoading={availLabels.isLoading}
isDisabled={availLabels.isLoading}
onChange={handleCategoryChange}
onCreateOption={handleCategoryChange}
onBlur={handleCategorySelectorBlur || defaultHandleBlur}
options={options}
/>
);
});

export default CategorySelector;
6 changes: 3 additions & 3 deletions src/components/ContextMenu.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ const itemStyles = {
all: 'unset',
fontSize: 13,
lineHeight: 1,
color: violet.violet11,
color: '$textDark',
borderRadius: 3,
display: 'flex',
alignItems: 'center',
Expand All @@ -55,8 +55,8 @@ const itemStyles = {
},

'&[data-highlighted]': {
backgroundColor: violet.violet9,
color: violet.violet1,
backgroundColor: '$hiContrast',
color: '$loContrast',
},
};

Expand Down
2 changes: 1 addition & 1 deletion src/components/ErrorAlerts.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ import {
dismissExportError,
} from '../features/images/imagesSlice';
import getErrorContent from '../content/Errors';
import { selectManageUserErrors, dismissManageUsersError } from '../features/projects/userSlice';
import { selectManageUserErrors, dismissManageUsersError } from '../features/projects/usersSlice';

// TODO: add updateAutomationRules errors

Expand Down
2 changes: 1 addition & 1 deletion src/components/HydratedModal.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {
setModalOpen,
setModalContent
} from '../features/projects/projectsSlice';
import { clearUsers } from '../features/projects/userSlice.js';
import { clearUsers } from '../features/projects/usersSlice.js';

// Modal populated with content
const HydratedModal = () => {
Expand Down
2 changes: 1 addition & 1 deletion src/components/NavBar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react';
import { useSelector } from 'react-redux';
import { styled } from '../theme/stitches.config.js';
import { Link } from 'react-router-dom';
import { selectUserUsername, selectUserAuthStatus } from '../features/user/userSlice.js';
import { selectUserUsername, selectUserAuthStatus } from '../features/auth/authSlice.js';
import { selectRouterLocation } from '../features/images/imagesSlice.js';
import ProjectAndViewNav from '../features/projects/ProjectAndViewNav.jsx';
import { useAuthenticator } from '@aws-amplify/ui-react';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { indigo } from '@radix-ui/colors';
import Button from '../../components/Button.jsx';
import '@aws-amplify/ui-react/styles.css';
import { useSelector } from 'react-redux';
import { selectUserUsername } from './userSlice.js';
import { selectUserUsername } from './authSlice.js';

const LoginScreen = styled('div', {
display: 'flex',
Expand Down
20 changes: 10 additions & 10 deletions src/features/user/userSlice.js → src/features/auth/authSlice.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ const initialState = {
authStatus: null,
};

export const userSlice = createSlice({
name: 'user',
export const authSlice = createSlice({
name: 'auth',
initialState,
reducers: {

Expand Down Expand Up @@ -43,15 +43,15 @@ export const userSlice = createSlice({

export const {
userAuthStateChanged,
} = userSlice.actions;
} = authSlice.actions;

// Selectors
export const selectUserAuthStatus = state => state.user.authStatus;
export const selectUserGroups = state => state.user.groups;
export const selectUserUsername = state => state.user.username;
export const selectUserProjects = state => state.user.projects;
export const selectUserIsSuperUser = state => state.user.groups && state.user.groups.includes('animl_superuser');
export const selectUserHasBetaAccess = state => state.user.groups.includes('beta_access');
export const selectUserAuthStatus = state => state.auth.authStatus;
export const selectUserGroups = state => state.auth.groups;
export const selectUserUsername = state => state.auth.username;
export const selectUserProjects = state => state.auth.projects;
export const selectUserIsSuperUser = state => state.auth.groups && state.auth.groups.includes('animl_superuser');
export const selectUserHasBetaAccess = state => state.auth.groups.includes('beta_access');
export const selectUserCurrentRoles = createSelector(
[selectSelectedProject, selectUserProjects, selectUserIsSuperUser],
(selectedProject, userProjects, isSuperUser) => {
Expand All @@ -67,4 +67,4 @@ export const selectUserCurrentRoles = createSelector(
);


export default userSlice.reducer;
export default authSlice.reducer;
File renamed without changes.
4 changes: 2 additions & 2 deletions src/features/cameras/CameraAdminModal.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useEffect, useState }from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { selectUserCurrentRoles } from '../user/userSlice';
import { hasRole, WRITE_CAMERA_REGISTRATION_ROLES } from '../../auth/roles';
import { selectUserCurrentRoles } from '../auth/authSlice';
import { hasRole, WRITE_CAMERA_REGISTRATION_ROLES } from '../auth/roles';
import {
selectWirelessCamerasLoading,
selectWirelessCameras,
Expand Down
4 changes: 2 additions & 2 deletions src/features/cameras/CameraList.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { DateTime } from 'luxon';
import { styled } from '../../theme/stitches.config';
import { selectUserCurrentRoles } from '../user/userSlice';
import { selectUserCurrentRoles } from '../auth/authSlice';
import { unregisterCamera } from './wirelessCamerasSlice';
import Accordion from '../../components/Accordion';
import IconButton from '../../components/IconButton';
Expand All @@ -11,7 +11,7 @@ import {
hasRole,
WRITE_CAMERA_REGISTRATION_ROLES,
WRITE_DEPLOYMENTS_ROLES
} from '../../auth/roles';
} from '../auth/roles';


const StyledCameraList = styled('div', {
Expand Down
4 changes: 2 additions & 2 deletions src/features/filters/FiltersPanel.jsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React from 'react';
import { useSelector } from 'react-redux';
import { styled } from '../../theme/stitches.config.js';
import { selectUserCurrentRoles } from '../user/userSlice.js';
import { hasRole, QUERY_WITH_CUSTOM_FILTER } from '../../auth/roles.js';
import { selectUserCurrentRoles } from '../auth/authSlice.js';
import { hasRole, QUERY_WITH_CUSTOM_FILTER } from '../auth/roles.js';
import PanelHeader from '../../components/PanelHeader.jsx';
import StyledScrollArea from '../../components/ScrollArea.jsx';
import DeploymentFilter from './DeploymentFilter.jsx';
Expand Down
4 changes: 2 additions & 2 deletions src/features/filters/FiltersPanelFooter.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import { styled } from '../../theme/stitches.config.js';
import { selectUserCurrentRoles } from '../user/userSlice.js';
import { hasRole, READ_STATS_ROLES, EXPORT_DATA_ROLES } from '../../auth/roles.js';
import { selectUserCurrentRoles } from '../auth/authSlice.js';
import { hasRole, READ_STATS_ROLES, EXPORT_DATA_ROLES } from '../auth/roles.js';
import { useDispatch, useSelector } from 'react-redux';
import { selectImagesCount, fetchImages } from '../images/imagesSlice.js';
import { selectActiveFilters } from './filtersSlice.js';
Expand Down
Loading

0 comments on commit ce1f74a

Please sign in to comment.