Removing Prisma and Grapql-nestjs-prisma resolvers (#2574)
* Some cleaning * Fix seeds * Fix all sign in, sign up flow and apiKey optimistic rendering * Fix
This commit is contained in:
@ -10,7 +10,7 @@ import {
|
||||
import { Checkmark } from '@/ui/display/checkmark/components/Checkmark';
|
||||
import DarkNoise from '@/ui/theme/assets/dark-noise.jpg';
|
||||
import LightNoise from '@/ui/theme/assets/light-noise.png';
|
||||
import { ColorScheme } from '~/generated/graphql';
|
||||
import { ColorScheme } from '@/workspace-member/types/WorkspaceMember';
|
||||
|
||||
const StyledColorSchemeBackground = styled.div<
|
||||
Pick<ColorSchemeCardProps, 'variant'>
|
||||
@ -18,18 +18,18 @@ const StyledColorSchemeBackground = styled.div<
|
||||
align-items: flex-end;
|
||||
background: ${({ variant }) => {
|
||||
switch (variant) {
|
||||
case 'dark':
|
||||
case 'Dark':
|
||||
return `url(${DarkNoise.toString()});`;
|
||||
case 'light':
|
||||
case 'Light':
|
||||
default:
|
||||
return `url(${LightNoise.toString()});`;
|
||||
}
|
||||
}};
|
||||
border: ${({ variant, theme }) => {
|
||||
switch (variant) {
|
||||
case 'dark':
|
||||
case 'Dark':
|
||||
return `1px solid ${theme.grayScale.gray70};`;
|
||||
case 'light':
|
||||
case 'Light':
|
||||
default:
|
||||
return `1px solid ${theme.grayScale.gray20};`;
|
||||
}
|
||||
@ -51,18 +51,18 @@ const StyledColorSchemeContent = styled(motion.div)<
|
||||
>`
|
||||
background: ${({ theme, variant }) => {
|
||||
switch (variant) {
|
||||
case 'dark':
|
||||
case 'Dark':
|
||||
return theme.grayScale.gray75;
|
||||
case 'light':
|
||||
case 'Light':
|
||||
return theme.grayScale.gray0;
|
||||
}
|
||||
}};
|
||||
|
||||
border-left: ${({ variant, theme }) => {
|
||||
switch (variant) {
|
||||
case 'dark':
|
||||
case 'Dark':
|
||||
return `1px solid ${theme.grayScale.gray60};`;
|
||||
case 'light':
|
||||
case 'Light':
|
||||
default:
|
||||
return `1px solid ${theme.grayScale.gray20};`;
|
||||
}
|
||||
@ -70,9 +70,9 @@ const StyledColorSchemeContent = styled(motion.div)<
|
||||
border-radius: ${({ theme }) => theme.border.radius.md} 0px 0px 0px;
|
||||
border-top: ${({ variant, theme }) => {
|
||||
switch (variant) {
|
||||
case 'dark':
|
||||
case 'Dark':
|
||||
return `1px solid ${theme.grayScale.gray60};`;
|
||||
case 'light':
|
||||
case 'Light':
|
||||
default:
|
||||
return `1px solid ${theme.grayScale.gray20};`;
|
||||
}
|
||||
@ -80,9 +80,9 @@ const StyledColorSchemeContent = styled(motion.div)<
|
||||
box-sizing: border-box;
|
||||
color: ${({ variant, theme }) => {
|
||||
switch (variant) {
|
||||
case 'dark':
|
||||
case 'Dark':
|
||||
return theme.grayScale.gray30;
|
||||
case 'light':
|
||||
case 'Light':
|
||||
default:
|
||||
return theme.grayScale.gray60;
|
||||
}
|
||||
@ -96,7 +96,7 @@ const StyledColorSchemeContent = styled(motion.div)<
|
||||
`;
|
||||
|
||||
export type ColorSchemeSegmentProps = {
|
||||
variant: `${Lowercase<ColorScheme.Dark | ColorScheme.Light>}`;
|
||||
variant: ColorScheme;
|
||||
controls: AnimationControls;
|
||||
} & React.ComponentPropsWithoutRef<'div'>;
|
||||
|
||||
@ -139,7 +139,7 @@ const StyledCheckmarkContainer = styled(motion.div)`
|
||||
`;
|
||||
|
||||
export type ColorSchemeCardProps = {
|
||||
variant: `${Lowercase<ColorScheme>}`;
|
||||
variant: ColorScheme;
|
||||
selected?: boolean;
|
||||
} & React.ComponentPropsWithoutRef<'div'>;
|
||||
|
||||
@ -172,7 +172,7 @@ export const ColorSchemeCard = ({
|
||||
});
|
||||
};
|
||||
|
||||
if (variant === 'system') {
|
||||
if (variant === 'System') {
|
||||
return (
|
||||
<StyledContainer>
|
||||
<StyledMixedColorSchemeSegment
|
||||
@ -183,12 +183,12 @@ export const ColorSchemeCard = ({
|
||||
<ColorSchemeSegment
|
||||
style={{ borderTopRightRadius: 0, borderBottomRightRadius: 0 }}
|
||||
controls={controls}
|
||||
variant="light"
|
||||
variant="Light"
|
||||
/>
|
||||
<ColorSchemeSegment
|
||||
style={{ borderTopLeftRadius: 0, borderBottomLeftRadius: 0 }}
|
||||
controls={controls}
|
||||
variant="dark"
|
||||
variant="Dark"
|
||||
/>
|
||||
</StyledMixedColorSchemeSegment>
|
||||
<AnimatePresence>
|
||||
|
||||
@ -38,7 +38,7 @@ export const ColorSchemePicker = ({
|
||||
<StyledCardContainer>
|
||||
<ColorSchemeCard
|
||||
onClick={() => onChange('Light')}
|
||||
variant="light"
|
||||
variant="Light"
|
||||
selected={value === 'Light'}
|
||||
/>
|
||||
<StyledLabel>Light</StyledLabel>
|
||||
@ -46,7 +46,7 @@ export const ColorSchemePicker = ({
|
||||
<StyledCardContainer>
|
||||
<ColorSchemeCard
|
||||
onClick={() => onChange('Dark')}
|
||||
variant="dark"
|
||||
variant="Dark"
|
||||
selected={value === 'Dark'}
|
||||
/>
|
||||
<StyledLabel>Dark</StyledLabel>
|
||||
@ -54,7 +54,7 @@ export const ColorSchemePicker = ({
|
||||
<StyledCardContainer>
|
||||
<ColorSchemeCard
|
||||
onClick={() => onChange('System')}
|
||||
variant="system"
|
||||
variant="System"
|
||||
selected={value === 'System'}
|
||||
/>
|
||||
<StyledLabel>System settings</StyledLabel>
|
||||
|
||||
@ -36,9 +36,9 @@ type Story = StoryObj<typeof ColorSchemeCard>;
|
||||
export const Default: Story = {
|
||||
render: (args) => (
|
||||
<>
|
||||
<ColorSchemeCard variant="light" selected={args.selected} />
|
||||
<ColorSchemeCard variant="dark" selected={args.selected} />
|
||||
<ColorSchemeCard variant="system" selected={args.selected} />
|
||||
<ColorSchemeCard variant="Light" selected={args.selected} />
|
||||
<ColorSchemeCard variant="Dark" selected={args.selected} />
|
||||
<ColorSchemeCard variant="System" selected={args.selected} />
|
||||
</>
|
||||
),
|
||||
};
|
||||
|
||||
@ -17,7 +17,7 @@ import { SingleEntitySelect } from '../SingleEntitySelect';
|
||||
const entities = mockedPeopleData.map<EntityForSelect>((person) => ({
|
||||
id: person.id,
|
||||
entityType: Entity.Person,
|
||||
name: person.displayName,
|
||||
name: person.name.firstName + ' ' + person.name.lastName,
|
||||
originalEntity: person,
|
||||
}));
|
||||
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import { ActivityTargetableEntityType } from '@/activities/types/ActivityTargetableEntity';
|
||||
import { PipelineProgressableType } from '~/generated/graphql';
|
||||
|
||||
export enum Entity {
|
||||
Company = 'Company',
|
||||
@ -8,7 +7,4 @@ export enum Entity {
|
||||
WorkspaceMember = 'WorkspaceMember',
|
||||
}
|
||||
|
||||
export type EntityTypeForSelect =
|
||||
| ActivityTargetableEntityType
|
||||
| PipelineProgressableType
|
||||
| Entity;
|
||||
export type EntityTypeForSelect = ActivityTargetableEntityType | Entity;
|
||||
|
||||
@ -2,7 +2,6 @@ import { useCallback, useContext, useRef, useState } from 'react';
|
||||
import styled from '@emotion/styled';
|
||||
import { Key } from 'ts-key-enum';
|
||||
|
||||
import { useCreateCompanyProgress } from '@/companies/hooks/useCreateCompanyProgress';
|
||||
import { useFilteredSearchCompanyQuery } from '@/companies/hooks/useFilteredSearchCompanyQuery';
|
||||
import {
|
||||
IconArrowLeft,
|
||||
@ -57,7 +56,6 @@ export const BoardColumnMenu = ({
|
||||
const boardColumnMenuRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const { enqueueSnackBar } = useSnackBar();
|
||||
const createCompanyProgress = useCreateCompanyProgress();
|
||||
const { handleMoveBoardColumn } = useBoardColumns();
|
||||
|
||||
const handleCompanySelected = (
|
||||
@ -75,7 +73,7 @@ export const BoardColumnMenu = ({
|
||||
return;
|
||||
}
|
||||
|
||||
createCompanyProgress(selectedCompany.id, stageId);
|
||||
//createCompanyProgress(selectedCompany.id, stageId);
|
||||
closeMenu();
|
||||
};
|
||||
|
||||
|
||||
@ -14,7 +14,6 @@ import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
|
||||
import { useListenClickOutsideByClassName } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
|
||||
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
|
||||
import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper';
|
||||
import { PipelineProgress, PipelineStage } from '~/generated/graphql';
|
||||
import { logError } from '~/utils/logError';
|
||||
|
||||
import { useCurrentCardSelected } from '../hooks/useCurrentCardSelected';
|
||||
@ -58,7 +57,7 @@ export const EntityBoard = ({
|
||||
|
||||
const { updateOneObject: updateOneOpportunity } =
|
||||
useUpdateOneObjectRecord<Opportunity>({
|
||||
objectNameSingular: 'opportunityV2',
|
||||
objectNameSingular: 'opportunity',
|
||||
});
|
||||
|
||||
const apolloClient = useApolloClient();
|
||||
@ -66,10 +65,7 @@ export const EntityBoard = ({
|
||||
const { unselectAllActiveCards } = useCurrentCardSelected();
|
||||
|
||||
const updatePipelineProgressStageInDB = useCallback(
|
||||
async (
|
||||
pipelineProgressId: NonNullable<PipelineProgress['id']>,
|
||||
pipelineStageId: NonNullable<PipelineStage['id']>,
|
||||
) => {
|
||||
async (pipelineProgressId: string, pipelineStageId: string) => {
|
||||
await updateOneOpportunity?.({
|
||||
idToUpdate: pipelineProgressId,
|
||||
input: {
|
||||
|
||||
@ -14,7 +14,7 @@ export const useBoardColumns = () => {
|
||||
|
||||
const { updateOneObject: updateOnePipelineStep } =
|
||||
useUpdateOneObjectRecord<PipelineStep>({
|
||||
objectNameSingular: 'pipelineStepV2',
|
||||
objectNameSingular: 'pipelineStep',
|
||||
});
|
||||
|
||||
const updatedPipelineStages = (stages: BoardColumnDefinition[]) => {
|
||||
|
||||
@ -14,7 +14,7 @@ export const useDeleteSelectedBoardCards = () => {
|
||||
|
||||
const { deleteOneObject: deleteOneOpportunity } =
|
||||
useDeleteOneObjectRecord<Opportunity>({
|
||||
objectNameSingular: 'opportunityV2',
|
||||
objectNameSingular: 'opportunity',
|
||||
});
|
||||
|
||||
const deleteSelectedBoardCards = useRecoilCallback(
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
import { ComponentType } from 'react';
|
||||
|
||||
import { Opportunity } from '@/pipeline/types/Opportunity';
|
||||
import { FilterDefinitionByEntity } from '@/ui/object/object-filter-dropdown/types/FilterDefinitionByEntity';
|
||||
import { SortDefinition } from '@/ui/object/object-sort-dropdown/types/SortDefinition';
|
||||
import { PipelineProgress } from '~/generated/graphql';
|
||||
|
||||
export type BoardOptions = {
|
||||
newCardComponent: React.ReactNode;
|
||||
CardComponent: ComponentType;
|
||||
filterDefinitions: FilterDefinitionByEntity<PipelineProgress>[];
|
||||
filterDefinitions: FilterDefinitionByEntity<Opportunity>[];
|
||||
sortDefinitions: SortDefinition[];
|
||||
};
|
||||
|
||||
@ -55,7 +55,6 @@ type DefaultLayoutProps = {
|
||||
|
||||
export const DefaultLayout = ({ children }: DefaultLayoutProps) => {
|
||||
const onboardingStatus = useOnboardingStatus();
|
||||
|
||||
return (
|
||||
<StyledLayout>
|
||||
<CommandMenu />
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
import { useOpenCreateActivityDrawer } from '@/activities/hooks/useOpenCreateActivityDrawer';
|
||||
import { ActivityType } from '@/activities/types/Activity';
|
||||
import { ActivityTargetableEntity } from '@/activities/types/ActivityTargetableEntity';
|
||||
import { PageHotkeyScope } from '@/types/PageHotkeyScope';
|
||||
import { IconCheckbox, IconNotes, IconPlus } from '@/ui/display/icon/index';
|
||||
@ -8,7 +9,6 @@ import { IconButton } from '@/ui/input/button/components/IconButton';
|
||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
||||
import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
|
||||
import { ActivityType } from '~/generated/graphql';
|
||||
|
||||
import { Dropdown } from '../../dropdown/components/Dropdown';
|
||||
import { DropdownMenu } from '../../dropdown/components/DropdownMenu';
|
||||
@ -51,13 +51,13 @@ export const ShowPageAddButton = ({
|
||||
<DropdownMenu>
|
||||
<DropdownMenuItemsContainer>
|
||||
<MenuItem
|
||||
onClick={() => handleSelect(ActivityType.Note)}
|
||||
onClick={() => handleSelect('Note')}
|
||||
accent="default"
|
||||
LeftIcon={IconNotes}
|
||||
text="Note"
|
||||
/>
|
||||
<MenuItem
|
||||
onClick={() => handleSelect(ActivityType.Task)}
|
||||
onClick={() => handleSelect('Task')}
|
||||
accent="default"
|
||||
LeftIcon={IconCheckbox}
|
||||
text="Task"
|
||||
|
||||
@ -2,8 +2,6 @@ import { MemoryRouter } from 'react-router-dom';
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
import { useSetRecoilState } from 'recoil';
|
||||
|
||||
import { useCompanyTableContextMenuEntries } from '@/companies/hooks/useCompanyTableContextMenuEntries';
|
||||
import { CompanyTableMockMode } from '@/companies/table/components/CompanyTableMockMode';
|
||||
import { RecordTableScope } from '@/ui/object/record-table/scopes/RecordTableScope';
|
||||
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
|
||||
|
||||
@ -11,8 +9,6 @@ import { actionBarOpenState } from '../../states/actionBarIsOpenState';
|
||||
import { ActionBar } from '../ActionBar';
|
||||
|
||||
const FilledActionBar = (props: { selectedIds: string[] }) => {
|
||||
const { setActionBarEntries } = useCompanyTableContextMenuEntries();
|
||||
setActionBarEntries();
|
||||
const setActionBarOpenState = useSetRecoilState(actionBarOpenState);
|
||||
setActionBarOpenState(true);
|
||||
return <ActionBar selectedIds={props.selectedIds} />;
|
||||
@ -26,10 +22,8 @@ const meta: Meta<typeof ActionBar> = {
|
||||
<RecordTableScope
|
||||
recordTableScopeId="companies"
|
||||
onColumnsChange={() => {}}
|
||||
onEntityCountChange={() => {}}
|
||||
>
|
||||
<MemoryRouter>
|
||||
<CompanyTableMockMode />
|
||||
<Story />
|
||||
</MemoryRouter>
|
||||
</RecordTableScope>
|
||||
|
||||
@ -2,8 +2,6 @@ import { MemoryRouter } from 'react-router-dom';
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
import { useSetRecoilState } from 'recoil';
|
||||
|
||||
import { useCompanyTableContextMenuEntries } from '@/companies/hooks/useCompanyTableContextMenuEntries';
|
||||
import { CompanyTableMockMode } from '@/companies/table/components/CompanyTableMockMode';
|
||||
import { RecordTableScope } from '@/ui/object/record-table/scopes/RecordTableScope';
|
||||
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
|
||||
|
||||
@ -12,8 +10,6 @@ import { contextMenuPositionState } from '../../states/contextMenuPositionState'
|
||||
import { ContextMenu } from '../ContextMenu';
|
||||
|
||||
const FilledContextMenu = (props: { selectedIds: string[] }) => {
|
||||
const { setContextMenuEntries } = useCompanyTableContextMenuEntries();
|
||||
setContextMenuEntries();
|
||||
const setContextMenuPosition = useSetRecoilState(contextMenuPositionState);
|
||||
setContextMenuPosition({
|
||||
x: 100,
|
||||
@ -32,10 +28,8 @@ const meta: Meta<typeof ContextMenu> = {
|
||||
<RecordTableScope
|
||||
recordTableScopeId="companies"
|
||||
onColumnsChange={() => {}}
|
||||
onEntityCountChange={() => {}}
|
||||
>
|
||||
<MemoryRouter>
|
||||
<CompanyTableMockMode></CompanyTableMockMode>
|
||||
<Story />
|
||||
</MemoryRouter>
|
||||
</RecordTableScope>
|
||||
|
||||
@ -30,6 +30,7 @@ const meta: Meta = {
|
||||
fieldMetadataId: 'date',
|
||||
label: 'Date',
|
||||
type: 'DATE',
|
||||
iconName: 'IconCalendarEvent',
|
||||
metadata: {
|
||||
fieldName: 'Date',
|
||||
},
|
||||
|
||||
@ -29,6 +29,7 @@ const meta: Meta = {
|
||||
fieldMetadataId: 'email',
|
||||
label: 'Email',
|
||||
type: 'EMAIL',
|
||||
iconName: 'IconLink',
|
||||
metadata: {
|
||||
fieldName: 'Email',
|
||||
placeHolder: 'Email',
|
||||
|
||||
@ -28,6 +28,7 @@ const meta: Meta = {
|
||||
fieldDefinition: {
|
||||
fieldMetadataId: 'enum',
|
||||
label: 'Enum',
|
||||
iconName: 'IconTag',
|
||||
type: 'ENUM',
|
||||
metadata: {
|
||||
fieldName: 'Enum',
|
||||
|
||||
@ -28,6 +28,7 @@ const meta: Meta = {
|
||||
fieldMetadataId: 'money',
|
||||
label: 'Money',
|
||||
type: 'MONEY_AMOUNT',
|
||||
iconName: 'Icon123',
|
||||
metadata: {
|
||||
fieldName: 'Amount',
|
||||
placeHolder: 'Amount',
|
||||
|
||||
@ -28,6 +28,7 @@ const meta: Meta = {
|
||||
fieldMetadataId: 'number',
|
||||
label: 'Number',
|
||||
type: 'NUMBER',
|
||||
iconName: 'Icon123',
|
||||
metadata: {
|
||||
fieldName: 'Number',
|
||||
placeHolder: 'Number',
|
||||
|
||||
@ -29,6 +29,7 @@ const meta: Meta = {
|
||||
fieldMetadataId: 'phone',
|
||||
label: 'Phone',
|
||||
type: 'PHONE',
|
||||
iconName: 'IconPhone',
|
||||
metadata: {
|
||||
fieldName: 'Phone',
|
||||
placeHolder: 'Phone',
|
||||
|
||||
@ -28,6 +28,7 @@ const meta: Meta = {
|
||||
fieldMetadataId: 'text',
|
||||
label: 'Text',
|
||||
type: 'TEXT',
|
||||
iconName: 'IconLink',
|
||||
metadata: {
|
||||
fieldName: 'Text',
|
||||
placeHolder: 'Text',
|
||||
|
||||
@ -29,6 +29,7 @@ const meta: Meta = {
|
||||
fieldMetadataId: 'URL',
|
||||
label: 'URL',
|
||||
type: 'URL',
|
||||
iconName: 'IconLink',
|
||||
metadata: {
|
||||
fieldName: 'URL',
|
||||
placeHolder: 'URL',
|
||||
|
||||
@ -4,7 +4,7 @@ import styled from '@emotion/styled';
|
||||
import { CompanyPicker } from '@/companies/components/CompanyPicker';
|
||||
import { PeoplePicker } from '@/people/components/PeoplePicker';
|
||||
import { EntityForSelect } from '@/ui/input/relation-picker/types/EntityForSelect';
|
||||
import { UserPicker } from '@/users/components/UserPicker';
|
||||
import { WorkspaceMemberPicker } from '@/workspace-member/components/WorkspaceMemberPicker';
|
||||
|
||||
import { usePersistField } from '../../../hooks/usePersistField';
|
||||
import { useRelationField } from '../../hooks/useRelationField';
|
||||
@ -48,7 +48,7 @@ export const RelationFieldInput = ({
|
||||
initialSearchFilter={initialSearchValue}
|
||||
/>
|
||||
) : fieldDefinition.metadata.fieldName === 'accountOwner' ? (
|
||||
<UserPicker
|
||||
<WorkspaceMemberPicker
|
||||
userId={initialValue?.id ?? ''}
|
||||
onSubmit={handleSubmit}
|
||||
onCancel={onCancel}
|
||||
|
||||
@ -35,6 +35,7 @@ const BooleanFieldInputWithContext = ({
|
||||
fieldDefinition={{
|
||||
fieldMetadataId: 'boolean',
|
||||
label: 'Boolean',
|
||||
iconName: 'Icon123',
|
||||
type: 'BOOLEAN',
|
||||
metadata: {
|
||||
fieldName: 'Boolean',
|
||||
|
||||
@ -47,6 +47,7 @@ const ChipFieldInputWithContext = ({
|
||||
fieldMetadataId: 'chip',
|
||||
label: 'Chip',
|
||||
type: 'CHIP',
|
||||
iconName: 'Icon123',
|
||||
metadata: {
|
||||
contentFieldName: 'name',
|
||||
urlFieldName: 'xURL',
|
||||
|
||||
@ -46,6 +46,7 @@ const DateFieldInputWithContext = ({
|
||||
fieldMetadataId: 'date',
|
||||
label: 'Date',
|
||||
type: 'DATE',
|
||||
iconName: 'IconCalendarEvent',
|
||||
metadata: {
|
||||
fieldName: 'Date',
|
||||
},
|
||||
|
||||
@ -60,6 +60,7 @@ const DoubleTextChipFieldInputWithContext = ({
|
||||
fieldMetadataId: 'double-text-chip',
|
||||
label: 'Double-Text-Chip',
|
||||
type: 'DOUBLE_TEXT_CHIP',
|
||||
iconName: 'IconUser',
|
||||
metadata: {
|
||||
firstValueFieldName: 'First-text',
|
||||
firstValuePlaceholder: 'First-text',
|
||||
|
||||
@ -46,6 +46,7 @@ const EmailFieldInputWithContext = ({
|
||||
fieldMetadataId: 'email',
|
||||
label: 'Email',
|
||||
type: 'EMAIL',
|
||||
iconName: 'IconLink',
|
||||
metadata: {
|
||||
fieldName: 'email',
|
||||
placeHolder: 'username@email.com',
|
||||
|
||||
@ -46,6 +46,7 @@ const MoneyFieldInputWithContext = ({
|
||||
fieldMetadataId: 'moneyAmount',
|
||||
label: 'MoneyAmout',
|
||||
type: 'MONEY_AMOUNT',
|
||||
iconName: 'Icon123',
|
||||
metadata: {
|
||||
fieldName: 'moneyAmount',
|
||||
placeHolder: 'Enter Amount',
|
||||
|
||||
@ -45,6 +45,7 @@ const NumberFieldInputWithContext = ({
|
||||
fieldDefinition={{
|
||||
fieldMetadataId: 'number',
|
||||
label: 'Number',
|
||||
iconName: 'Icon123',
|
||||
type: 'NUMBER',
|
||||
metadata: {
|
||||
fieldName: 'number',
|
||||
|
||||
@ -46,6 +46,7 @@ const PhoneFieldInputWithContext = ({
|
||||
fieldMetadataId: 'phone',
|
||||
label: 'Phone',
|
||||
type: 'PHONE',
|
||||
iconName: 'IconPhone',
|
||||
metadata: {
|
||||
fieldName: 'Phone',
|
||||
placeHolder: 'Enter phone number',
|
||||
|
||||
@ -44,6 +44,7 @@ const ProbabilityFieldInputWithContext = ({
|
||||
fieldMetadataId: 'probability',
|
||||
label: 'Probability',
|
||||
type: 'PROBABILITY',
|
||||
iconName: 'Icon123',
|
||||
metadata: {
|
||||
fieldName: 'Probability',
|
||||
},
|
||||
|
||||
@ -49,6 +49,7 @@ const RelationFieldInputWithContext = ({
|
||||
fieldMetadataId: 'relation',
|
||||
label: 'Relation',
|
||||
type: 'RELATION',
|
||||
iconName: 'IconLink',
|
||||
metadata: {
|
||||
fieldName: 'Relation',
|
||||
relationType: Entity.Person,
|
||||
|
||||
@ -46,6 +46,7 @@ const TextFieldInputWithContext = ({
|
||||
fieldMetadataId: 'text',
|
||||
label: 'Text',
|
||||
type: 'TEXT',
|
||||
iconName: 'IconTag',
|
||||
metadata: {
|
||||
fieldName: 'Text',
|
||||
placeHolder: 'Enter text',
|
||||
|
||||
@ -46,6 +46,7 @@ const URLFieldInputWithContext = ({
|
||||
fieldMetadataId: 'url',
|
||||
label: 'URL',
|
||||
type: 'URL',
|
||||
iconName: 'IconLink',
|
||||
metadata: {
|
||||
fieldName: 'URL',
|
||||
placeHolder: 'Enter URL',
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
import { IconComponent } from '@/ui/display/icon/types/IconComponent';
|
||||
import { AvatarType } from '@/users/components/Avatar';
|
||||
|
||||
import { FieldMetadata } from './FieldMetadata';
|
||||
@ -13,7 +12,7 @@ export type FieldDefinitionRelationType =
|
||||
export type FieldDefinition<T extends FieldMetadata> = {
|
||||
fieldMetadataId: string;
|
||||
label: string;
|
||||
Icon?: IconComponent;
|
||||
iconName: string;
|
||||
type: FieldType;
|
||||
metadata: T;
|
||||
basePathToShowPage?: string;
|
||||
|
||||
@ -9,7 +9,7 @@ export type FieldType =
|
||||
| 'DOUBLE_TEXT'
|
||||
| 'EMAIL'
|
||||
| 'ENUM'
|
||||
| 'MONEY_AMOUNT_V2'
|
||||
| 'MONEY_AMOUNT_'
|
||||
| 'MONEY_AMOUNT'
|
||||
| 'MONEY'
|
||||
| 'NUMBER'
|
||||
|
||||
@ -2,5 +2,5 @@ import { FieldDefinition } from '../FieldDefinition';
|
||||
import { FieldBooleanMetadata, FieldMetadata } from '../FieldMetadata';
|
||||
|
||||
export const isFieldBoolean = (
|
||||
field: FieldDefinition<FieldMetadata>,
|
||||
field: Pick<FieldDefinition<FieldMetadata>, 'type'>,
|
||||
): field is FieldDefinition<FieldBooleanMetadata> => field.type === 'BOOLEAN';
|
||||
|
||||
@ -2,5 +2,5 @@ import { FieldDefinition } from '../FieldDefinition';
|
||||
import { FieldChipMetadata, FieldMetadata } from '../FieldMetadata';
|
||||
|
||||
export const isFieldChip = (
|
||||
field: FieldDefinition<FieldMetadata>,
|
||||
field: Pick<FieldDefinition<FieldMetadata>, 'type'>,
|
||||
): field is FieldDefinition<FieldChipMetadata> => field.type === 'CHIP';
|
||||
|
||||
@ -2,5 +2,5 @@ import { FieldDefinition } from '../FieldDefinition';
|
||||
import { FieldCurrencyMetadata, FieldMetadata } from '../FieldMetadata';
|
||||
|
||||
export const isFieldCurrency = (
|
||||
field: FieldDefinition<FieldMetadata>,
|
||||
field: Pick<FieldDefinition<FieldMetadata>, 'type'>,
|
||||
): field is FieldDefinition<FieldCurrencyMetadata> => field.type === 'CURRENCY';
|
||||
|
||||
@ -2,5 +2,5 @@ import { FieldDefinition } from '../FieldDefinition';
|
||||
import { FieldDateMetadata, FieldMetadata } from '../FieldMetadata';
|
||||
|
||||
export const isFieldDate = (
|
||||
field: FieldDefinition<FieldMetadata>,
|
||||
field: Pick<FieldDefinition<FieldMetadata>, 'type'>,
|
||||
): field is FieldDefinition<FieldDateMetadata> => field.type === 'DATE';
|
||||
|
||||
@ -2,6 +2,6 @@ import { FieldDefinition } from '../FieldDefinition';
|
||||
import { FieldDoubleTextMetadata, FieldMetadata } from '../FieldMetadata';
|
||||
|
||||
export const isFieldDoubleText = (
|
||||
field: FieldDefinition<FieldMetadata>,
|
||||
field: Pick<FieldDefinition<FieldMetadata>, 'type'>,
|
||||
): field is FieldDefinition<FieldDoubleTextMetadata> =>
|
||||
field.type === 'DOUBLE_TEXT';
|
||||
|
||||
@ -2,6 +2,6 @@ import { FieldDefinition } from '../FieldDefinition';
|
||||
import { FieldDoubleTextChipMetadata, FieldMetadata } from '../FieldMetadata';
|
||||
|
||||
export const isFieldDoubleTextChip = (
|
||||
field: FieldDefinition<FieldMetadata>,
|
||||
field: Pick<FieldDefinition<FieldMetadata>, 'type'>,
|
||||
): field is FieldDefinition<FieldDoubleTextChipMetadata> =>
|
||||
field.type === 'DOUBLE_TEXT_CHIP';
|
||||
|
||||
@ -2,5 +2,5 @@ import { FieldDefinition } from '../FieldDefinition';
|
||||
import { FieldEmailMetadata, FieldMetadata } from '../FieldMetadata';
|
||||
|
||||
export const isFieldEmail = (
|
||||
field: FieldDefinition<FieldMetadata>,
|
||||
field: Pick<FieldDefinition<FieldMetadata>, 'type'>,
|
||||
): field is FieldDefinition<FieldEmailMetadata> => field.type === 'EMAIL';
|
||||
|
||||
@ -2,5 +2,5 @@ import { FieldDefinition } from '../FieldDefinition';
|
||||
import { FieldEnumMetadata, FieldMetadata } from '../FieldMetadata';
|
||||
|
||||
export const isFieldEnum = (
|
||||
field: FieldDefinition<FieldMetadata>,
|
||||
field: Pick<FieldDefinition<FieldMetadata>, 'type'>,
|
||||
): field is FieldDefinition<FieldEnumMetadata> => field.type === 'ENUM';
|
||||
|
||||
@ -2,6 +2,6 @@ import { FieldDefinition } from '../FieldDefinition';
|
||||
import { FieldCurrencyMetadata, FieldMetadata } from '../FieldMetadata';
|
||||
|
||||
export const isFieldFullName = (
|
||||
field: FieldDefinition<FieldMetadata>,
|
||||
field: Pick<FieldDefinition<FieldMetadata>, 'type'>,
|
||||
): field is FieldDefinition<FieldCurrencyMetadata> =>
|
||||
field.type === 'FULL_NAME';
|
||||
|
||||
@ -2,5 +2,5 @@ import { FieldDefinition } from '../FieldDefinition';
|
||||
import { FieldLinkMetadata, FieldMetadata } from '../FieldMetadata';
|
||||
|
||||
export const isFieldLink = (
|
||||
field: FieldDefinition<FieldMetadata>,
|
||||
field: Pick<FieldDefinition<FieldMetadata>, 'type'>,
|
||||
): field is FieldDefinition<FieldLinkMetadata> => field.type === 'LINK';
|
||||
|
||||
@ -2,6 +2,6 @@ import { FieldDefinition } from '../FieldDefinition';
|
||||
import { FieldMetadata, FieldMoneyMetadata } from '../FieldMetadata';
|
||||
|
||||
export const isFieldMoney = (
|
||||
field: FieldDefinition<FieldMetadata>,
|
||||
field: Pick<FieldDefinition<FieldMetadata>, 'type'>,
|
||||
): field is FieldDefinition<FieldMoneyMetadata> =>
|
||||
field.type === 'MONEY_AMOUNT';
|
||||
|
||||
@ -2,5 +2,5 @@ import { FieldDefinition } from '../FieldDefinition';
|
||||
import { FieldMetadata, FieldNumberMetadata } from '../FieldMetadata';
|
||||
|
||||
export const isFieldNumber = (
|
||||
field: FieldDefinition<FieldMetadata>,
|
||||
field: Pick<FieldDefinition<FieldMetadata>, 'type'>,
|
||||
): field is FieldDefinition<FieldNumberMetadata> => field.type === 'NUMBER';
|
||||
|
||||
@ -2,5 +2,5 @@ import { FieldDefinition } from '../FieldDefinition';
|
||||
import { FieldMetadata, FieldPhoneMetadata } from '../FieldMetadata';
|
||||
|
||||
export const isFieldPhone = (
|
||||
field: FieldDefinition<FieldMetadata>,
|
||||
field: Pick<FieldDefinition<FieldMetadata>, 'type'>,
|
||||
): field is FieldDefinition<FieldPhoneMetadata> => field.type === 'PHONE';
|
||||
|
||||
@ -2,6 +2,6 @@ import { FieldDefinition } from '../FieldDefinition';
|
||||
import { FieldMetadata, FieldProbabilityMetadata } from '../FieldMetadata';
|
||||
|
||||
export const isFieldProbability = (
|
||||
field: FieldDefinition<FieldMetadata>,
|
||||
field: Pick<FieldDefinition<FieldMetadata>, 'type'>,
|
||||
): field is FieldDefinition<FieldProbabilityMetadata> =>
|
||||
field.type === 'PROBABILITY';
|
||||
|
||||
@ -2,5 +2,5 @@ import { FieldDefinition } from '../FieldDefinition';
|
||||
import { FieldMetadata, FieldRelationMetadata } from '../FieldMetadata';
|
||||
|
||||
export const isFieldRelation = (
|
||||
field: FieldDefinition<FieldMetadata>,
|
||||
field: Pick<FieldDefinition<FieldMetadata>, 'type'>,
|
||||
): field is FieldDefinition<FieldRelationMetadata> => field.type === 'RELATION';
|
||||
|
||||
@ -2,5 +2,5 @@ import { FieldDefinition } from '../FieldDefinition';
|
||||
import { FieldMetadata, FieldTextMetadata } from '../FieldMetadata';
|
||||
|
||||
export const isFieldText = (
|
||||
field: FieldDefinition<FieldMetadata>,
|
||||
field: Pick<FieldDefinition<FieldMetadata>, 'type'>,
|
||||
): field is FieldDefinition<FieldTextMetadata> => field.type === 'TEXT';
|
||||
|
||||
@ -2,5 +2,5 @@ import { FieldDefinition } from '../FieldDefinition';
|
||||
import { FieldMetadata, FieldURLMetadata } from '../FieldMetadata';
|
||||
|
||||
export const isFieldURL = (
|
||||
field: FieldDefinition<FieldMetadata>,
|
||||
field: Pick<FieldDefinition<FieldMetadata>, 'type'>,
|
||||
): field is FieldDefinition<FieldURLMetadata> => field.type === 'URL';
|
||||
|
||||
@ -2,5 +2,5 @@ import { FieldDefinition } from '../FieldDefinition';
|
||||
import { FieldMetadata, FieldUuidMetadata } from '../FieldMetadata';
|
||||
|
||||
export const isFieldUuid = (
|
||||
field: FieldDefinition<FieldMetadata>,
|
||||
field: Pick<FieldDefinition<FieldMetadata>, 'type'>,
|
||||
): field is FieldDefinition<FieldUuidMetadata> => field.type === 'UUID';
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { useLazyLoadIcons } from '@/ui/input/hooks/useLazyLoadIcons';
|
||||
import { RelationPickerHotkeyScope } from '@/ui/input/relation-picker/types/RelationPickerHotkeyScope';
|
||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||
import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
|
||||
@ -14,6 +15,8 @@ export const ObjectFilterDropdownFilterSelect = () => {
|
||||
availableFilterDefinitions,
|
||||
} = useFilter();
|
||||
|
||||
const { icons } = useLazyLoadIcons();
|
||||
|
||||
const setHotkeyScope = useSetHotkeyScope();
|
||||
|
||||
return (
|
||||
@ -35,7 +38,7 @@ export const ObjectFilterDropdownFilterSelect = () => {
|
||||
|
||||
setObjectFilterDropdownSearchInput('');
|
||||
}}
|
||||
LeftIcon={availableFilterDefinition.Icon}
|
||||
LeftIcon={icons[availableFilterDefinition.iconName]}
|
||||
text={availableFilterDefinition.label}
|
||||
/>
|
||||
))}
|
||||
|
||||
@ -5,7 +5,7 @@ import { FilterType } from './FilterType';
|
||||
export type FilterDefinition = {
|
||||
fieldMetadataId: string;
|
||||
label: string;
|
||||
Icon: IconComponent;
|
||||
iconName: string;
|
||||
type: FilterType;
|
||||
entitySelectComponent?: JSX.Element;
|
||||
selectAllLabel?: string;
|
||||
|
||||
@ -1,111 +0,0 @@
|
||||
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
|
||||
import { QueryMode } from '~/generated/graphql';
|
||||
|
||||
import { Filter } from '../types/Filter';
|
||||
|
||||
type FilterToTurnIntoWhereClause = Omit<Filter, 'definition'> & {
|
||||
definition: {
|
||||
type: Filter['definition']['type'];
|
||||
};
|
||||
};
|
||||
|
||||
export const turnFilterIntoWhereClause = (
|
||||
filter: FilterToTurnIntoWhereClause | undefined,
|
||||
) => {
|
||||
if (!filter) {
|
||||
return {};
|
||||
}
|
||||
switch (filter.operand) {
|
||||
case ViewFilterOperand.IsNotNull:
|
||||
return {
|
||||
[filter.fieldMetadataId]: {
|
||||
not: null,
|
||||
},
|
||||
};
|
||||
default:
|
||||
switch (filter.definition.type) {
|
||||
case 'TEXT':
|
||||
switch (filter.operand) {
|
||||
case ViewFilterOperand.Contains:
|
||||
return {
|
||||
[filter.fieldMetadataId]: {
|
||||
contains: filter.value,
|
||||
mode: QueryMode.Insensitive,
|
||||
},
|
||||
};
|
||||
case ViewFilterOperand.DoesNotContain:
|
||||
return {
|
||||
[filter.fieldMetadataId]: {
|
||||
not: {
|
||||
contains: filter.value,
|
||||
mode: QueryMode.Insensitive,
|
||||
},
|
||||
},
|
||||
};
|
||||
default:
|
||||
throw new Error(
|
||||
`Unknown operand ${filter.operand} for ${filter.definition.type} filter`,
|
||||
);
|
||||
}
|
||||
case 'NUMBER':
|
||||
switch (filter.operand) {
|
||||
case ViewFilterOperand.GreaterThan:
|
||||
return {
|
||||
[filter.fieldMetadataId]: {
|
||||
gte: parseFloat(filter.value),
|
||||
},
|
||||
};
|
||||
case ViewFilterOperand.LessThan:
|
||||
return {
|
||||
[filter.fieldMetadataId]: {
|
||||
lte: parseFloat(filter.value),
|
||||
},
|
||||
};
|
||||
default:
|
||||
throw new Error(
|
||||
`Unknown operand ${filter.operand} for ${filter.definition.type} filter`,
|
||||
);
|
||||
}
|
||||
case 'DATE':
|
||||
switch (filter.operand) {
|
||||
case ViewFilterOperand.GreaterThan:
|
||||
return {
|
||||
[filter.fieldMetadataId]: {
|
||||
gte: filter.value,
|
||||
},
|
||||
};
|
||||
case ViewFilterOperand.LessThan:
|
||||
return {
|
||||
[filter.fieldMetadataId]: {
|
||||
lte: filter.value,
|
||||
},
|
||||
};
|
||||
default:
|
||||
throw new Error(
|
||||
`Unknown operand ${filter.operand} for ${filter.definition.type} filter`,
|
||||
);
|
||||
}
|
||||
case 'ENTITY':
|
||||
switch (filter.operand) {
|
||||
case ViewFilterOperand.Is:
|
||||
return {
|
||||
[filter.fieldMetadataId]: {
|
||||
equals: filter.value,
|
||||
},
|
||||
};
|
||||
case ViewFilterOperand.IsNot:
|
||||
return {
|
||||
[filter.fieldMetadataId]: {
|
||||
not: { equals: filter.value },
|
||||
},
|
||||
};
|
||||
default:
|
||||
throw new Error(
|
||||
`Unknown operand ${filter.operand} for ${filter.definition.type} filter`,
|
||||
);
|
||||
}
|
||||
default:
|
||||
throw new Error('Unknown filter type');
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -1,13 +0,0 @@
|
||||
import { IconComponent } from '@/ui/display/icon/types/IconComponent';
|
||||
import { SortOrder as Order_By } from '~/generated/graphql';
|
||||
|
||||
export type SortType<OrderByTemplate> = {
|
||||
label: string;
|
||||
key: string;
|
||||
Icon?: IconComponent;
|
||||
orderByTemplate?: (order: Order_By) => OrderByTemplate[];
|
||||
};
|
||||
|
||||
export type SelectedSortType<OrderByTemplate> = SortType<OrderByTemplate> & {
|
||||
order: 'asc' | 'desc';
|
||||
};
|
||||
@ -1,16 +0,0 @@
|
||||
import { SortOrder as Order_By } from '~/generated/graphql';
|
||||
|
||||
import { Sort } from '../types/Sort';
|
||||
|
||||
export const reduceSortsToOrderBy = (sorts: Sort[]): any[] =>
|
||||
sorts
|
||||
.map((sort) => {
|
||||
const direction = sort.direction === 'asc' ? Order_By.Asc : Order_By.Desc;
|
||||
|
||||
if (sort.definition.getOrderByTemplate) {
|
||||
return sort.definition.getOrderByTemplate(direction);
|
||||
} else {
|
||||
return [{ [sort.definition.fieldMetadataId]: direction }];
|
||||
}
|
||||
})
|
||||
.flat();
|
||||
@ -1,5 +1,6 @@
|
||||
import { useContext } from 'react';
|
||||
|
||||
import { useLazyLoadIcons } from '@/ui/input/hooks/useLazyLoadIcons';
|
||||
import { RelationPickerHotkeyScope } from '@/ui/input/relation-picker/types/RelationPickerHotkeyScope';
|
||||
|
||||
import { FieldDisplay } from '../../field/components/FieldDisplay';
|
||||
@ -58,6 +59,8 @@ export const RecordInlineCell = () => {
|
||||
closeInlineCell();
|
||||
};
|
||||
|
||||
const { icons } = useLazyLoadIcons();
|
||||
|
||||
return (
|
||||
<RecordInlineCellContainer
|
||||
buttonIcon={buttonIcon}
|
||||
@ -68,7 +71,7 @@ export const RecordInlineCell = () => {
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
IconLabel={fieldDefinition.Icon}
|
||||
IconLabel={icons[fieldDefinition.iconName]}
|
||||
editModeContent={
|
||||
<FieldInput
|
||||
onEnter={handleEnter}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import { useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
import { useLazyLoadIcons } from '@/ui/input/hooks/useLazyLoadIcons';
|
||||
import { FieldMetadata } from '@/ui/object/field/types/FieldMetadata';
|
||||
|
||||
import { ColumnDefinition } from '../types/ColumnDefinition';
|
||||
@ -38,11 +39,14 @@ const StyledText = styled.span`
|
||||
export const ColumnHead = ({ column }: ColumnHeadProps) => {
|
||||
const theme = useTheme();
|
||||
|
||||
const { icons, isLoadingIcons } = useLazyLoadIcons();
|
||||
const Icon = icons[column.iconName];
|
||||
|
||||
return (
|
||||
<>
|
||||
<StyledTitle>
|
||||
<StyledIcon>
|
||||
{column.Icon && <column.Icon size={theme.icon.size.md} />}
|
||||
{!isLoadingIcons && <Icon size={theme.icon.size.md} />}
|
||||
</StyledIcon>
|
||||
<StyledText>{column.label}</StyledText>
|
||||
</StyledTitle>
|
||||
|
||||
@ -1,32 +0,0 @@
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
import { RowIdContext } from '../contexts/RowIdContext';
|
||||
import { RowIndexContext } from '../contexts/RowIndexContext';
|
||||
import { isFetchingRecordTableDataState } from '../states/isFetchingRecordTableDataState';
|
||||
import { tableRowIdsState } from '../states/tableRowIdsState';
|
||||
|
||||
import { RecordTableRow } from './RecordTableRow';
|
||||
|
||||
export const RecordTableBodyV1 = () => {
|
||||
const tableRowIds = useRecoilValue(tableRowIdsState);
|
||||
|
||||
const isFetchingRecordTableData = useRecoilValue(
|
||||
isFetchingRecordTableDataState,
|
||||
);
|
||||
|
||||
if (isFetchingRecordTableData) {
|
||||
return <></>;
|
||||
}
|
||||
|
||||
return (
|
||||
<tbody>
|
||||
{tableRowIds.map((rowId, rowIndex) => (
|
||||
<RowIdContext.Provider value={rowId} key={rowId}>
|
||||
<RowIndexContext.Provider value={rowIndex}>
|
||||
<RecordTableRow key={rowId} rowId={rowId} />
|
||||
</RowIndexContext.Provider>
|
||||
</RowIdContext.Provider>
|
||||
))}
|
||||
</tbody>
|
||||
);
|
||||
};
|
||||
@ -1,73 +0,0 @@
|
||||
import { useEffect } from 'react';
|
||||
import { useSearchParams } from 'react-router-dom';
|
||||
import defaults from 'lodash/defaults';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
import { useOptimisticEffect } from '@/apollo/optimistic-effect/hooks/useOptimisticEffect';
|
||||
import { OptimisticEffectDefinition } from '@/apollo/optimistic-effect/types/OptimisticEffectDefinition';
|
||||
import {
|
||||
SortOrder,
|
||||
useGetCompaniesQuery,
|
||||
useGetPeopleQuery,
|
||||
} from '~/generated/graphql';
|
||||
|
||||
import { FilterDefinition } from '../../object-filter-dropdown/types/FilterDefinition';
|
||||
import { SortDefinition } from '../../object-sort-dropdown/types/SortDefinition';
|
||||
import { useRecordTableScopedStates } from '../hooks/internal/useRecordTableScopedStates';
|
||||
import { useRecordTable } from '../hooks/useRecordTable';
|
||||
|
||||
export const RecordTableEffect = ({
|
||||
useGetRequest,
|
||||
getRequestResultKey,
|
||||
getRequestOptimisticEffectDefinition,
|
||||
|
||||
setActionBarEntries,
|
||||
setContextMenuEntries,
|
||||
}: {
|
||||
useGetRequest: typeof useGetCompaniesQuery | typeof useGetPeopleQuery;
|
||||
getRequestResultKey: string;
|
||||
getRequestOptimisticEffectDefinition: OptimisticEffectDefinition;
|
||||
filterDefinitionArray: FilterDefinition[];
|
||||
sortDefinitionArray: SortDefinition[];
|
||||
setActionBarEntries?: () => void;
|
||||
setContextMenuEntries?: () => void;
|
||||
}) => {
|
||||
const { setRecordTableData } = useRecordTable();
|
||||
const { tableSortsOrderBySelector, tableFiltersWhereSelector } =
|
||||
useRecordTableScopedStates();
|
||||
|
||||
const { registerOptimisticEffect } = useOptimisticEffect({
|
||||
objectNameSingular: 'companyV2',
|
||||
});
|
||||
|
||||
const tableSortsOrderBy = useRecoilValue(tableSortsOrderBySelector);
|
||||
const sortsOrderBy = defaults(tableSortsOrderBy, [
|
||||
{
|
||||
createdAt: SortOrder.Desc,
|
||||
},
|
||||
]);
|
||||
const tableFiltersWhere = useRecoilValue(tableFiltersWhereSelector);
|
||||
|
||||
useGetRequest({
|
||||
variables: { orderBy: sortsOrderBy, where: tableFiltersWhere },
|
||||
onCompleted: (data: any) => {
|
||||
const entities = data[getRequestResultKey] ?? [];
|
||||
|
||||
setRecordTableData(entities);
|
||||
|
||||
registerOptimisticEffect({
|
||||
variables: { orderBy: sortsOrderBy, where: tableFiltersWhere },
|
||||
definition: getRequestOptimisticEffectDefinition,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
const [searchParams] = useSearchParams();
|
||||
|
||||
useEffect(() => {
|
||||
setActionBarEntries?.();
|
||||
setContextMenuEntries?.();
|
||||
}, [searchParams, setActionBarEntries, setContextMenuEntries]);
|
||||
|
||||
return <></>;
|
||||
};
|
||||
@ -2,6 +2,7 @@ import { useCallback } from 'react';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
import { IconPlus } from '@/ui/display/icon';
|
||||
import { useLazyLoadIcons } from '@/ui/input/hooks/useLazyLoadIcons';
|
||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
||||
import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
|
||||
@ -18,6 +19,8 @@ export const RecordTableHeaderPlusButtonContent = () => {
|
||||
|
||||
const hiddenTableColumns = useRecoilValue(hiddenTableColumnsSelector);
|
||||
|
||||
const { icons } = useLazyLoadIcons();
|
||||
|
||||
const { handleColumnVisibilityChange } = useTableColumns();
|
||||
|
||||
const handleAddColumn = useCallback(
|
||||
@ -39,7 +42,7 @@ export const RecordTableHeaderPlusButtonContent = () => {
|
||||
onClick: () => handleAddColumn(column),
|
||||
},
|
||||
]}
|
||||
LeftIcon={column.Icon}
|
||||
LeftIcon={icons[column.iconName]}
|
||||
text={column.label}
|
||||
/>
|
||||
))}
|
||||
|
||||
@ -1,146 +0,0 @@
|
||||
import { useRef } from 'react';
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
import { DragSelect } from '@/ui/utilities/drag-select/components/DragSelect';
|
||||
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
|
||||
import {
|
||||
useListenClickOutside,
|
||||
useListenClickOutsideByClassName,
|
||||
} from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
|
||||
|
||||
import { EntityUpdateMutationContext } from '../contexts/EntityUpdateMutationHookContext';
|
||||
import { useRecordTable } from '../hooks/useRecordTable';
|
||||
import { TableHotkeyScope } from '../types/TableHotkeyScope';
|
||||
|
||||
import { RecordTableBodyV1 } from './RecordTableBodyV1';
|
||||
import { RecordTableHeader } from './RecordTableHeader';
|
||||
|
||||
const StyledTable = styled.table`
|
||||
border-collapse: collapse;
|
||||
|
||||
border-radius: ${({ theme }) => theme.border.radius.sm};
|
||||
border-spacing: 0;
|
||||
margin-left: ${({ theme }) => theme.table.horizontalCellMargin};
|
||||
margin-right: ${({ theme }) => theme.table.horizontalCellMargin};
|
||||
table-layout: fixed;
|
||||
|
||||
width: calc(100% - ${({ theme }) => theme.table.horizontalCellMargin} * 2);
|
||||
|
||||
th {
|
||||
border: 1px solid ${({ theme }) => theme.border.color.light};
|
||||
border-collapse: collapse;
|
||||
color: ${({ theme }) => theme.font.color.tertiary};
|
||||
padding: 0;
|
||||
text-align: left;
|
||||
|
||||
:last-child {
|
||||
border-right-color: transparent;
|
||||
}
|
||||
:first-of-type {
|
||||
border-left-color: transparent;
|
||||
border-right-color: transparent;
|
||||
}
|
||||
:last-of-type {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
td {
|
||||
border: 1px solid ${({ theme }) => theme.border.color.light};
|
||||
border-collapse: collapse;
|
||||
color: ${({ theme }) => theme.font.color.primary};
|
||||
padding: 0;
|
||||
|
||||
text-align: left;
|
||||
|
||||
:last-child {
|
||||
border-right-color: transparent;
|
||||
}
|
||||
:first-of-type {
|
||||
border-left-color: transparent;
|
||||
border-right-color: transparent;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledTableWithHeader = styled.div`
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
const StyledTableContainer = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
position: relative;
|
||||
`;
|
||||
|
||||
type RecordTableV1Props = {
|
||||
updateEntityMutation: (params: any) => void;
|
||||
};
|
||||
|
||||
export const RecordTableV1 = ({ updateEntityMutation }: RecordTableV1Props) => {
|
||||
const tableBodyRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const {
|
||||
leaveTableFocus,
|
||||
setRowSelectedState,
|
||||
resetTableRowSelection,
|
||||
useMapKeyboardToSoftFocus,
|
||||
getIsSomeCellInEditMode,
|
||||
} = useRecordTable();
|
||||
|
||||
useMapKeyboardToSoftFocus();
|
||||
|
||||
useListenClickOutside({
|
||||
refs: [tableBodyRef],
|
||||
callback: () => {
|
||||
leaveTableFocus();
|
||||
},
|
||||
});
|
||||
|
||||
useScopedHotkeys(
|
||||
'escape',
|
||||
() => {
|
||||
resetTableRowSelection();
|
||||
},
|
||||
TableHotkeyScope.Table,
|
||||
);
|
||||
|
||||
useListenClickOutsideByClassName({
|
||||
classNames: ['entity-table-cell'],
|
||||
excludeClassNames: ['action-bar', 'context-menu'],
|
||||
callback: () => {
|
||||
resetTableRowSelection();
|
||||
},
|
||||
});
|
||||
|
||||
const handleMouseLeave = () => {
|
||||
const isSomeCellInEditMode = getIsSomeCellInEditMode();
|
||||
if (isSomeCellInEditMode) return;
|
||||
leaveTableFocus();
|
||||
};
|
||||
|
||||
return (
|
||||
<EntityUpdateMutationContext.Provider value={updateEntityMutation}>
|
||||
<StyledTableWithHeader>
|
||||
<StyledTableContainer>
|
||||
<div ref={tableBodyRef} onMouseLeave={handleMouseLeave}>
|
||||
<StyledTable className="entity-table-cell">
|
||||
<RecordTableHeader />
|
||||
<RecordTableBodyV1 />
|
||||
</StyledTable>
|
||||
<DragSelect
|
||||
dragSelectable={tableBodyRef}
|
||||
onDragSelectionStart={resetTableRowSelection}
|
||||
onDragSelectionChange={setRowSelectedState}
|
||||
/>
|
||||
</div>
|
||||
</StyledTableContainer>
|
||||
</StyledTableWithHeader>
|
||||
</EntityUpdateMutationContext.Provider>
|
||||
);
|
||||
};
|
||||
@ -17,8 +17,6 @@ export const useRecordTableScopedStates = (args?: {
|
||||
availableTableColumnsState,
|
||||
tableFiltersState,
|
||||
tableSortsState,
|
||||
tableSortsOrderBySelector,
|
||||
tableFiltersWhereSelector,
|
||||
tableColumnsState,
|
||||
tableColumnsByKeySelector,
|
||||
hiddenTableColumnsSelector,
|
||||
@ -34,8 +32,6 @@ export const useRecordTableScopedStates = (args?: {
|
||||
availableTableColumnsState,
|
||||
tableFiltersState,
|
||||
tableSortsState,
|
||||
tableSortsOrderBySelector,
|
||||
tableFiltersWhereSelector,
|
||||
tableColumnsState,
|
||||
tableColumnsByKeySelector,
|
||||
hiddenTableColumnsSelector,
|
||||
|
||||
@ -43,6 +43,7 @@ export const useRecordTable = (props?: useRecordTableProps) => {
|
||||
tableFiltersState,
|
||||
tableSortsState,
|
||||
tableColumnsState,
|
||||
onEntityCountChangeState,
|
||||
} = useRecordTableScopedStates({
|
||||
customRecordTableScopeId: scopeId,
|
||||
});
|
||||
@ -51,6 +52,7 @@ export const useRecordTable = (props?: useRecordTableProps) => {
|
||||
availableTableColumnsState,
|
||||
);
|
||||
|
||||
const setOnEntityCountChange = useSetRecoilState(onEntityCountChangeState);
|
||||
const setTableFilters = useSetRecoilState(tableFiltersState);
|
||||
|
||||
const setTableSorts = useSetRecoilState(tableSortsState);
|
||||
@ -299,6 +301,7 @@ export const useRecordTable = (props?: useRecordTableProps) => {
|
||||
setAvailableTableColumns,
|
||||
setTableFilters,
|
||||
setTableSorts,
|
||||
setOnEntityCountChange,
|
||||
setRecordTableData,
|
||||
setTableColumns,
|
||||
leaveTableFocus,
|
||||
|
||||
@ -10,27 +10,21 @@ type RecordTableScopeProps = {
|
||||
children: ReactNode;
|
||||
recordTableScopeId: string;
|
||||
onColumnsChange: (columns: ColumnDefinition<FieldMetadata>[]) => void;
|
||||
onEntityCountChange: (entityCount: number) => void;
|
||||
};
|
||||
|
||||
export const RecordTableScope = ({
|
||||
children,
|
||||
recordTableScopeId,
|
||||
onColumnsChange,
|
||||
onEntityCountChange,
|
||||
}: RecordTableScopeProps) => {
|
||||
return (
|
||||
<RecordTableScopeInternalContext.Provider
|
||||
value={{
|
||||
scopeId: recordTableScopeId,
|
||||
onColumnsChange,
|
||||
onEntityCountChange,
|
||||
}}
|
||||
>
|
||||
<RecordTableScopeInitEffect
|
||||
onColumnsChange={onColumnsChange}
|
||||
onEntityCountChange={onEntityCountChange}
|
||||
/>
|
||||
<RecordTableScopeInitEffect onColumnsChange={onColumnsChange} />
|
||||
{children}
|
||||
</RecordTableScopeInternalContext.Provider>
|
||||
);
|
||||
|
||||
@ -12,23 +12,14 @@ type RecordTableScopeInitEffectProps = {
|
||||
|
||||
export const RecordTableScopeInitEffect = ({
|
||||
onColumnsChange,
|
||||
onEntityCountChange,
|
||||
}: RecordTableScopeInitEffectProps) => {
|
||||
const { onColumnsChangeState, onEntityCountChangeState } =
|
||||
useRecordTableScopedStates();
|
||||
const { onColumnsChangeState } = useRecordTableScopedStates();
|
||||
|
||||
const setOnEntityCountChange = useSetRecoilState(onEntityCountChangeState);
|
||||
const setOnColumnsChange = useSetRecoilState(onColumnsChangeState);
|
||||
|
||||
useEffect(() => {
|
||||
setOnEntityCountChange(() => onEntityCountChange);
|
||||
setOnColumnsChange(() => onColumnsChange);
|
||||
}, [
|
||||
onColumnsChange,
|
||||
onEntityCountChange,
|
||||
setOnColumnsChange,
|
||||
setOnEntityCountChange,
|
||||
]);
|
||||
}, [onColumnsChange, setOnColumnsChange]);
|
||||
|
||||
return <></>;
|
||||
};
|
||||
|
||||
@ -6,7 +6,6 @@ import { ColumnDefinition } from '../../types/ColumnDefinition';
|
||||
|
||||
type RecordTableScopeInternalContextProps = ScopedStateKey & {
|
||||
onColumnsChange: (columns: ColumnDefinition<FieldMetadata>[]) => void;
|
||||
onEntityCountChange: (entityCount: number) => void;
|
||||
};
|
||||
|
||||
export const RecordTableScopeInternalContext =
|
||||
|
||||
@ -1,18 +0,0 @@
|
||||
import { selectorFamily } from 'recoil';
|
||||
|
||||
import { reduceSortsToOrderBy } from '@/ui/object/object-sort-dropdown/utils/helpers';
|
||||
import { SortOrder } from '~/generated/graphql';
|
||||
|
||||
import { tableSortsScopedState } from '../tableSortsScopedState';
|
||||
|
||||
export const tableSortsOrderByScopedSelector = selectorFamily({
|
||||
key: 'tableSortsOrderByScopedSelector',
|
||||
get:
|
||||
(scopeId: string) =>
|
||||
({ get }) => {
|
||||
const orderBy = reduceSortsToOrderBy(
|
||||
get(tableSortsScopedState({ scopeId })),
|
||||
);
|
||||
return orderBy.length ? orderBy : [{ createdAt: SortOrder.Desc }];
|
||||
},
|
||||
});
|
||||
@ -1,15 +0,0 @@
|
||||
import { selectorFamily } from 'recoil';
|
||||
|
||||
import { turnFilterIntoWhereClause } from '../../../object-filter-dropdown/utils/turnFilterIntoWhereClause';
|
||||
import { tableFiltersScopedState } from '../tableFiltersScopedState';
|
||||
|
||||
export const tableFiltersWhereScopedSelector = selectorFamily({
|
||||
key: 'tablefiltersWhereScopedSelector',
|
||||
get:
|
||||
(scopeId: string) =>
|
||||
({ get }) => ({
|
||||
AND: get(tableFiltersScopedState({ scopeId })).map(
|
||||
turnFilterIntoWhereClause,
|
||||
),
|
||||
}),
|
||||
});
|
||||
@ -4,8 +4,6 @@ import { availableTableColumnsScopedState } from '../states/availableTableColumn
|
||||
import { onColumnsChangeScopedState } from '../states/onColumnsChangeScopedState';
|
||||
import { hiddenTableColumnsScopedSelector } from '../states/selectors/hiddenTableColumnsScopedSelector';
|
||||
import { tableColumnsByKeyScopedSelector } from '../states/selectors/tableColumnsByKeyScopedSelector';
|
||||
import { tableFiltersWhereScopedSelector } from '../states/selectors/tablefiltersWhereScopedSelector';
|
||||
import { tableSortsOrderByScopedSelector } from '../states/selectors/tableSortsOrderByScopedSelector';
|
||||
import { visibleTableColumnsScopedSelector } from '../states/selectors/visibleTableColumnsScopedSelector';
|
||||
import { tableColumnsScopedState } from '../states/tableColumnsScopedState';
|
||||
import { tableFiltersScopedState } from '../states/tableFiltersScopedState';
|
||||
@ -33,12 +31,6 @@ export const getRecordTableScopedStates = ({
|
||||
recordTableScopeId,
|
||||
);
|
||||
|
||||
const tableSortsOrderBySelector =
|
||||
tableSortsOrderByScopedSelector(recordTableScopeId);
|
||||
|
||||
const tableFiltersWhereSelector =
|
||||
tableFiltersWhereScopedSelector(recordTableScopeId);
|
||||
|
||||
const tableColumnsState = getScopedState(
|
||||
tableColumnsScopedState,
|
||||
recordTableScopeId,
|
||||
@ -67,8 +59,6 @@ export const getRecordTableScopedStates = ({
|
||||
availableTableColumnsState,
|
||||
tableFiltersState,
|
||||
tableSortsState,
|
||||
tableSortsOrderBySelector,
|
||||
tableFiltersWhereSelector,
|
||||
tableColumnsState,
|
||||
tableColumnsByKeySelector,
|
||||
hiddenTableColumnsSelector,
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import { ThemeProvider } from '@emotion/react';
|
||||
|
||||
import { darkTheme, lightTheme } from '@/ui/theme/constants/theme';
|
||||
import { ColorScheme } from '~/generated/graphql';
|
||||
|
||||
import { useColorScheme } from '../hooks/useColorScheme';
|
||||
import { useSystemColorScheme } from '../hooks/useSystemColorScheme';
|
||||
@ -10,20 +9,14 @@ type AppThemeProviderProps = {
|
||||
children: JSX.Element;
|
||||
};
|
||||
|
||||
const themes = {
|
||||
[ColorScheme.Dark]: darkTheme,
|
||||
[ColorScheme.Light]: lightTheme,
|
||||
};
|
||||
|
||||
export const AppThemeProvider = ({ children }: AppThemeProviderProps) => {
|
||||
const systemColorScheme = useSystemColorScheme();
|
||||
|
||||
const { colorScheme } = useColorScheme();
|
||||
|
||||
const theme =
|
||||
themes[
|
||||
colorScheme === ColorScheme.System ? systemColorScheme : colorScheme
|
||||
];
|
||||
const computedColorScheme =
|
||||
colorScheme === 'System' ? systemColorScheme : colorScheme;
|
||||
const theme = computedColorScheme === 'Dark' ? darkTheme : lightTheme;
|
||||
|
||||
return <ThemeProvider theme={theme}>{children}</ThemeProvider>;
|
||||
};
|
||||
|
||||
@ -12,8 +12,9 @@ export const useColorScheme = () => {
|
||||
|
||||
const { updateOneObject: updateOneWorkspaceMember } =
|
||||
useUpdateOneObjectRecord({
|
||||
objectNameSingular: 'workspaceMemberV2',
|
||||
objectNameSingular: 'workspaceMember',
|
||||
});
|
||||
|
||||
const colorScheme = currentWorkspaceMember?.colorScheme ?? 'System';
|
||||
|
||||
const setColorScheme = useCallback(
|
||||
|
||||
@ -1,21 +1,16 @@
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
|
||||
import { ColorScheme } from '~/generated/graphql';
|
||||
import { ColorScheme } from '@/workspace-member/types/WorkspaceMember';
|
||||
|
||||
type SystemColorScheme = ColorScheme.Light | ColorScheme.Dark;
|
||||
|
||||
export const useSystemColorScheme = (): SystemColorScheme => {
|
||||
export const useSystemColorScheme = (): ColorScheme => {
|
||||
const mediaQuery = useMemo(
|
||||
() => window.matchMedia('(prefers-color-scheme: dark)'),
|
||||
[],
|
||||
);
|
||||
|
||||
const [preferredColorScheme, setPreferredColorScheme] =
|
||||
useState<SystemColorScheme>(
|
||||
!window.matchMedia || !mediaQuery.matches
|
||||
? ColorScheme.Light
|
||||
: ColorScheme.Dark,
|
||||
);
|
||||
const [preferredColorScheme, setPreferredColorScheme] = useState<ColorScheme>(
|
||||
!window.matchMedia || !mediaQuery.matches ? 'Light' : 'Dark',
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (!window.matchMedia) {
|
||||
@ -23,9 +18,7 @@ export const useSystemColorScheme = (): SystemColorScheme => {
|
||||
}
|
||||
|
||||
const handleChange = (event: MediaQueryListEvent): void => {
|
||||
setPreferredColorScheme(
|
||||
event.matches ? ColorScheme.Dark : ColorScheme.Light,
|
||||
);
|
||||
setPreferredColorScheme(event.matches ? 'Dark' : 'Light');
|
||||
};
|
||||
|
||||
mediaQuery.addEventListener('change', handleChange);
|
||||
|
||||
Reference in New Issue
Block a user