diff --git a/front/src/modules/ui/content-display/components/DoubleTextChipDisplay.tsx b/front/src/modules/ui/content-display/components/DoubleTextChipDisplay.tsx
new file mode 100644
index 000000000..70c2c3239
--- /dev/null
+++ b/front/src/modules/ui/content-display/components/DoubleTextChipDisplay.tsx
@@ -0,0 +1,37 @@
+import { CompanyChip } from '@/companies/components/CompanyChip';
+import { PersonChip } from '@/people/components/PersonChip';
+import { Entity } from '@/ui/input/relation-picker/types/EntityTypeForSelect';
+
+type OwnProps = {
+ entityType: Entity;
+ displayName: string;
+ entityId: string | null;
+ avatarUrlValue?: string;
+};
+
+export const DoubleTextChipDisplay = ({
+ entityType,
+ displayName,
+ entityId,
+ avatarUrlValue,
+}: OwnProps) => {
+ switch (entityType) {
+ case Entity.Company: {
+ return ;
+ }
+ case Entity.Person: {
+ return (
+
+ );
+ }
+ default:
+ console.warn(
+ `Unknown relation type: "${entityType}" in DoubleTextChipDisplay`,
+ );
+ return <> >;
+ }
+};
diff --git a/front/src/modules/ui/content-display/components/DoubleTextDisplay.tsx b/front/src/modules/ui/content-display/components/DoubleTextDisplay.tsx
new file mode 100644
index 000000000..d8c2ac0b1
--- /dev/null
+++ b/front/src/modules/ui/content-display/components/DoubleTextDisplay.tsx
@@ -0,0 +1,3 @@
+import { TextDisplay } from './TextDisplay';
+
+export const DoubleTextDisplay = TextDisplay;
diff --git a/front/src/modules/ui/editable-field/components/ProbabilityEditableFieldEditMode.tsx b/front/src/modules/ui/editable-field/components/ProbabilityEditableFieldEditMode.tsx
index 745aecca5..e44874ffb 100644
--- a/front/src/modules/ui/editable-field/components/ProbabilityEditableFieldEditMode.tsx
+++ b/front/src/modules/ui/editable-field/components/ProbabilityEditableFieldEditMode.tsx
@@ -1,8 +1,8 @@
-import { useContext, useState } from 'react';
-import styled from '@emotion/styled';
+import { useContext } from 'react';
import { useRecoilState } from 'recoil';
import { useEditableField } from '@/ui/editable-field/hooks/useEditableField';
+import { ProbabilityInput } from '@/ui/input/components/ProbabilityInput';
import { EditableFieldDefinitionContext } from '../contexts/EditableFieldDefinitionContext';
import { EditableFieldEntityIdContext } from '../contexts/EditableFieldEntityIdContext';
@@ -11,66 +11,7 @@ import { genericEntityFieldFamilySelector } from '../states/selectors/genericEnt
import { FieldDefinition } from '../types/FieldDefinition';
import { FieldProbabilityMetadata } from '../types/FieldMetadata';
-const StyledContainer = styled.div`
- align-items: center;
- display: flex;
- flex-direction: row;
- justify-content: flex-start;
- width: 100%;
-`;
-
-const StyledProgressBarItemContainer = styled.div`
- align-items: center;
- display: flex;
- height: ${({ theme }) => theme.spacing(4)};
- padding-right: ${({ theme }) => theme.spacing(1)};
-`;
-
-const StyledProgressBarItem = styled.div<{
- isFirst: boolean;
- isLast: boolean;
- isActive: boolean;
-}>`
- background-color: ${({ theme, isActive }) =>
- isActive
- ? theme.font.color.secondary
- : theme.background.transparent.medium};
- border-bottom-left-radius: ${({ theme, isFirst }) =>
- isFirst ? theme.border.radius.sm : theme.border.radius.xs};
- border-bottom-right-radius: ${({ theme, isLast }) =>
- isLast ? theme.border.radius.sm : theme.border.radius.xs};
- border-top-left-radius: ${({ theme, isFirst }) =>
- isFirst ? theme.border.radius.sm : theme.border.radius.xs};
- border-top-right-radius: ${({ theme, isLast }) =>
- isLast ? theme.border.radius.sm : theme.border.radius.xs};
- height: ${({ theme }) => theme.spacing(2)};
- width: ${({ theme }) => theme.spacing(3)};
-`;
-
-const StyledProgressBarContainer = styled.div`
- align-items: center;
- display: flex;
- flex-direction: row;
- justify-content: flex-start;
- width: 100%;
-`;
-
-const StyledLabel = styled.div`
- width: ${({ theme }) => theme.spacing(12)};
-`;
-
-const PROBABILITY_VALUES = [
- { label: '0%', value: 0 },
- { label: '25%', value: 25 },
- { label: '50%', value: 50 },
- { label: '75%', value: 75 },
- { label: '100%', value: 100 },
-];
-
export const ProbabilityEditableFieldEditMode = () => {
- const [nextProbabilityIndex, setNextProbabilityIndex] = useState<
- number | null
- >(null);
const currentEditableFieldEntityId = useContext(EditableFieldEntityIdContext);
const currentEditableFieldDefinition = useContext(
EditableFieldDefinitionContext,
@@ -104,37 +45,9 @@ export const ProbabilityEditableFieldEditMode = () => {
};
return (
-
-
- {
- PROBABILITY_VALUES[
- nextProbabilityIndex || nextProbabilityIndex === 0
- ? nextProbabilityIndex
- : probabilityIndex
- ].label
- }
-
-
- {PROBABILITY_VALUES.map((probability, i) => (
- handleChange(probability.value)}
- onMouseEnter={() => setNextProbabilityIndex(i)}
- onMouseLeave={() => setNextProbabilityIndex(null)}
- >
-
-
- ))}
-
-
+
);
};
diff --git a/front/src/modules/ui/input/components/DoubleTextInput.tsx b/front/src/modules/ui/input/components/DoubleTextInput.tsx
new file mode 100644
index 000000000..9a917d65f
--- /dev/null
+++ b/front/src/modules/ui/input/components/DoubleTextInput.tsx
@@ -0,0 +1,65 @@
+import { ChangeEvent, Ref } from 'react';
+import styled from '@emotion/styled';
+
+import { StyledInput } from './TextInput';
+
+type OwnProps = {
+ firstValue: string;
+ secondValue: string;
+ firstValuePlaceholder: string;
+ secondValuePlaceholder: string;
+ onChange: (firstValue: string, secondValue: string) => void;
+ firstValueInputRef?: Ref;
+ secondValueInputRef?: Ref;
+ containerRef?: Ref;
+};
+
+const StyledContainer = styled.div`
+ align-items: center;
+ display: flex;
+ justify-content: space-between;
+
+ input {
+ width: ${({ theme }) => theme.spacing(24)};
+ }
+
+ & > input:last-child {
+ border-left: 1px solid ${({ theme }) => theme.border.color.medium};
+ padding-left: ${({ theme }) => theme.spacing(2)};
+ }
+`;
+
+export const DoubleTextInput = ({
+ firstValue,
+ secondValue,
+ firstValuePlaceholder,
+ secondValuePlaceholder,
+ firstValueInputRef,
+ secondValueInputRef,
+ onChange,
+ containerRef,
+}: OwnProps) => {
+ return (
+
+ ) => {
+ onChange(event.target.value, secondValue);
+ }}
+ />
+ ) => {
+ onChange(firstValue, event.target.value);
+ }}
+ />
+
+ );
+};
diff --git a/front/src/modules/ui/input/components/ProbabilityInput.tsx b/front/src/modules/ui/input/components/ProbabilityInput.tsx
new file mode 100644
index 000000000..999c2b093
--- /dev/null
+++ b/front/src/modules/ui/input/components/ProbabilityInput.tsx
@@ -0,0 +1,104 @@
+import { useState } from 'react';
+import styled from '@emotion/styled';
+
+const StyledContainer = styled.div`
+ align-items: center;
+ display: flex;
+ flex-direction: row;
+ justify-content: flex-start;
+ width: 100%;
+`;
+
+const StyledProgressBarItemContainer = styled.div`
+ align-items: center;
+ display: flex;
+ height: ${({ theme }) => theme.spacing(4)};
+ padding-right: ${({ theme }) => theme.spacing(1)};
+`;
+
+const StyledProgressBarItem = styled.div<{
+ isFirst: boolean;
+ isLast: boolean;
+ isActive: boolean;
+}>`
+ background-color: ${({ theme, isActive }) =>
+ isActive
+ ? theme.font.color.secondary
+ : theme.background.transparent.medium};
+ border-bottom-left-radius: ${({ theme, isFirst }) =>
+ isFirst ? theme.border.radius.sm : theme.border.radius.xs};
+ border-bottom-right-radius: ${({ theme, isLast }) =>
+ isLast ? theme.border.radius.sm : theme.border.radius.xs};
+ border-top-left-radius: ${({ theme, isFirst }) =>
+ isFirst ? theme.border.radius.sm : theme.border.radius.xs};
+ border-top-right-radius: ${({ theme, isLast }) =>
+ isLast ? theme.border.radius.sm : theme.border.radius.xs};
+ height: ${({ theme }) => theme.spacing(2)};
+ width: ${({ theme }) => theme.spacing(3)};
+`;
+
+const StyledProgressBarContainer = styled.div`
+ align-items: center;
+ display: flex;
+ flex-direction: row;
+ justify-content: flex-start;
+ width: 100%;
+`;
+
+const StyledLabel = styled.div`
+ width: ${({ theme }) => theme.spacing(12)};
+`;
+
+const PROBABILITY_VALUES = [
+ { label: '0%', value: 0 },
+ { label: '25%', value: 25 },
+ { label: '50%', value: 50 },
+ { label: '75%', value: 75 },
+ { label: '100%', value: 100 },
+];
+
+type OwnProps = {
+ probabilityIndex: number;
+ onChange: (newValue: number) => void;
+};
+
+export const ProbabilityInput = ({ onChange, probabilityIndex }: OwnProps) => {
+ const [nextProbabilityIndex, setNextProbabilityIndex] = useState<
+ number | null
+ >(null);
+
+ return (
+
+
+ {
+ PROBABILITY_VALUES[
+ nextProbabilityIndex || nextProbabilityIndex === 0
+ ? nextProbabilityIndex
+ : probabilityIndex
+ ].label
+ }
+
+
+ {PROBABILITY_VALUES.map((probability, i) => (
+ onChange(probability.value)}
+ onMouseEnter={() => setNextProbabilityIndex(i)}
+ onMouseLeave={() => setNextProbabilityIndex(null)}
+ >
+
+
+ ))}
+
+
+ );
+};
diff --git a/front/src/modules/ui/table/editable-cell/type/components/DoubleTextCellEdit.tsx b/front/src/modules/ui/table/editable-cell/type/components/DoubleTextCellEdit.tsx
index 38dcf7ea1..6d949dc5b 100644
--- a/front/src/modules/ui/table/editable-cell/type/components/DoubleTextCellEdit.tsx
+++ b/front/src/modules/ui/table/editable-cell/type/components/DoubleTextCellEdit.tsx
@@ -1,15 +1,13 @@
-import { ChangeEvent, useEffect, useRef, useState } from 'react';
-import styled from '@emotion/styled';
+import { useEffect, useRef, useState } from 'react';
import { Key } from 'ts-key-enum';
+import { DoubleTextInput } from '@/ui/input/components/DoubleTextInput';
+import { useEditableCell } from '@/ui/table/editable-cell/hooks/useEditableCell';
+import { useRegisterCloseCellHandlers } from '@/ui/table/editable-cell/hooks/useRegisterCloseCellHandlers';
import { useMoveSoftFocus } from '@/ui/table/hooks/useMoveSoftFocus';
import { TableHotkeyScope } from '@/ui/table/types/TableHotkeyScope';
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
-import { StyledInput } from '../../../../input/components/TextInput';
-import { useEditableCell } from '../../hooks/useEditableCell';
-import { useRegisterCloseCellHandlers } from '../../hooks/useRegisterCloseCellHandlers';
-
type OwnProps = {
firstValue: string;
secondValue: string;
@@ -20,21 +18,6 @@ type OwnProps = {
onCancel?: () => void;
};
-const StyledContainer = styled.div`
- align-items: center;
- display: flex;
- justify-content: space-between;
-
- input {
- width: ${({ theme }) => theme.spacing(24)};
- }
-
- & > input:last-child {
- border-left: 1px solid ${({ theme }) => theme.border.color.medium};
- padding-left: ${({ theme }) => theme.spacing(2)};
- }
-`;
-
export const DoubleTextCellEdit = ({
firstValue,
secondValue,
@@ -142,26 +125,17 @@ export const DoubleTextCellEdit = ({
useRegisterCloseCellHandlers(wrapperRef, handleSubmit, handleCancel);
return (
-
- ) => {
- handleOnChange(event.target.value, secondInternalValue);
- }}
- />
- ) => {
- handleOnChange(firstInternalValue, event.target.value);
- }}
- />
-
+
);
};
diff --git a/front/src/modules/ui/table/editable-cell/type/components/GenericEditableDoubleTextCell.tsx b/front/src/modules/ui/table/editable-cell/type/components/GenericEditableDoubleTextCell.tsx
index cc95bf030..3ce781d39 100644
--- a/front/src/modules/ui/table/editable-cell/type/components/GenericEditableDoubleTextCell.tsx
+++ b/front/src/modules/ui/table/editable-cell/type/components/GenericEditableDoubleTextCell.tsx
@@ -1,6 +1,6 @@
import { useRecoilValue } from 'recoil';
-import { TextDisplay } from '@/ui/content-display/components/TextDisplay';
+import { DoubleTextDisplay } from '@/ui/content-display/components/DoubleTextDisplay';
import type { ViewFieldDoubleTextMetadata } from '@/ui/editable-field/types/ViewField';
import { EditableCell } from '@/ui/table/editable-cell/components/EditableCell';
import { useCurrentRowEntityId } from '@/ui/table/hooks/useCurrentEntityId';
@@ -42,7 +42,7 @@ export const GenericEditableDoubleTextCell = ({
columnDefinition={columnDefinition}
/>
}
- nonEditModeContent={}
+ nonEditModeContent={}
>
);
};
diff --git a/front/src/modules/ui/table/editable-cell/type/components/GenericEditableDoubleTextChipCellDisplayMode.tsx b/front/src/modules/ui/table/editable-cell/type/components/GenericEditableDoubleTextChipCellDisplayMode.tsx
index 3e183270b..9434f0655 100644
--- a/front/src/modules/ui/table/editable-cell/type/components/GenericEditableDoubleTextChipCellDisplayMode.tsx
+++ b/front/src/modules/ui/table/editable-cell/type/components/GenericEditableDoubleTextChipCellDisplayMode.tsx
@@ -1,9 +1,7 @@
import { useRecoilState } from 'recoil';
-import { CompanyChip } from '@/companies/components/CompanyChip';
-import { PersonChip } from '@/people/components/PersonChip';
+import { DoubleTextChipDisplay } from '@/ui/content-display/components/DoubleTextChipDisplay';
import type { ViewFieldDoubleTextChipMetadata } from '@/ui/editable-field/types/ViewField';
-import { Entity } from '@/ui/input/relation-picker/types/EntityTypeForSelect';
import { useCurrentRowEntityId } from '@/ui/table/hooks/useCurrentEntityId';
import { tableEntityFieldFamilySelector } from '@/ui/table/states/selectors/tableEntityFieldFamilySelector';
@@ -41,23 +39,12 @@ export const GenericEditableDoubleTextChipCellDisplayMode = ({
const displayName = [firstValue, secondValue].filter(Boolean).join(' ');
- switch (columnDefinition.metadata.entityType) {
- case Entity.Company: {
- return ;
- }
- case Entity.Person: {
- return (
-
- );
- }
- default:
- console.warn(
- `Unknown relation type: "${columnDefinition.metadata.entityType}" in GenericEditableDoubleTextChipCellDisplayMode`,
- );
- return <> >;
- }
+ return (
+
+ );
};