Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5e29c0ef1d | |||
| 09254580f2 | |||
| ca8fccecff | |||
| bf2c6affbb |
-9
@@ -1,7 +1,6 @@
|
||||
import { defineLogicFunction, RoutePayload } from "twenty-sdk";
|
||||
import { MetadataApiClient } from 'twenty-sdk/generated';
|
||||
|
||||
|
||||
export const OAUTH_TOKEN_PAIRS_PATH = '/oauth/token-pairs';
|
||||
|
||||
type ApolloTokenResponse = {
|
||||
@@ -53,16 +52,8 @@ const handler = async (event: RoutePayload): Promise<any> => {
|
||||
const apolloClientSecret = process.env.APOLLO_CLIENT_SECRET ?? '';
|
||||
const applicationId = process.env.APPLICATION_ID ?? '';
|
||||
|
||||
|
||||
const metadataClient = new MetadataApiClient({});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const tokenPairs = await getAuthenticationTokenPairs(
|
||||
code,
|
||||
apolloClientId,
|
||||
|
||||
@@ -5,8 +5,6 @@ import {
|
||||
} from 'twenty-sdk';
|
||||
import { CoreApiClient } from 'twenty-sdk/generated';
|
||||
|
||||
|
||||
|
||||
type CompanyRecord = {
|
||||
id: string;
|
||||
name?: string;
|
||||
@@ -38,8 +36,6 @@ type ApolloEnrichResponse = {
|
||||
organization?: ApolloOrganization;
|
||||
};
|
||||
|
||||
|
||||
|
||||
const extractDomain = (
|
||||
domainName?: CompanyRecord['domainName'],
|
||||
): string | undefined => {
|
||||
@@ -172,7 +168,6 @@ const updateCompanyInTwenty = async (
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
type CompanyUpdateEvent = DatabaseEventPayload<
|
||||
ObjectRecordUpdateEvent<CompanyRecord>
|
||||
>;
|
||||
@@ -181,7 +176,6 @@ const handler = async (
|
||||
event: CompanyUpdateEvent,
|
||||
): Promise<object | undefined> => {
|
||||
|
||||
|
||||
const { recordId, properties } = event;
|
||||
const { after: companyAfter } = properties;
|
||||
|
||||
@@ -206,7 +200,6 @@ const handler = async (
|
||||
return { skipped: true, reason: 'no enrichment data to apply' };
|
||||
}
|
||||
|
||||
|
||||
await updateCompanyInTwenty(recordId, updateData);
|
||||
|
||||
const result = {
|
||||
|
||||
@@ -219,4 +219,3 @@ main().catch((error) => {
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
|
||||
|
||||
@@ -81,4 +81,3 @@ describe('HistoricalImporter', () => {
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
@@ -158,4 +158,3 @@ export class HistoricalImporter {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +1,2 @@
|
||||
export { Meeting } from './meeting';
|
||||
|
||||
|
||||
|
||||
@@ -330,7 +330,6 @@ export class WebhookHandler {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private async createFailedMeetingRecord(params: unknown, error: string): Promise<void> {
|
||||
try {
|
||||
const twentyApiKey = process.env.TWENTY_API_KEY || '';
|
||||
|
||||
-1
@@ -43,7 +43,6 @@ export default defineContentScript({
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
ctx.addEventListener(window, 'wxt:locationchange', ({newUrl, }) => {
|
||||
const injectedBtn = document.querySelector('[data-id="twenty-btn"]');
|
||||
if(personPattern.includes(newUrl) && !injectedBtn) ui.mount();
|
||||
|
||||
-2
@@ -8,7 +8,6 @@ const StyledButton = styled.button`
|
||||
--text-color: #0a66c2;
|
||||
--bg-color: #00000000;
|
||||
|
||||
|
||||
font-size: ${({theme}) => theme.spacing(3.5)};
|
||||
font-weight: ${({theme}) => theme.font.weight.semiBold};
|
||||
font-family: ${({theme}) => theme.font.family};
|
||||
@@ -26,7 +25,6 @@ const StyledButton = styled.button`
|
||||
transition-timing-function: cubic-bezier(.4, 0, .2, 1);
|
||||
transition-duration: 167ms;
|
||||
|
||||
|
||||
&:hover {
|
||||
background-color: var(--hover-bg-color);
|
||||
color: var(--hover-color);
|
||||
|
||||
+2
-7
@@ -1,6 +1,5 @@
|
||||
import { ThemeProvider } from '@emotion/react';
|
||||
import type React from 'react';
|
||||
import { THEME_DARK, ThemeContextProvider } from 'twenty-ui/theme';
|
||||
import { ColorSchemeProvider } from 'twenty-ui/theme-constants';
|
||||
|
||||
type ThemeContextProps = {
|
||||
children: React.ReactNode;
|
||||
@@ -8,10 +7,6 @@ type ThemeContextProps = {
|
||||
|
||||
export const ThemeContext = ({ children }: ThemeContextProps) => {
|
||||
return (
|
||||
<ThemeProvider theme={THEME_DARK}>
|
||||
<ThemeContextProvider theme={THEME_DARK}>
|
||||
{children}
|
||||
</ThemeContextProvider>
|
||||
</ThemeProvider>
|
||||
<ColorSchemeProvider colorScheme="dark">{children}</ColorSchemeProvider>
|
||||
);
|
||||
};
|
||||
|
||||
+1
-3
@@ -1,5 +1,3 @@
|
||||
import type { ThemeType } from 'twenty-ui/theme';
|
||||
|
||||
declare module '@emotion/react' {
|
||||
export interface Theme extends ThemeType {}
|
||||
export interface Theme {}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,7 @@ import { i18n } from '@lingui/core';
|
||||
import { I18nProvider } from '@lingui/react';
|
||||
import { type Preview } from '@storybook/react-vite';
|
||||
import { initialize, mswLoader } from 'msw-storybook-addon';
|
||||
import { useEffect } from 'react';
|
||||
import { SOURCE_LOCALE } from 'twenty-shared/translations';
|
||||
//import { useDarkMode } from 'storybook-dark-mode';
|
||||
|
||||
// eslint-disable-next-line no-restricted-imports
|
||||
import { RootDecorator } from '../src/testing/decorators/RootDecorator';
|
||||
@@ -13,7 +11,7 @@ import { resetJotaiStore } from '../src/modules/ui/utilities/state/jotai/jotaiSt
|
||||
|
||||
import 'react-loading-skeleton/dist/skeleton.css';
|
||||
import 'twenty-ui/style.css';
|
||||
import { THEME_LIGHT, ThemeContextProvider } from 'twenty-ui/theme';
|
||||
import { ColorSchemeProvider } from 'twenty-ui/theme-constants';
|
||||
// eslint-disable-next-line no-restricted-imports
|
||||
import { messages as enMessages } from '../src/locales/generated/en';
|
||||
|
||||
@@ -60,23 +58,15 @@ initialize({
|
||||
const preview: Preview = {
|
||||
decorators: [
|
||||
(Story) => {
|
||||
// const theme = useDarkMode() ? THEME_DARK : THEME_LIGHT;
|
||||
const theme = THEME_LIGHT;
|
||||
|
||||
useEffect(() => {
|
||||
document.documentElement.className =
|
||||
theme.name === 'dark' ? 'dark' : 'light';
|
||||
}, [theme]);
|
||||
|
||||
return (
|
||||
<I18nProvider i18n={i18n}>
|
||||
<ThemeContextProvider theme={theme}>
|
||||
<ColorSchemeProvider colorScheme="light">
|
||||
<ClickOutsideListenerContext.Provider
|
||||
value={{ excludedClickOutsideId: undefined }}
|
||||
>
|
||||
<Story />
|
||||
</ClickOutsideListenerContext.Provider>
|
||||
</ThemeContextProvider>
|
||||
</ColorSchemeProvider>
|
||||
</I18nProvider>
|
||||
);
|
||||
},
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -143,92 +143,74 @@ export type Mutation = {
|
||||
updateWorkflowVersionStep: WorkflowAction;
|
||||
};
|
||||
|
||||
|
||||
export type MutationActivateWorkflowVersionArgs = {
|
||||
workflowVersionId: Scalars['UUID'];
|
||||
};
|
||||
|
||||
|
||||
export type MutationComputeStepOutputSchemaArgs = {
|
||||
input: ComputeStepOutputSchemaInput;
|
||||
};
|
||||
|
||||
|
||||
export type MutationCreateDraftFromWorkflowVersionArgs = {
|
||||
input: CreateDraftFromWorkflowVersionInput;
|
||||
};
|
||||
|
||||
|
||||
export type MutationCreateWorkflowVersionEdgeArgs = {
|
||||
input: CreateWorkflowVersionEdgeInput;
|
||||
};
|
||||
|
||||
|
||||
export type MutationCreateWorkflowVersionStepArgs = {
|
||||
input: CreateWorkflowVersionStepInput;
|
||||
};
|
||||
|
||||
|
||||
export type MutationDeactivateWorkflowVersionArgs = {
|
||||
workflowVersionId: Scalars['UUID'];
|
||||
};
|
||||
|
||||
|
||||
export type MutationDeleteWorkflowVersionEdgeArgs = {
|
||||
input: CreateWorkflowVersionEdgeInput;
|
||||
};
|
||||
|
||||
|
||||
export type MutationDeleteWorkflowVersionStepArgs = {
|
||||
input: DeleteWorkflowVersionStepInput;
|
||||
};
|
||||
|
||||
|
||||
export type MutationDismissReconnectAccountBannerArgs = {
|
||||
connectedAccountId: Scalars['UUID'];
|
||||
};
|
||||
|
||||
|
||||
export type MutationDuplicateWorkflowArgs = {
|
||||
input: DuplicateWorkflowInput;
|
||||
};
|
||||
|
||||
|
||||
export type MutationDuplicateWorkflowVersionStepArgs = {
|
||||
input: DuplicateWorkflowVersionStepInput;
|
||||
};
|
||||
|
||||
|
||||
export type MutationRunWorkflowVersionArgs = {
|
||||
input: RunWorkflowVersionInput;
|
||||
};
|
||||
|
||||
|
||||
export type MutationStopWorkflowRunArgs = {
|
||||
workflowRunId: Scalars['UUID'];
|
||||
};
|
||||
|
||||
|
||||
export type MutationSubmitFormStepArgs = {
|
||||
input: SubmitFormStepInput;
|
||||
};
|
||||
|
||||
|
||||
export type MutationTestHttpRequestArgs = {
|
||||
input: TestHttpRequestInput;
|
||||
};
|
||||
|
||||
|
||||
export type MutationUpdateWorkflowRunStepArgs = {
|
||||
input: UpdateWorkflowRunStepInput;
|
||||
};
|
||||
|
||||
|
||||
export type MutationUpdateWorkflowVersionPositionsArgs = {
|
||||
input: UpdateWorkflowVersionPositionsInput;
|
||||
};
|
||||
|
||||
|
||||
export type MutationUpdateWorkflowVersionStepArgs = {
|
||||
input: UpdateWorkflowVersionStepInput;
|
||||
};
|
||||
@@ -254,49 +236,42 @@ export type Query = {
|
||||
search: SearchResultConnection;
|
||||
};
|
||||
|
||||
|
||||
export type QueryGetTimelineCalendarEventsFromCompanyIdArgs = {
|
||||
companyId: Scalars['UUID'];
|
||||
page: Scalars['Int'];
|
||||
pageSize: Scalars['Int'];
|
||||
};
|
||||
|
||||
|
||||
export type QueryGetTimelineCalendarEventsFromOpportunityIdArgs = {
|
||||
opportunityId: Scalars['UUID'];
|
||||
page: Scalars['Int'];
|
||||
pageSize: Scalars['Int'];
|
||||
};
|
||||
|
||||
|
||||
export type QueryGetTimelineCalendarEventsFromPersonIdArgs = {
|
||||
page: Scalars['Int'];
|
||||
pageSize: Scalars['Int'];
|
||||
personId: Scalars['UUID'];
|
||||
};
|
||||
|
||||
|
||||
export type QueryGetTimelineThreadsFromCompanyIdArgs = {
|
||||
companyId: Scalars['UUID'];
|
||||
page: Scalars['Int'];
|
||||
pageSize: Scalars['Int'];
|
||||
};
|
||||
|
||||
|
||||
export type QueryGetTimelineThreadsFromOpportunityIdArgs = {
|
||||
opportunityId: Scalars['UUID'];
|
||||
page: Scalars['Int'];
|
||||
pageSize: Scalars['Int'];
|
||||
};
|
||||
|
||||
|
||||
export type QueryGetTimelineThreadsFromPersonIdArgs = {
|
||||
page: Scalars['Int'];
|
||||
pageSize: Scalars['Int'];
|
||||
personId: Scalars['UUID'];
|
||||
};
|
||||
|
||||
|
||||
export type QuerySearchArgs = {
|
||||
after?: InputMaybe<Scalars['String']>;
|
||||
excludedObjectNameSingulars?: InputMaybe<Array<Scalars['String']>>;
|
||||
@@ -579,7 +554,6 @@ export type GetTimelineCalendarEventsFromCompanyIdQueryVariables = Exact<{
|
||||
pageSize: Scalars['Int'];
|
||||
}>;
|
||||
|
||||
|
||||
export type GetTimelineCalendarEventsFromCompanyIdQuery = { __typename?: 'Query', getTimelineCalendarEventsFromCompanyId: { __typename?: 'TimelineCalendarEventsWithTotal', totalNumberOfCalendarEvents: number, timelineCalendarEvents: Array<{ __typename?: 'TimelineCalendarEvent', id: any, title: string, description: string, location: string, startsAt: string, endsAt: string, isFullDay: boolean, visibility: CalendarChannelVisibility, participants: Array<{ __typename?: 'TimelineCalendarEventParticipant', personId?: any | null, workspaceMemberId?: any | null, firstName: string, lastName: string, displayName: string, avatarUrl: string, handle: string }> }> } };
|
||||
|
||||
export type GetTimelineCalendarEventsFromOpportunityIdQueryVariables = Exact<{
|
||||
@@ -588,7 +562,6 @@ export type GetTimelineCalendarEventsFromOpportunityIdQueryVariables = Exact<{
|
||||
pageSize: Scalars['Int'];
|
||||
}>;
|
||||
|
||||
|
||||
export type GetTimelineCalendarEventsFromOpportunityIdQuery = { __typename?: 'Query', getTimelineCalendarEventsFromOpportunityId: { __typename?: 'TimelineCalendarEventsWithTotal', totalNumberOfCalendarEvents: number, timelineCalendarEvents: Array<{ __typename?: 'TimelineCalendarEvent', id: any, title: string, description: string, location: string, startsAt: string, endsAt: string, isFullDay: boolean, visibility: CalendarChannelVisibility, participants: Array<{ __typename?: 'TimelineCalendarEventParticipant', personId?: any | null, workspaceMemberId?: any | null, firstName: string, lastName: string, displayName: string, avatarUrl: string, handle: string }> }> } };
|
||||
|
||||
export type GetTimelineCalendarEventsFromPersonIdQueryVariables = Exact<{
|
||||
@@ -597,7 +570,6 @@ export type GetTimelineCalendarEventsFromPersonIdQueryVariables = Exact<{
|
||||
pageSize: Scalars['Int'];
|
||||
}>;
|
||||
|
||||
|
||||
export type GetTimelineCalendarEventsFromPersonIdQuery = { __typename?: 'Query', getTimelineCalendarEventsFromPersonId: { __typename?: 'TimelineCalendarEventsWithTotal', totalNumberOfCalendarEvents: number, timelineCalendarEvents: Array<{ __typename?: 'TimelineCalendarEvent', id: any, title: string, description: string, location: string, startsAt: string, endsAt: string, isFullDay: boolean, visibility: CalendarChannelVisibility, participants: Array<{ __typename?: 'TimelineCalendarEventParticipant', personId?: any | null, workspaceMemberId?: any | null, firstName: string, lastName: string, displayName: string, avatarUrl: string, handle: string }> }> } };
|
||||
|
||||
export type ParticipantFragmentFragment = { __typename?: 'TimelineThreadParticipant', personId?: any | null, workspaceMemberId?: any | null, firstName: string, lastName: string, displayName: string, avatarUrl: string, handle: string };
|
||||
@@ -612,7 +584,6 @@ export type GetTimelineThreadsFromCompanyIdQueryVariables = Exact<{
|
||||
pageSize: Scalars['Int'];
|
||||
}>;
|
||||
|
||||
|
||||
export type GetTimelineThreadsFromCompanyIdQuery = { __typename?: 'Query', getTimelineThreadsFromCompanyId: { __typename?: 'TimelineThreadsWithTotal', totalNumberOfThreads: number, timelineThreads: Array<{ __typename?: 'TimelineThread', id: any, read: boolean, visibility: MessageChannelVisibility, lastMessageReceivedAt: string, lastMessageBody: string, subject: string, numberOfMessagesInThread: number, participantCount: number, firstParticipant: { __typename?: 'TimelineThreadParticipant', personId?: any | null, workspaceMemberId?: any | null, firstName: string, lastName: string, displayName: string, avatarUrl: string, handle: string }, lastTwoParticipants: Array<{ __typename?: 'TimelineThreadParticipant', personId?: any | null, workspaceMemberId?: any | null, firstName: string, lastName: string, displayName: string, avatarUrl: string, handle: string }> }> } };
|
||||
|
||||
export type GetTimelineThreadsFromOpportunityIdQueryVariables = Exact<{
|
||||
@@ -621,7 +592,6 @@ export type GetTimelineThreadsFromOpportunityIdQueryVariables = Exact<{
|
||||
pageSize: Scalars['Int'];
|
||||
}>;
|
||||
|
||||
|
||||
export type GetTimelineThreadsFromOpportunityIdQuery = { __typename?: 'Query', getTimelineThreadsFromOpportunityId: { __typename?: 'TimelineThreadsWithTotal', totalNumberOfThreads: number, timelineThreads: Array<{ __typename?: 'TimelineThread', id: any, read: boolean, visibility: MessageChannelVisibility, lastMessageReceivedAt: string, lastMessageBody: string, subject: string, numberOfMessagesInThread: number, participantCount: number, firstParticipant: { __typename?: 'TimelineThreadParticipant', personId?: any | null, workspaceMemberId?: any | null, firstName: string, lastName: string, displayName: string, avatarUrl: string, handle: string }, lastTwoParticipants: Array<{ __typename?: 'TimelineThreadParticipant', personId?: any | null, workspaceMemberId?: any | null, firstName: string, lastName: string, displayName: string, avatarUrl: string, handle: string }> }> } };
|
||||
|
||||
export type GetTimelineThreadsFromPersonIdQueryVariables = Exact<{
|
||||
@@ -630,7 +600,6 @@ export type GetTimelineThreadsFromPersonIdQueryVariables = Exact<{
|
||||
pageSize: Scalars['Int'];
|
||||
}>;
|
||||
|
||||
|
||||
export type GetTimelineThreadsFromPersonIdQuery = { __typename?: 'Query', getTimelineThreadsFromPersonId: { __typename?: 'TimelineThreadsWithTotal', totalNumberOfThreads: number, timelineThreads: Array<{ __typename?: 'TimelineThread', id: any, read: boolean, visibility: MessageChannelVisibility, lastMessageReceivedAt: string, lastMessageBody: string, subject: string, numberOfMessagesInThread: number, participantCount: number, firstParticipant: { __typename?: 'TimelineThreadParticipant', personId?: any | null, workspaceMemberId?: any | null, firstName: string, lastName: string, displayName: string, avatarUrl: string, handle: string }, lastTwoParticipants: Array<{ __typename?: 'TimelineThreadParticipant', personId?: any | null, workspaceMemberId?: any | null, firstName: string, lastName: string, displayName: string, avatarUrl: string, handle: string }> }> } };
|
||||
|
||||
export type SearchQueryVariables = Exact<{
|
||||
@@ -642,7 +611,6 @@ export type SearchQueryVariables = Exact<{
|
||||
filter?: InputMaybe<ObjectRecordFilterInput>;
|
||||
}>;
|
||||
|
||||
|
||||
export type SearchQuery = { __typename?: 'Query', search: { __typename?: 'SearchResultConnection', edges: Array<{ __typename?: 'SearchResultEdge', cursor: string, node: { __typename?: 'SearchRecord', recordId: any, objectNameSingular: string, objectLabelSingular: string, label: string, imageUrl?: string | null, tsRankCD: number, tsRank: number } }>, pageInfo: { __typename?: 'SearchResultPageInfo', hasNextPage: boolean, endCursor?: string | null } } };
|
||||
|
||||
export type WorkflowDiffFragmentFragment = { __typename?: 'WorkflowVersionStepChanges', triggerDiff?: any | null, stepsDiff?: any | null };
|
||||
@@ -651,119 +619,102 @@ export type ActivateWorkflowVersionMutationVariables = Exact<{
|
||||
workflowVersionId: Scalars['UUID'];
|
||||
}>;
|
||||
|
||||
|
||||
export type ActivateWorkflowVersionMutation = { __typename?: 'Mutation', activateWorkflowVersion: boolean };
|
||||
|
||||
export type ComputeStepOutputSchemaMutationVariables = Exact<{
|
||||
input: ComputeStepOutputSchemaInput;
|
||||
}>;
|
||||
|
||||
|
||||
export type ComputeStepOutputSchemaMutation = { __typename?: 'Mutation', computeStepOutputSchema: any };
|
||||
|
||||
export type CreateDraftFromWorkflowVersionMutationVariables = Exact<{
|
||||
input: CreateDraftFromWorkflowVersionInput;
|
||||
}>;
|
||||
|
||||
|
||||
export type CreateDraftFromWorkflowVersionMutation = { __typename?: 'Mutation', createDraftFromWorkflowVersion: { __typename?: 'WorkflowVersionDTO', id: any, name: string, status: string, trigger?: any | null, steps?: any | null, createdAt: string, updatedAt: string } };
|
||||
|
||||
export type CreateWorkflowVersionEdgeMutationVariables = Exact<{
|
||||
input: CreateWorkflowVersionEdgeInput;
|
||||
}>;
|
||||
|
||||
|
||||
export type CreateWorkflowVersionEdgeMutation = { __typename?: 'Mutation', createWorkflowVersionEdge: { __typename?: 'WorkflowVersionStepChanges', triggerDiff?: any | null, stepsDiff?: any | null } };
|
||||
|
||||
export type CreateWorkflowVersionStepMutationVariables = Exact<{
|
||||
input: CreateWorkflowVersionStepInput;
|
||||
}>;
|
||||
|
||||
|
||||
export type CreateWorkflowVersionStepMutation = { __typename?: 'Mutation', createWorkflowVersionStep: { __typename?: 'WorkflowVersionStepChanges', triggerDiff?: any | null, stepsDiff?: any | null } };
|
||||
|
||||
export type DeactivateWorkflowVersionMutationVariables = Exact<{
|
||||
workflowVersionId: Scalars['UUID'];
|
||||
}>;
|
||||
|
||||
|
||||
export type DeactivateWorkflowVersionMutation = { __typename?: 'Mutation', deactivateWorkflowVersion: boolean };
|
||||
|
||||
export type DeleteWorkflowVersionEdgeMutationVariables = Exact<{
|
||||
input: CreateWorkflowVersionEdgeInput;
|
||||
}>;
|
||||
|
||||
|
||||
export type DeleteWorkflowVersionEdgeMutation = { __typename?: 'Mutation', deleteWorkflowVersionEdge: { __typename?: 'WorkflowVersionStepChanges', triggerDiff?: any | null, stepsDiff?: any | null } };
|
||||
|
||||
export type DeleteWorkflowVersionStepMutationVariables = Exact<{
|
||||
input: DeleteWorkflowVersionStepInput;
|
||||
}>;
|
||||
|
||||
|
||||
export type DeleteWorkflowVersionStepMutation = { __typename?: 'Mutation', deleteWorkflowVersionStep: { __typename?: 'WorkflowVersionStepChanges', triggerDiff?: any | null, stepsDiff?: any | null } };
|
||||
|
||||
export type DuplicateWorkflowMutationVariables = Exact<{
|
||||
input: DuplicateWorkflowInput;
|
||||
}>;
|
||||
|
||||
|
||||
export type DuplicateWorkflowMutation = { __typename?: 'Mutation', duplicateWorkflow: { __typename?: 'WorkflowVersionDTO', id: any, name: string, status: string, trigger?: any | null, steps?: any | null, createdAt: string, updatedAt: string, workflowId: any } };
|
||||
|
||||
export type DuplicateWorkflowVersionStepMutationVariables = Exact<{
|
||||
input: DuplicateWorkflowVersionStepInput;
|
||||
}>;
|
||||
|
||||
|
||||
export type DuplicateWorkflowVersionStepMutation = { __typename?: 'Mutation', duplicateWorkflowVersionStep: { __typename?: 'WorkflowVersionStepChanges', triggerDiff?: any | null, stepsDiff?: any | null } };
|
||||
|
||||
export type RunWorkflowVersionMutationVariables = Exact<{
|
||||
input: RunWorkflowVersionInput;
|
||||
}>;
|
||||
|
||||
|
||||
export type RunWorkflowVersionMutation = { __typename?: 'Mutation', runWorkflowVersion: { __typename?: 'RunWorkflowVersion', workflowRunId: any } };
|
||||
|
||||
export type StopWorkflowRunMutationVariables = Exact<{
|
||||
workflowRunId: Scalars['UUID'];
|
||||
}>;
|
||||
|
||||
|
||||
export type StopWorkflowRunMutation = { __typename?: 'Mutation', stopWorkflowRun: { __typename: 'WorkflowRun', id: any, status: WorkflowRunStatusEnum } };
|
||||
|
||||
export type UpdateWorkflowRunStepMutationVariables = Exact<{
|
||||
input: UpdateWorkflowRunStepInput;
|
||||
}>;
|
||||
|
||||
|
||||
export type UpdateWorkflowRunStepMutation = { __typename?: 'Mutation', updateWorkflowRunStep: { __typename?: 'WorkflowAction', id: any, name: string, type: WorkflowActionType, settings: any, valid: boolean, nextStepIds?: Array<any> | null, position?: { __typename?: 'WorkflowStepPosition', x: number, y: number } | null } };
|
||||
|
||||
export type UpdateWorkflowVersionStepMutationVariables = Exact<{
|
||||
input: UpdateWorkflowVersionStepInput;
|
||||
}>;
|
||||
|
||||
|
||||
export type UpdateWorkflowVersionStepMutation = { __typename?: 'Mutation', updateWorkflowVersionStep: { __typename?: 'WorkflowAction', id: any, name: string, type: WorkflowActionType, settings: any, valid: boolean, nextStepIds?: Array<any> | null, position?: { __typename?: 'WorkflowStepPosition', x: number, y: number } | null } };
|
||||
|
||||
export type SubmitFormStepMutationVariables = Exact<{
|
||||
input: SubmitFormStepInput;
|
||||
}>;
|
||||
|
||||
|
||||
export type SubmitFormStepMutation = { __typename?: 'Mutation', submitFormStep: boolean };
|
||||
|
||||
export type TestHttpRequestMutationVariables = Exact<{
|
||||
input: TestHttpRequestInput;
|
||||
}>;
|
||||
|
||||
|
||||
export type TestHttpRequestMutation = { __typename?: 'Mutation', testHttpRequest: { __typename?: 'TestHttpRequest', success: boolean, message: string, result?: any | null, error?: any | null, status?: number | null, statusText?: string | null, headers?: any | null } };
|
||||
|
||||
export type UpdateWorkflowVersionPositionsMutationVariables = Exact<{
|
||||
input: UpdateWorkflowVersionPositionsInput;
|
||||
}>;
|
||||
|
||||
|
||||
export type UpdateWorkflowVersionPositionsMutation = { __typename?: 'Mutation', updateWorkflowVersionPositions: boolean };
|
||||
|
||||
export const TimelineCalendarEventParticipantFragmentFragmentDoc = gql`
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { IconCopy, IconExclamationCircle } from 'twenty-ui/display';
|
||||
import { useContext } from 'react';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
|
||||
import {
|
||||
resolveThemeVariableAsNumber,
|
||||
themeCssVariables,
|
||||
} from 'twenty-ui/theme-constants';
|
||||
export const useCopyToClipboard = () => {
|
||||
const { theme } = useContext(ThemeContext);
|
||||
const { enqueueSuccessSnackBar, enqueueErrorSnackBar } = useSnackBar();
|
||||
const { t } = useLingui();
|
||||
|
||||
@@ -28,7 +28,13 @@ export const useCopyToClipboard = () => {
|
||||
enqueueSuccessSnackBar({
|
||||
message: message || t`Copied to clipboard`,
|
||||
options: {
|
||||
icon: <IconCopy size={theme.icon.size.md} />,
|
||||
icon: (
|
||||
<IconCopy
|
||||
size={resolveThemeVariableAsNumber(
|
||||
themeCssVariables.icon.size.md,
|
||||
)}
|
||||
/>
|
||||
),
|
||||
duration: 2000,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -5,9 +5,12 @@ import Skeleton, { SkeletonTheme } from 'react-loading-skeleton';
|
||||
import { SKELETON_LOADER_HEIGHT_SIZES } from '@/activities/components/SkeletonLoader';
|
||||
import { NAVIGATION_DRAWER_CONSTRAINTS } from '@/ui/layout/resizable-panel/constants/NavigationDrawerConstraints';
|
||||
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
|
||||
import { useContext } from 'react';
|
||||
import { ANIMATION, ThemeContext } from 'twenty-ui/theme';
|
||||
import { MainNavigationDrawerItemsSkeletonLoader } from '~/loading/components/MainNavigationDrawerItemsSkeletonLoader';
|
||||
import {
|
||||
resolveThemeVariable,
|
||||
resolveThemeVariableAsNumber,
|
||||
themeCssVariables,
|
||||
} from 'twenty-ui/theme-constants';
|
||||
|
||||
const StyledAnimatedContainer = styled(motion.div)`
|
||||
align-items: center;
|
||||
@@ -48,8 +51,6 @@ const StyledSkeletonTitleContainer = styled.div`
|
||||
|
||||
export const LeftPanelSkeletonLoader = () => {
|
||||
const isMobile = useIsMobile();
|
||||
const { theme } = useContext(ThemeContext);
|
||||
|
||||
return (
|
||||
<StyledAnimatedContainer
|
||||
initial={false}
|
||||
@@ -57,13 +58,21 @@ export const LeftPanelSkeletonLoader = () => {
|
||||
width: isMobile ? 0 : NAVIGATION_DRAWER_CONSTRAINTS.default,
|
||||
opacity: isMobile ? 0 : 1,
|
||||
}}
|
||||
transition={{ duration: ANIMATION.duration.fast }}
|
||||
transition={{
|
||||
duration: resolveThemeVariableAsNumber(
|
||||
themeCssVariables.animation.duration.fast,
|
||||
),
|
||||
}}
|
||||
>
|
||||
<StyledItemsContainer>
|
||||
<StyledSkeletonTitleContainer>
|
||||
<SkeletonTheme
|
||||
baseColor={theme.background.tertiary}
|
||||
highlightColor={theme.background.transparent.lighter}
|
||||
baseColor={resolveThemeVariable(
|
||||
themeCssVariables.background.tertiary,
|
||||
)}
|
||||
highlightColor={resolveThemeVariable(
|
||||
themeCssVariables.background.transparent.lighter,
|
||||
)}
|
||||
borderRadius={4}
|
||||
>
|
||||
<Skeleton
|
||||
|
||||
+8
-6
@@ -1,8 +1,10 @@
|
||||
import { SKELETON_LOADER_HEIGHT_SIZES } from '@/activities/components/SkeletonLoader';
|
||||
import { styled } from '@linaria/react';
|
||||
import { useContext } from 'react';
|
||||
import Skeleton, { SkeletonTheme } from 'react-loading-skeleton';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
import {
|
||||
resolveThemeVariable,
|
||||
themeCssVariables,
|
||||
} from 'twenty-ui/theme-constants';
|
||||
|
||||
const StyledSkeletonContainer = styled.div`
|
||||
align-items: flex-start;
|
||||
@@ -21,13 +23,13 @@ export const MainNavigationDrawerItemsSkeletonLoader = ({
|
||||
title?: boolean;
|
||||
length: number;
|
||||
}) => {
|
||||
const { theme } = useContext(ThemeContext);
|
||||
|
||||
return (
|
||||
<StyledSkeletonContainer>
|
||||
<SkeletonTheme
|
||||
baseColor={theme.background.tertiary}
|
||||
highlightColor={theme.background.transparent.lighter}
|
||||
baseColor={resolveThemeVariable(themeCssVariables.background.tertiary)}
|
||||
highlightColor={resolveThemeVariable(
|
||||
themeCssVariables.background.transparent.lighter,
|
||||
)}
|
||||
borderRadius={4}
|
||||
>
|
||||
{title && (
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { SKELETON_LOADER_HEIGHT_SIZES } from '@/activities/components/SkeletonLoader';
|
||||
import { styled } from '@linaria/react';
|
||||
import { useContext } from 'react';
|
||||
import Skeleton, { SkeletonTheme } from 'react-loading-skeleton';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
import {
|
||||
themeCssVariables,
|
||||
resolveThemeVariable,
|
||||
} from 'twenty-ui/theme-constants';
|
||||
|
||||
const StyledRightDrawerContainer = styled.div`
|
||||
display: flex;
|
||||
@@ -13,12 +14,12 @@ const StyledRightDrawerContainer = styled.div`
|
||||
`;
|
||||
|
||||
const StyledSkeletonLoader = () => {
|
||||
const { theme } = useContext(ThemeContext);
|
||||
|
||||
return (
|
||||
<SkeletonTheme
|
||||
baseColor={theme.background.tertiary}
|
||||
highlightColor={theme.background.transparent.lighter}
|
||||
baseColor={resolveThemeVariable(themeCssVariables.background.tertiary)}
|
||||
highlightColor={resolveThemeVariable(
|
||||
themeCssVariables.background.transparent.lighter,
|
||||
)}
|
||||
borderRadius={4}
|
||||
>
|
||||
<Skeleton height={SKELETON_LOADER_HEIGHT_SIZES.standard.m} width={140} />
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import { SKELETON_LOADER_HEIGHT_SIZES } from '@/activities/components/SkeletonLoader';
|
||||
import { styled } from '@linaria/react';
|
||||
import { useContext } from 'react';
|
||||
import Skeleton, { SkeletonTheme } from 'react-loading-skeleton';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
import { MOBILE_VIEWPORT, themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
import {
|
||||
MOBILE_VIEWPORT,
|
||||
themeCssVariables,
|
||||
resolveThemeVariable,
|
||||
} from 'twenty-ui/theme-constants';
|
||||
|
||||
const StyledMainContainer = styled.div`
|
||||
background: ${themeCssVariables.background.noisy};
|
||||
@@ -50,13 +52,13 @@ const StyledRightPanelFlexContainer = styled.div`
|
||||
`;
|
||||
|
||||
const StyledSkeletonHeaderLoader = () => {
|
||||
const { theme } = useContext(ThemeContext);
|
||||
|
||||
return (
|
||||
<StyledHeaderContainer>
|
||||
<SkeletonTheme
|
||||
baseColor={theme.background.tertiary}
|
||||
highlightColor={theme.background.transparent.lighter}
|
||||
baseColor={resolveThemeVariable(themeCssVariables.background.tertiary)}
|
||||
highlightColor={resolveThemeVariable(
|
||||
themeCssVariables.background.transparent.lighter,
|
||||
)}
|
||||
borderRadius={4}
|
||||
>
|
||||
<Skeleton
|
||||
@@ -69,12 +71,12 @@ const StyledSkeletonHeaderLoader = () => {
|
||||
};
|
||||
|
||||
const StyledSkeletonAddLoader = () => {
|
||||
const { theme } = useContext(ThemeContext);
|
||||
|
||||
return (
|
||||
<SkeletonTheme
|
||||
baseColor={theme.background.tertiary}
|
||||
highlightColor={theme.background.transparent.lighter}
|
||||
baseColor={resolveThemeVariable(themeCssVariables.background.tertiary)}
|
||||
highlightColor={resolveThemeVariable(
|
||||
themeCssVariables.background.transparent.lighter,
|
||||
)}
|
||||
borderRadius={4}
|
||||
>
|
||||
<Skeleton width={132} height={SKELETON_LOADER_HEIGHT_SIZES.standard.s} />
|
||||
|
||||
+7
-4
@@ -3,7 +3,10 @@ import { ActionMenuContext } from '@/action-menu/contexts/ActionMenuContext';
|
||||
import { styled } from '@linaria/react';
|
||||
import { motion } from 'framer-motion';
|
||||
import { useContext } from 'react';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
import {
|
||||
resolveThemeVariable,
|
||||
themeCssVariables,
|
||||
} from 'twenty-ui/theme-constants';
|
||||
|
||||
const StyledActionContainer = styled(motion.div)`
|
||||
display: flex;
|
||||
@@ -13,8 +16,6 @@ const StyledActionContainer = styled(motion.div)`
|
||||
|
||||
export const PageHeaderActionMenuButtons = () => {
|
||||
const { actions } = useContext(ActionMenuContext);
|
||||
const { theme } = useContext(ThemeContext);
|
||||
|
||||
const pinnedActions = actions.filter((entry) => entry.isPinned).toReversed();
|
||||
|
||||
const actionsWithPositionForAnimation = pinnedActions.map(
|
||||
@@ -34,7 +35,9 @@ export const PageHeaderActionMenuButtons = () => {
|
||||
animate={{ width: 'unset', opacity: 1 }}
|
||||
exit={{ width: 0, opacity: 0 }}
|
||||
transition={{
|
||||
duration: theme.animation.duration.instant,
|
||||
duration: resolveThemeVariable(
|
||||
themeCssVariables.animation.duration.instant,
|
||||
),
|
||||
ease: 'easeInOut',
|
||||
}}
|
||||
>
|
||||
|
||||
+44
-36
@@ -1,12 +1,13 @@
|
||||
import { useContext } from 'react';
|
||||
import { styled } from '@linaria/react';
|
||||
import { differenceInSeconds, endOfDay, format } from 'date-fns';
|
||||
|
||||
import { CalendarEventRow } from '@/activities/calendar/components/CalendarEventRow';
|
||||
import { getCalendarEventStartDate } from '@/activities/calendar/utils/getCalendarEventStartDate';
|
||||
import { CardContent } from 'twenty-ui/layout';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
import {
|
||||
themeCssVariables,
|
||||
resolveThemeVariable,
|
||||
} from 'twenty-ui/theme-constants';
|
||||
import { type TimelineCalendarEvent } from '~/generated/graphql';
|
||||
|
||||
type CalendarDayCardContentProps = {
|
||||
@@ -14,12 +15,14 @@ type CalendarDayCardContentProps = {
|
||||
divider?: boolean;
|
||||
};
|
||||
|
||||
const StyledCardContent = styled(CardContent)`
|
||||
align-items: flex-start;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: ${themeCssVariables.spacing[3]};
|
||||
padding: ${themeCssVariables.spacing[2]} ${themeCssVariables.spacing[3]};
|
||||
const StyledCardContentContainer = styled.div`
|
||||
> div {
|
||||
align-items: flex-start;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: ${themeCssVariables.spacing[3]};
|
||||
padding: ${themeCssVariables.spacing[2]} ${themeCssVariables.spacing[3]};
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledDayContainer = styled.div`
|
||||
@@ -45,7 +48,7 @@ const StyledEvents = styled.div`
|
||||
gap: ${themeCssVariables.spacing[3]};
|
||||
`;
|
||||
|
||||
const StyledEventRow = styled(CalendarEventRow)`
|
||||
const StyledEventRowWrapper = styled.div`
|
||||
flex: 1 0 auto;
|
||||
`;
|
||||
|
||||
@@ -53,8 +56,6 @@ export const CalendarDayCardContent = ({
|
||||
calendarEvents,
|
||||
divider,
|
||||
}: CalendarDayCardContentProps) => {
|
||||
const { theme } = useContext(ThemeContext);
|
||||
|
||||
const endOfDayDate = endOfDay(getCalendarEventStartDate(calendarEvents[0]));
|
||||
const dayEndsIn = differenceInSeconds(endOfDayDate, Date.now());
|
||||
|
||||
@@ -63,32 +64,39 @@ export const CalendarDayCardContent = ({
|
||||
|
||||
const upcomingDayCardContentVariants = {
|
||||
upcoming: {},
|
||||
ended: { backgroundColor: theme.background.primary },
|
||||
ended: {
|
||||
backgroundColor: resolveThemeVariable(
|
||||
themeCssVariables.background.primary,
|
||||
),
|
||||
},
|
||||
};
|
||||
|
||||
return (
|
||||
<StyledCardContent
|
||||
divider={divider}
|
||||
initial="upcoming"
|
||||
animate="ended"
|
||||
variants={upcomingDayCardContentVariants}
|
||||
transition={{
|
||||
delay: Math.max(0, dayEndsIn),
|
||||
duration: theme.animation.duration.fast,
|
||||
}}
|
||||
>
|
||||
<StyledDayContainer>
|
||||
<StyledWeekDay>{weekDayLabel}</StyledWeekDay>
|
||||
<StyledMonthDay>{monthDayLabel}</StyledMonthDay>
|
||||
</StyledDayContainer>
|
||||
<StyledEvents>
|
||||
{calendarEvents.map((calendarEvent) => (
|
||||
<StyledEventRow
|
||||
key={calendarEvent.id}
|
||||
calendarEvent={calendarEvent}
|
||||
/>
|
||||
))}
|
||||
</StyledEvents>
|
||||
</StyledCardContent>
|
||||
<StyledCardContentContainer>
|
||||
<CardContent
|
||||
divider={divider}
|
||||
initial="upcoming"
|
||||
animate="ended"
|
||||
variants={upcomingDayCardContentVariants}
|
||||
transition={{
|
||||
delay: Math.max(0, dayEndsIn),
|
||||
duration: resolveThemeVariable(
|
||||
themeCssVariables.animation.duration.fast,
|
||||
),
|
||||
}}
|
||||
>
|
||||
<StyledDayContainer>
|
||||
<StyledWeekDay>{weekDayLabel}</StyledWeekDay>
|
||||
<StyledMonthDay>{monthDayLabel}</StyledMonthDay>
|
||||
</StyledDayContainer>
|
||||
<StyledEvents>
|
||||
{calendarEvents.map((calendarEvent) => (
|
||||
<StyledEventRowWrapper key={calendarEvent.id}>
|
||||
<CalendarEventRow calendarEvent={calendarEvent} />
|
||||
</StyledEventRowWrapper>
|
||||
))}
|
||||
</StyledEvents>
|
||||
</CardContent>
|
||||
</StyledCardContentContainer>
|
||||
);
|
||||
};
|
||||
|
||||
+32
-28
@@ -85,9 +85,11 @@ const StyledFields = styled.div`
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
const StyledPropertyBox = styled(PropertyBox)`
|
||||
height: ${themeCssVariables.spacing[6]};
|
||||
width: 100%;
|
||||
const StyledPropertyBoxWrapper = styled.div`
|
||||
> div {
|
||||
height: ${themeCssVariables.spacing[6]};
|
||||
width: 100%;
|
||||
}
|
||||
`;
|
||||
|
||||
export const CalendarEventDetails = ({
|
||||
@@ -165,35 +167,37 @@ export const CalendarEventDetails = ({
|
||||
});
|
||||
|
||||
return (
|
||||
<StyledPropertyBox key={fieldMetadataItem.id}>
|
||||
<FieldContext.Provider
|
||||
value={{
|
||||
recordId: calendarEvent.id,
|
||||
isLabelIdentifier: false,
|
||||
fieldDefinition: formatFieldMetadataItemAsFieldDefinition({
|
||||
field: fieldMetadataItem,
|
||||
objectMetadataItem,
|
||||
showLabel: true,
|
||||
labelWidth: 72,
|
||||
}),
|
||||
useUpdateRecord: useUpdateOneCalendarEventRecordMutation,
|
||||
maxWidth: 300,
|
||||
isRecordFieldReadOnly: isReadOnly,
|
||||
}}
|
||||
>
|
||||
<RecordFieldComponentInstanceContext.Provider
|
||||
<StyledPropertyBoxWrapper key={fieldMetadataItem.id}>
|
||||
<PropertyBox>
|
||||
<FieldContext.Provider
|
||||
value={{
|
||||
instanceId: getRecordFieldInputInstanceId({
|
||||
recordId: calendarEvent.id,
|
||||
fieldName: fieldMetadataItem.name,
|
||||
prefix: INPUT_ID_PREFIX,
|
||||
recordId: calendarEvent.id,
|
||||
isLabelIdentifier: false,
|
||||
fieldDefinition: formatFieldMetadataItemAsFieldDefinition({
|
||||
field: fieldMetadataItem,
|
||||
objectMetadataItem,
|
||||
showLabel: true,
|
||||
labelWidth: 72,
|
||||
}),
|
||||
useUpdateRecord: useUpdateOneCalendarEventRecordMutation,
|
||||
maxWidth: 300,
|
||||
isRecordFieldReadOnly: isReadOnly,
|
||||
}}
|
||||
>
|
||||
<RecordInlineCell />
|
||||
</RecordFieldComponentInstanceContext.Provider>
|
||||
</FieldContext.Provider>
|
||||
</StyledPropertyBox>
|
||||
<RecordFieldComponentInstanceContext.Provider
|
||||
value={{
|
||||
instanceId: getRecordFieldInputInstanceId({
|
||||
recordId: calendarEvent.id,
|
||||
fieldName: fieldMetadataItem.name,
|
||||
prefix: INPUT_ID_PREFIX,
|
||||
}),
|
||||
}}
|
||||
>
|
||||
<RecordInlineCell />
|
||||
</RecordFieldComponentInstanceContext.Provider>
|
||||
</FieldContext.Provider>
|
||||
</PropertyBox>
|
||||
</StyledPropertyBoxWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
+37
-25
@@ -1,40 +1,52 @@
|
||||
import { useContext } from 'react';
|
||||
import { styled } from '@linaria/react';
|
||||
import { Trans } from '@lingui/react/macro';
|
||||
import { IconLock } from 'twenty-ui/display';
|
||||
import { Card, CardContent } from 'twenty-ui/layout';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
import {
|
||||
resolveThemeVariableAsNumber,
|
||||
themeCssVariables,
|
||||
} from 'twenty-ui/theme-constants';
|
||||
|
||||
const StyledVisibilityCard = styled(Card)`
|
||||
color: ${themeCssVariables.font.color.light};
|
||||
const StyledVisibilityCardContainer = styled.div`
|
||||
flex: 1;
|
||||
border-color: ${themeCssVariables.border.color.light};
|
||||
transition: color ${themeCssVariables.animation.duration.normal} ease;
|
||||
width: 100%;
|
||||
|
||||
> div {
|
||||
color: ${themeCssVariables.font.color.light};
|
||||
border-color: ${themeCssVariables.border.color.light};
|
||||
transition: color ${themeCssVariables.animation.duration.normal} ease;
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledVisibilityCardContent = styled(CardContent)`
|
||||
align-items: center;
|
||||
background-color: ${themeCssVariables.background.transparent.lighter};
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
font-size: ${themeCssVariables.font.size.sm};
|
||||
font-weight: ${themeCssVariables.font.weight.medium};
|
||||
gap: ${themeCssVariables.spacing[1]};
|
||||
height: ${themeCssVariables.spacing[6]};
|
||||
padding: ${themeCssVariables.spacing[0]} ${themeCssVariables.spacing[1]};
|
||||
const StyledVisibilityCardContentContainer = styled.div`
|
||||
> div {
|
||||
align-items: center;
|
||||
background-color: ${themeCssVariables.background.transparent.lighter};
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
font-size: ${themeCssVariables.font.size.sm};
|
||||
font-weight: ${themeCssVariables.font.weight.medium};
|
||||
gap: ${themeCssVariables.spacing[1]};
|
||||
height: ${themeCssVariables.spacing[6]};
|
||||
padding: ${themeCssVariables.spacing[0]} ${themeCssVariables.spacing[1]};
|
||||
}
|
||||
`;
|
||||
|
||||
export const CalendarEventNotSharedContent = () => {
|
||||
const { theme } = useContext(ThemeContext);
|
||||
|
||||
return (
|
||||
<StyledVisibilityCard>
|
||||
<StyledVisibilityCardContent>
|
||||
<IconLock size={theme.icon.size.sm} />
|
||||
<Trans>Not shared</Trans>
|
||||
</StyledVisibilityCardContent>
|
||||
</StyledVisibilityCard>
|
||||
<StyledVisibilityCardContainer>
|
||||
<Card>
|
||||
<StyledVisibilityCardContentContainer>
|
||||
<CardContent>
|
||||
<IconLock
|
||||
size={resolveThemeVariableAsNumber(
|
||||
themeCssVariables.icon.size.sm,
|
||||
)}
|
||||
/>
|
||||
<Trans>Not shared</Trans>
|
||||
</CardContent>
|
||||
</StyledVisibilityCardContentContainer>
|
||||
</Card>
|
||||
</StyledVisibilityCardContainer>
|
||||
);
|
||||
};
|
||||
|
||||
+40
-24
@@ -1,4 +1,4 @@
|
||||
import { useContext, useRef } from 'react';
|
||||
import { useRef } from 'react';
|
||||
import { styled } from '@linaria/react';
|
||||
|
||||
import { type CalendarEventParticipant } from '@/activities/calendar/types/CalendarEventParticipant';
|
||||
@@ -7,8 +7,10 @@ import { ParticipantChip } from '@/activities/components/ParticipantChip';
|
||||
import { EllipsisDisplay } from '@/ui/field/display/components/EllipsisDisplay';
|
||||
import { ExpandableList } from '@/ui/layout/expandable-list/components/ExpandableList';
|
||||
import { IconCheck, IconQuestionMark, IconX } from 'twenty-ui/display';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
import {
|
||||
resolveThemeVariableAsNumber,
|
||||
themeCssVariables,
|
||||
} from 'twenty-ui/theme-constants';
|
||||
|
||||
const StyledInlineCellBaseContainer = styled.div`
|
||||
align-items: center;
|
||||
@@ -22,9 +24,11 @@ const StyledInlineCellBaseContainer = styled.div`
|
||||
user-select: none;
|
||||
`;
|
||||
|
||||
const StyledPropertyBox = styled(PropertyBox)`
|
||||
height: ${themeCssVariables.spacing[6]};
|
||||
width: 100%;
|
||||
const StyledPropertyBoxWrapper = styled.div`
|
||||
> div {
|
||||
height: ${themeCssVariables.spacing[6]};
|
||||
width: 100%;
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledIconContainer = styled.div`
|
||||
@@ -65,12 +69,22 @@ export const CalendarEventParticipantsResponseStatusField = ({
|
||||
responseStatus: 'Yes' | 'Maybe' | 'No';
|
||||
participants: CalendarEventParticipant[];
|
||||
}) => {
|
||||
const { theme } = useContext(ThemeContext);
|
||||
|
||||
const Icon = {
|
||||
Yes: <IconCheck stroke={theme.icon.stroke.sm} />,
|
||||
Maybe: <IconQuestionMark stroke={theme.icon.stroke.sm} />,
|
||||
No: <IconX stroke={theme.icon.stroke.sm} />,
|
||||
Yes: (
|
||||
<IconCheck
|
||||
stroke={resolveThemeVariableAsNumber(themeCssVariables.icon.stroke.sm)}
|
||||
/>
|
||||
),
|
||||
Maybe: (
|
||||
<IconQuestionMark
|
||||
stroke={resolveThemeVariableAsNumber(themeCssVariables.icon.stroke.sm)}
|
||||
/>
|
||||
),
|
||||
No: (
|
||||
<IconX
|
||||
stroke={resolveThemeVariableAsNumber(themeCssVariables.icon.stroke.sm)}
|
||||
/>
|
||||
),
|
||||
}[responseStatus];
|
||||
|
||||
// We want to display external participants first
|
||||
@@ -88,19 +102,21 @@ export const CalendarEventParticipantsResponseStatusField = ({
|
||||
));
|
||||
|
||||
return (
|
||||
<StyledPropertyBox>
|
||||
<StyledInlineCellBaseContainer>
|
||||
<StyledLabelAndIconContainer>
|
||||
<StyledIconContainer>{Icon}</StyledIconContainer>
|
||||
<StyledPropertyBoxWrapper>
|
||||
<PropertyBox>
|
||||
<StyledInlineCellBaseContainer>
|
||||
<StyledLabelAndIconContainer>
|
||||
<StyledIconContainer>{Icon}</StyledIconContainer>
|
||||
|
||||
<StyledLabelContainer width={72}>
|
||||
<EllipsisDisplay>{responseStatus}</EllipsisDisplay>
|
||||
</StyledLabelContainer>
|
||||
</StyledLabelAndIconContainer>
|
||||
<StyledDiv ref={participantsContainerRef}>
|
||||
<ExpandableList isChipCountDisplayed>{styledChips}</ExpandableList>
|
||||
</StyledDiv>
|
||||
</StyledInlineCellBaseContainer>
|
||||
</StyledPropertyBox>
|
||||
<StyledLabelContainer width={72}>
|
||||
<EllipsisDisplay>{responseStatus}</EllipsisDisplay>
|
||||
</StyledLabelContainer>
|
||||
</StyledLabelAndIconContainer>
|
||||
<StyledDiv ref={participantsContainerRef}>
|
||||
<ExpandableList isChipCountDisplayed>{styledChips}</ExpandableList>
|
||||
</StyledDiv>
|
||||
</StyledInlineCellBaseContainer>
|
||||
</PropertyBox>
|
||||
</StyledPropertyBoxWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
+9
-5
@@ -1,4 +1,3 @@
|
||||
import { useContext } from 'react';
|
||||
import { styled } from '@linaria/react';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { format } from 'date-fns';
|
||||
@@ -16,8 +15,10 @@ import { hasCalendarEventEnded } from '@/activities/calendar/utils/hasCalendarEv
|
||||
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
|
||||
import { useOpenCalendarEventInCommandMenu } from '@/command-menu/hooks/useOpenCalendarEventInCommandMenu';
|
||||
import { IconArrowRight } from 'twenty-ui/display';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
import {
|
||||
resolveThemeVariableAsNumber,
|
||||
themeCssVariables,
|
||||
} from 'twenty-ui/theme-constants';
|
||||
|
||||
type CalendarEventRowProps = {
|
||||
calendarEvent: TimelineCalendarEvent;
|
||||
@@ -76,7 +77,6 @@ export const CalendarEventRow = ({
|
||||
calendarEvent,
|
||||
className,
|
||||
}: CalendarEventRowProps) => {
|
||||
const { theme } = useContext(ThemeContext);
|
||||
const currentWorkspaceMember = useAtomStateValue(currentWorkspaceMemberState);
|
||||
const { openCalendarEventInCommandMenu } =
|
||||
useOpenCalendarEventInCommandMenu();
|
||||
@@ -114,7 +114,11 @@ export const CalendarEventRow = ({
|
||||
{startTimeLabel}
|
||||
{endTimeLabel && (
|
||||
<>
|
||||
<IconArrowRight size={theme.icon.size.sm} />
|
||||
<IconArrowRight
|
||||
size={resolveThemeVariableAsNumber(
|
||||
themeCssVariables.icon.size.sm,
|
||||
)}
|
||||
/>
|
||||
{endTimeLabel}
|
||||
</>
|
||||
)}
|
||||
|
||||
@@ -2,16 +2,20 @@ import { styled } from '@linaria/react';
|
||||
import { Card } from 'twenty-ui/layout';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
const StyledList = styled(Card)`
|
||||
& > :not(:last-child) {
|
||||
border-bottom: 1px solid ${themeCssVariables.border.color.light};
|
||||
}
|
||||
|
||||
const StyledListContainer = styled.div`
|
||||
width: calc(100% - 2px);
|
||||
|
||||
overflow: auto;
|
||||
> div {
|
||||
overflow: auto;
|
||||
& > :not(:last-child) {
|
||||
border-bottom: 1px solid ${themeCssVariables.border.color.light};
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const ActivityList = ({ children }: React.PropsWithChildren) => {
|
||||
return <StyledList>{children}</StyledList>;
|
||||
return (
|
||||
<StyledListContainer>
|
||||
<Card>{children}</Card>
|
||||
</StyledListContainer>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -3,15 +3,17 @@ import React from 'react';
|
||||
import { CardContent } from 'twenty-ui/layout';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
const StyledRowContent = styled(CardContent)`
|
||||
align-items: center;
|
||||
display: flex;
|
||||
gap: ${themeCssVariables.spacing[2]};
|
||||
height: ${themeCssVariables.spacing[12]};
|
||||
padding: ${themeCssVariables.spacing[0]} ${themeCssVariables.spacing[4]};
|
||||
const StyledRowContentContainer = styled.div`
|
||||
> div {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
gap: ${themeCssVariables.spacing[2]};
|
||||
height: ${themeCssVariables.spacing[12]};
|
||||
padding: ${themeCssVariables.spacing[0]} ${themeCssVariables.spacing[4]};
|
||||
|
||||
&[data-clickable='false'] {
|
||||
cursor: default;
|
||||
&[data-clickable='false'] {
|
||||
cursor: default;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -30,8 +32,10 @@ export const ActivityRow = ({
|
||||
};
|
||||
|
||||
return (
|
||||
<StyledRowContent onClick={handleClick} isClickable={disabled !== true}>
|
||||
{children}
|
||||
</StyledRowContent>
|
||||
<StyledRowContentContainer>
|
||||
<CardContent onClick={handleClick} isClickable={disabled !== true}>
|
||||
{children}
|
||||
</CardContent>
|
||||
</StyledRowContentContainer>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -7,7 +7,7 @@ import { RecordChip } from '@/object-record/components/RecordChip';
|
||||
import { Avatar } from 'twenty-ui/display';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
const StyledAvatar = styled(Avatar)`
|
||||
const StyledAvatarContainer = styled.div`
|
||||
margin-right: ${themeCssVariables.spacing[1]};
|
||||
`;
|
||||
|
||||
@@ -67,12 +67,14 @@ export const ParticipantChip = ({
|
||||
/>
|
||||
) : (
|
||||
<StyledChip>
|
||||
<StyledAvatar
|
||||
avatarUrl={avatarUrl}
|
||||
type="rounded"
|
||||
placeholder={displayName}
|
||||
size="sm"
|
||||
/>
|
||||
<StyledAvatarContainer>
|
||||
<Avatar
|
||||
avatarUrl={avatarUrl}
|
||||
type="rounded"
|
||||
placeholder={displayName}
|
||||
size="sm"
|
||||
/>
|
||||
</StyledAvatarContainer>
|
||||
<StyledSenderName variant={variant}>{displayName}</StyledSenderName>
|
||||
</StyledChip>
|
||||
)}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { useContext } from 'react';
|
||||
import { styled } from '@linaria/react';
|
||||
import Skeleton, { SkeletonTheme } from 'react-loading-skeleton';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
import {
|
||||
themeCssVariables,
|
||||
resolveThemeVariable,
|
||||
} from 'twenty-ui/theme-constants';
|
||||
|
||||
const StyledSkeletonContainer = styled.div`
|
||||
align-items: center;
|
||||
@@ -43,12 +44,12 @@ export const SKELETON_LOADER_HEIGHT_SIZES = {
|
||||
};
|
||||
|
||||
const SkeletonColumnLoader = ({ height }: { height: number }) => {
|
||||
const { theme } = useContext(ThemeContext);
|
||||
|
||||
return (
|
||||
<SkeletonTheme
|
||||
baseColor={theme.background.tertiary}
|
||||
highlightColor={theme.background.transparent.lighter}
|
||||
baseColor={resolveThemeVariable(themeCssVariables.background.tertiary)}
|
||||
highlightColor={resolveThemeVariable(
|
||||
themeCssVariables.background.transparent.lighter,
|
||||
)}
|
||||
borderRadius={80}
|
||||
>
|
||||
<Skeleton width={24} height={height} />
|
||||
@@ -61,15 +62,16 @@ export const SkeletonLoader = ({
|
||||
}: {
|
||||
withSubSections?: boolean;
|
||||
}) => {
|
||||
const { theme } = useContext(ThemeContext);
|
||||
const skeletonItems = Array.from({ length: 3 }).map((_, index) => ({
|
||||
id: `skeleton-item-${index}`,
|
||||
}));
|
||||
|
||||
return (
|
||||
<SkeletonTheme
|
||||
baseColor={theme.background.tertiary}
|
||||
highlightColor={theme.background.transparent.lighter}
|
||||
baseColor={resolveThemeVariable(themeCssVariables.background.tertiary)}
|
||||
highlightColor={resolveThemeVariable(
|
||||
themeCssVariables.background.transparent.lighter,
|
||||
)}
|
||||
borderRadius={4}
|
||||
>
|
||||
<StyledSkeletonContainer>
|
||||
|
||||
+7
-5
@@ -1,9 +1,10 @@
|
||||
import { useContext } from 'react';
|
||||
import { styled } from '@linaria/react';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { AppTooltip, IconLock, TooltipDelay } from 'twenty-ui/display';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
import {
|
||||
resolveThemeVariableAsNumber,
|
||||
themeCssVariables,
|
||||
} from 'twenty-ui/theme-constants';
|
||||
import { MessageChannelVisibility } from '~/generated/graphql';
|
||||
|
||||
const StyledContainer = styled.div<{ isCompact?: boolean }>`
|
||||
@@ -35,14 +36,15 @@ export const EmailThreadNotShared = ({
|
||||
visibility,
|
||||
}: EmailThreadNotSharedProps) => {
|
||||
const { t } = useLingui();
|
||||
const { theme } = useContext(ThemeContext);
|
||||
const containerId = 'email-thread-not-shared';
|
||||
const isCompact = visibility === MessageChannelVisibility.SUBJECT;
|
||||
|
||||
return (
|
||||
<>
|
||||
<StyledContainer id={containerId} isCompact={isCompact}>
|
||||
<IconLock size={theme.icon.size.sm} />
|
||||
<IconLock
|
||||
size={resolveThemeVariableAsNumber(themeCssVariables.icon.size.sm)}
|
||||
/>
|
||||
{t`Not shared`}
|
||||
</StyledContainer>
|
||||
{visibility === MessageChannelVisibility.SUBJECT && (
|
||||
|
||||
+12
-7
@@ -1,12 +1,13 @@
|
||||
import { useContext } from 'react';
|
||||
import { styled } from '@linaria/react';
|
||||
|
||||
import { ActivityRow } from '@/activities/components/ActivityRow';
|
||||
import { EmailThreadNotShared } from '@/activities/emails/components/EmailThreadNotShared';
|
||||
import { useOpenEmailThreadInCommandMenu } from '@/command-menu/hooks/useOpenEmailThreadInCommandMenu';
|
||||
import { Avatar } from 'twenty-ui/display';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
import {
|
||||
themeCssVariables,
|
||||
resolveThemeVariable,
|
||||
} from 'twenty-ui/theme-constants';
|
||||
import {
|
||||
MessageChannelVisibility,
|
||||
type TimelineThread,
|
||||
@@ -107,8 +108,6 @@ export const EmailThreadPreview = ({ thread }: EmailThreadPreviewProps) => {
|
||||
};
|
||||
|
||||
const isDisabled = visibility !== MessageChannelVisibility.SHARE_EVERYTHING;
|
||||
const { theme } = useContext(ThemeContext);
|
||||
|
||||
return (
|
||||
<ActivityRow onClick={handleThreadClick} disabled={isDisabled}>
|
||||
<StyledHeading unread={!thread.read}>
|
||||
@@ -141,9 +140,15 @@ export const EmailThreadPreview = ({ thread }: EmailThreadPreviewProps) => {
|
||||
avatarUrl={finalAvatarUrl}
|
||||
placeholder={finalDisplayedName}
|
||||
type="rounded"
|
||||
color={isCountIcon ? theme.grayScale.gray11 : undefined}
|
||||
color={
|
||||
isCountIcon
|
||||
? resolveThemeVariable(themeCssVariables.grayScale.gray11)
|
||||
: undefined
|
||||
}
|
||||
backgroundColor={
|
||||
isCountIcon ? theme.grayScale.gray2 : undefined
|
||||
isCountIcon
|
||||
? resolveThemeVariable(themeCssVariables.grayScale.gray2)
|
||||
: undefined
|
||||
}
|
||||
/>
|
||||
</StyledAvatarWrapper>
|
||||
|
||||
@@ -38,9 +38,11 @@ const StyledContainer = styled.div`
|
||||
overflow: auto;
|
||||
`;
|
||||
|
||||
const StyledH1Title = styled(H1Title)`
|
||||
display: flex;
|
||||
gap: ${themeCssVariables.spacing[2]};
|
||||
const StyledH1TitleWrapper = styled.div`
|
||||
> div {
|
||||
display: flex;
|
||||
gap: ${themeCssVariables.spacing[2]};
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledEmailCount = styled.span`
|
||||
@@ -107,15 +109,17 @@ export const EmailsCard = () => {
|
||||
return (
|
||||
<StyledContainer>
|
||||
<Section>
|
||||
<StyledH1Title
|
||||
title={
|
||||
<>
|
||||
<Trans>Inbox</Trans>{' '}
|
||||
<StyledEmailCount>{totalNumberOfThreads}</StyledEmailCount>
|
||||
</>
|
||||
}
|
||||
fontColor={H1TitleFontColor.Primary}
|
||||
/>
|
||||
<StyledH1TitleWrapper>
|
||||
<H1Title
|
||||
title={
|
||||
<>
|
||||
<Trans>Inbox</Trans>{' '}
|
||||
<StyledEmailCount>{totalNumberOfThreads}</StyledEmailCount>
|
||||
</>
|
||||
}
|
||||
fontColor={H1TitleFontColor.Primary}
|
||||
/>
|
||||
</StyledH1TitleWrapper>
|
||||
{!firstQueryLoading && (
|
||||
<ActivityList>
|
||||
{timelineThreads?.map((thread: TimelineThread) => (
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
import { getFileCategoryFromExtension } from '@/object-record/record-field/ui/utils/getFileCategoryFromExtension';
|
||||
import { SettingsTextInput } from '@/ui/input/components/SettingsTextInput';
|
||||
import { styled } from '@linaria/react';
|
||||
import { useContext, useState } from 'react';
|
||||
import { useState } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { type AttachmentWithFile } from '@/activities/files/utils/filterAttachmentsWithFile';
|
||||
@@ -18,8 +18,10 @@ import { FileIcon } from '@/file/components/FileIcon';
|
||||
import { useHasPermissionFlag } from '@/settings/roles/hooks/useHasPermissionFlag';
|
||||
import { CoreObjectNameSingular } from 'twenty-shared/types';
|
||||
import { IconCalendar, OverflowingTextWithTooltip } from 'twenty-ui/display';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
import {
|
||||
resolveThemeVariableAsNumber,
|
||||
themeCssVariables,
|
||||
} from 'twenty-ui/theme-constants';
|
||||
import { isNavigationModifierPressed } from 'twenty-ui/utilities';
|
||||
import { PermissionFlagType } from '~/generated-metadata/graphql';
|
||||
import { formatToHumanReadableDate } from '~/utils/date-utils';
|
||||
@@ -81,7 +83,6 @@ export const AttachmentRow = ({
|
||||
attachment,
|
||||
onPreview,
|
||||
}: AttachmentRowProps) => {
|
||||
const { theme } = useContext(ThemeContext);
|
||||
const [isEditing, setIsEditing] = useState(false);
|
||||
|
||||
const hasDownloadPermission = useHasPermissionFlag(
|
||||
@@ -200,7 +201,11 @@ export const AttachmentRow = ({
|
||||
</StyledLeftContent>
|
||||
<StyledRightContent>
|
||||
<StyledCalendarIconContainer>
|
||||
<IconCalendar size={theme.icon.size.md} />
|
||||
<IconCalendar
|
||||
size={resolveThemeVariableAsNumber(
|
||||
themeCssVariables.icon.size.md,
|
||||
)}
|
||||
/>
|
||||
</StyledCalendarIconContainer>
|
||||
{formatToHumanReadableDate(attachment.createdAt)}
|
||||
<AttachmentDropdown
|
||||
|
||||
@@ -9,12 +9,14 @@ import DocViewer, { DocViewerRenderers } from '@cyntler/react-doc-viewer';
|
||||
import '@cyntler/react-doc-viewer/dist/index.css';
|
||||
import { styled } from '@linaria/react';
|
||||
import { Trans, useLingui } from '@lingui/react/macro';
|
||||
import { useContext, useEffect, useState } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { IconDownload } from 'twenty-ui/display';
|
||||
import { Button } from 'twenty-ui/input';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
import {
|
||||
themeCssVariables,
|
||||
resolveThemeVariable,
|
||||
} from 'twenty-ui/theme-constants';
|
||||
import { getFileNameAndExtension } from '~/utils/file/getFileNameAndExtension';
|
||||
|
||||
const MS_OFFICE_EXTENSIONS = [
|
||||
@@ -201,7 +203,6 @@ export const DocumentViewer = ({
|
||||
documentExtension,
|
||||
}: DocumentViewerProps) => {
|
||||
const { t } = useLingui();
|
||||
const { theme } = useContext(ThemeContext);
|
||||
const [csvPreview, setCsvPreview] = useState<CsvPreviewData | undefined>(
|
||||
undefined,
|
||||
);
|
||||
@@ -319,8 +320,10 @@ export const DocumentViewer = ({
|
||||
pluginRenderers={DocViewerRenderers}
|
||||
style={{
|
||||
height: '100%',
|
||||
color: theme.font.color.primary,
|
||||
backgroundColor: theme.background.primary,
|
||||
color: resolveThemeVariable(themeCssVariables.font.color.primary),
|
||||
backgroundColor: resolveThemeVariable(
|
||||
themeCssVariables.background.primary,
|
||||
),
|
||||
}}
|
||||
config={{
|
||||
header: {
|
||||
@@ -335,12 +338,20 @@ export const DocumentViewer = ({
|
||||
},
|
||||
}}
|
||||
theme={{
|
||||
primary: theme.background.primary,
|
||||
secondary: theme.background.secondary,
|
||||
tertiary: theme.background.tertiary,
|
||||
textPrimary: theme.font.color.primary,
|
||||
textSecondary: theme.font.color.secondary,
|
||||
textTertiary: theme.font.color.tertiary,
|
||||
primary: resolveThemeVariable(themeCssVariables.background.primary),
|
||||
secondary: resolveThemeVariable(
|
||||
themeCssVariables.background.secondary,
|
||||
),
|
||||
tertiary: resolveThemeVariable(themeCssVariables.background.tertiary),
|
||||
textPrimary: resolveThemeVariable(
|
||||
themeCssVariables.font.color.primary,
|
||||
),
|
||||
textSecondary: resolveThemeVariable(
|
||||
themeCssVariables.font.color.secondary,
|
||||
),
|
||||
textTertiary: resolveThemeVariable(
|
||||
themeCssVariables.font.color.tertiary,
|
||||
),
|
||||
disableThemeScrollbar: true,
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import { useContext } from 'react';
|
||||
import { styled } from '@linaria/react';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { useDropzone } from 'react-dropzone';
|
||||
|
||||
import { useSpreadsheetImportInternal } from '@/spreadsheet-import/hooks/useSpreadsheetImportInternal';
|
||||
import { IconUpload } from 'twenty-ui/display';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
import {
|
||||
resolveThemeVariableAsNumber,
|
||||
themeCssVariables,
|
||||
} from 'twenty-ui/theme-constants';
|
||||
|
||||
const StyledContainer = styled.div`
|
||||
align-items: center;
|
||||
@@ -35,9 +36,10 @@ const StyledUploadDragSubTitle = styled.div`
|
||||
line-height: ${themeCssVariables.text.lineHeight.md};
|
||||
`;
|
||||
|
||||
const StyledUploadIcon = styled(IconUpload)`
|
||||
const StyledUploadIconContainer = styled.span`
|
||||
color: ${themeCssVariables.font.color.tertiary};
|
||||
margin-bottom: ${themeCssVariables.spacing[3]};
|
||||
display: flex;
|
||||
`;
|
||||
|
||||
type DropZoneProps = {
|
||||
@@ -50,7 +52,6 @@ export const DropZone = ({
|
||||
onUploadFiles,
|
||||
}: DropZoneProps) => {
|
||||
const { t } = useLingui();
|
||||
const { theme } = useContext(ThemeContext);
|
||||
const { maxFileSize } = useSpreadsheetImportInternal();
|
||||
|
||||
const { getRootProps, getInputProps, isDragActive } = useDropzone({
|
||||
@@ -84,10 +85,16 @@ export const DropZone = ({
|
||||
// eslint-disable-next-line react/jsx-props-no-spreading
|
||||
{...getInputProps()}
|
||||
/>
|
||||
<StyledUploadIcon
|
||||
stroke={theme.icon.stroke.sm}
|
||||
size={theme.icon.size.lg}
|
||||
/>
|
||||
<StyledUploadIconContainer>
|
||||
<IconUpload
|
||||
stroke={resolveThemeVariableAsNumber(
|
||||
themeCssVariables.icon.stroke.sm,
|
||||
)}
|
||||
size={resolveThemeVariableAsNumber(
|
||||
themeCssVariables.icon.size.lg,
|
||||
)}
|
||||
/>
|
||||
</StyledUploadIconContainer>
|
||||
<StyledUploadDragTitle>{t`Upload files`}</StyledUploadDragTitle>
|
||||
<StyledUploadDragSubTitle>
|
||||
{t`Drag and Drop Here`}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { useContext } from 'react';
|
||||
import { styled } from '@linaria/react';
|
||||
import { t } from '@lingui/core/macro';
|
||||
|
||||
@@ -16,8 +15,10 @@ import { RecordFieldsScopeContextProvider } from '@/object-record/record-field-l
|
||||
import { FieldContextProvider } from '@/object-record/record-field/ui/components/FieldContextProvider';
|
||||
import { IconCalendar, OverflowingTextWithTooltip } from 'twenty-ui/display';
|
||||
import { Checkbox, CheckboxShape } from 'twenty-ui/input';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
import {
|
||||
resolveThemeVariableAsNumber,
|
||||
themeCssVariables,
|
||||
} from 'twenty-ui/theme-constants';
|
||||
import { useCompleteTask } from '@/activities/tasks/hooks/useCompleteTask';
|
||||
|
||||
const StyledTaskBody = styled.div`
|
||||
@@ -86,7 +87,6 @@ const StyledCheckboxContainer = styled.div`
|
||||
`;
|
||||
|
||||
export const TaskRow = ({ task }: { task: Task }) => {
|
||||
const { theme } = useContext(ThemeContext);
|
||||
const { openRecordInCommandMenu } = useOpenRecordInCommandMenu();
|
||||
|
||||
const body = getActivitySummary(task?.bodyV2?.blocknote ?? null);
|
||||
@@ -131,7 +131,11 @@ export const TaskRow = ({ task }: { task: Task }) => {
|
||||
<StyledDueDate
|
||||
isPast={hasDatePassed(task.dueAt) && task.status === 'TODO'}
|
||||
>
|
||||
<IconCalendar size={theme.icon.size.md} />
|
||||
<IconCalendar
|
||||
size={resolveThemeVariableAsNumber(
|
||||
themeCssVariables.icon.size.md,
|
||||
)}
|
||||
/>
|
||||
{beautifyExactDate(task.dueAt)}
|
||||
</StyledDueDate>
|
||||
)}
|
||||
|
||||
+12
-10
@@ -38,9 +38,7 @@ const StyledMainContainer = styled.div`
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledRightDrawerAnimatedPlaceholderEmptyContainer = styled(
|
||||
AnimatedPlaceholderEmptyContainer,
|
||||
)`
|
||||
const StyledRightDrawerEmptyContainerWrapper = styled.div`
|
||||
height: auto;
|
||||
padding-top: ${themeCssVariables.spacing[8]};
|
||||
`;
|
||||
@@ -59,12 +57,8 @@ export const TimelineCard = () => {
|
||||
}
|
||||
|
||||
if (isTimelineActivitiesEmpty) {
|
||||
const EmptyContainer = isInRightDrawer
|
||||
? StyledRightDrawerAnimatedPlaceholderEmptyContainer
|
||||
: AnimatedPlaceholderEmptyContainer;
|
||||
|
||||
return (
|
||||
<EmptyContainer
|
||||
const content = (
|
||||
<AnimatedPlaceholderEmptyContainer
|
||||
// eslint-disable-next-line react/jsx-props-no-spreading
|
||||
{...EMPTY_PLACEHOLDER_TRANSITION_PROPS}
|
||||
>
|
||||
@@ -77,7 +71,15 @@ export const TimelineCard = () => {
|
||||
{t`There is no activity associated with this record.`}
|
||||
</AnimatedPlaceholderEmptySubTitle>
|
||||
</AnimatedPlaceholderEmptyTextContainer>
|
||||
</EmptyContainer>
|
||||
</AnimatedPlaceholderEmptyContainer>
|
||||
);
|
||||
|
||||
return isInRightDrawer ? (
|
||||
<StyledRightDrawerEmptyContainerWrapper>
|
||||
{content}
|
||||
</StyledRightDrawerEmptyContainerWrapper>
|
||||
) : (
|
||||
content
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
+14
-14
@@ -20,27 +20,27 @@ const StyledCardContainer = styled.div`
|
||||
@media (max-width: ${MOBILE_VIEWPORT}px) {
|
||||
width: 300px;
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledCard = styled(Card)`
|
||||
background: ${themeCssVariables.background.secondary};
|
||||
border: 1px solid ${themeCssVariables.border.color.medium};
|
||||
border-radius: ${themeCssVariables.border.radius.md};
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
padding: ${themeCssVariables.spacing[2]};
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: ${themeCssVariables.spacing[2]};
|
||||
justify-content: center;
|
||||
align-self: stretch;
|
||||
> div {
|
||||
background: ${themeCssVariables.background.secondary};
|
||||
border: 1px solid ${themeCssVariables.border.color.medium};
|
||||
border-radius: ${themeCssVariables.border.radius.md};
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
padding: ${themeCssVariables.spacing[2]};
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: ${themeCssVariables.spacing[2]};
|
||||
justify-content: center;
|
||||
align-self: stretch;
|
||||
}
|
||||
`;
|
||||
|
||||
export const EventCard = ({ children, isOpen }: EventCardProps) => {
|
||||
return (
|
||||
isOpen && (
|
||||
<StyledCardContainer>
|
||||
<StyledCard fullWidth>{children}</StyledCard>
|
||||
<Card fullWidth>{children}</Card>
|
||||
</StyledCardContainer>
|
||||
)
|
||||
);
|
||||
|
||||
+5
-1
@@ -26,8 +26,12 @@ export const StyledEventRowItemColumn = styled.div`
|
||||
gap: ${themeCssVariables.spacing[1]};
|
||||
`;
|
||||
|
||||
export const StyledEventRowItemAction = styled(StyledEventRowItemColumn)`
|
||||
export const StyledEventRowItemAction = styled.div`
|
||||
align-items: center;
|
||||
color: ${themeCssVariables.font.color.secondary};
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: ${themeCssVariables.spacing[1]};
|
||||
`;
|
||||
|
||||
export const EventRowDynamicComponent = ({
|
||||
|
||||
+20
-17
@@ -13,11 +13,13 @@ type BubbleMenuIconButtonProps = {
|
||||
isActive?: boolean;
|
||||
};
|
||||
|
||||
const StyledBubbleMenuIconButton = styled(FloatingIconButton)`
|
||||
border: none;
|
||||
border-radius: ${themeCssVariables.spacing[1.5]};
|
||||
width: ${themeCssVariables.spacing[6]};
|
||||
height: ${themeCssVariables.spacing[6]};
|
||||
const StyledBubbleMenuIconButtonContainer = styled.div`
|
||||
& > button {
|
||||
border: none;
|
||||
border-radius: ${themeCssVariables.spacing[1.5]};
|
||||
width: ${themeCssVariables.spacing[6]};
|
||||
height: ${themeCssVariables.spacing[6]};
|
||||
}
|
||||
`;
|
||||
|
||||
export const BubbleMenuIconButton = ({
|
||||
@@ -29,17 +31,18 @@ export const BubbleMenuIconButton = ({
|
||||
isActive,
|
||||
}: BubbleMenuIconButtonProps) => {
|
||||
return (
|
||||
<StyledBubbleMenuIconButton
|
||||
className={className}
|
||||
Icon={Icon}
|
||||
disabled={disabled}
|
||||
focus={focus}
|
||||
onClick={onClick}
|
||||
isActive={isActive}
|
||||
applyShadow={false}
|
||||
applyBlur={false}
|
||||
size="medium"
|
||||
position="standalone"
|
||||
/>
|
||||
<StyledBubbleMenuIconButtonContainer className={className}>
|
||||
<FloatingIconButton
|
||||
Icon={Icon}
|
||||
disabled={disabled}
|
||||
focus={focus}
|
||||
onClick={onClick}
|
||||
isActive={isActive}
|
||||
applyShadow={false}
|
||||
applyBlur={false}
|
||||
size="medium"
|
||||
position="standalone"
|
||||
/>
|
||||
</StyledBubbleMenuIconButtonContainer>
|
||||
);
|
||||
};
|
||||
|
||||
+10
-7
@@ -6,11 +6,14 @@ import { useToggleDropdown } from '@/ui/layout/dropdown/hooks/useToggleDropdown'
|
||||
import { styled } from '@linaria/react';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { type Editor } from '@tiptap/react';
|
||||
import { useContext, useId } from 'react';
|
||||
import { useId } from 'react';
|
||||
import { IconPilcrow } from 'twenty-ui/display';
|
||||
import { MenuItem } from 'twenty-ui/navigation';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
import {
|
||||
resolveThemeVariable,
|
||||
resolveThemeVariableAsNumber,
|
||||
themeCssVariables,
|
||||
} from 'twenty-ui/theme-constants';
|
||||
|
||||
const StyledMenuItem = styled.button`
|
||||
align-items: center;
|
||||
@@ -44,8 +47,6 @@ type TurnIntoBlockDropdownProps = {
|
||||
export const TurnIntoBlockDropdown = ({
|
||||
editor,
|
||||
}: TurnIntoBlockDropdownProps) => {
|
||||
const { theme } = useContext(ThemeContext);
|
||||
|
||||
const instanceId = useId();
|
||||
const dropdownId = `turn-into-block-dropdown-${instanceId}`;
|
||||
const { toggleDropdown } = useToggleDropdown();
|
||||
@@ -79,12 +80,14 @@ export const TurnIntoBlockDropdown = ({
|
||||
dropdownId={dropdownId}
|
||||
clickableComponent={
|
||||
<StyledMenuItem>
|
||||
<ActiveIcon size={theme.icon.size.md} />
|
||||
<ActiveIcon
|
||||
size={resolveThemeVariableAsNumber(themeCssVariables.icon.size.md)}
|
||||
/>
|
||||
{activeTitle}
|
||||
</StyledMenuItem>
|
||||
}
|
||||
dropdownOffset={{
|
||||
y: parseInt(theme.spacing(1), 10),
|
||||
y: parseInt(resolveThemeVariable(themeCssVariables.spacing[1]), 10),
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
+10
-6
@@ -2,12 +2,13 @@ import { getFileType } from '@/activities/files/utils/getFileType';
|
||||
import { useFileCategoryColors } from '@/file/hooks/useFileCategoryColors';
|
||||
import { IconMapping } from '@/file/utils/fileIconMappings';
|
||||
import { styled } from '@linaria/react';
|
||||
import { useContext } from 'react';
|
||||
import { type WorkflowAttachment } from 'twenty-shared/workflow';
|
||||
import { AvatarOrIcon } from 'twenty-ui/components';
|
||||
import { IconX } from 'twenty-ui/display';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
import {
|
||||
resolveThemeVariableAsNumber,
|
||||
themeCssVariables,
|
||||
} from 'twenty-ui/theme-constants';
|
||||
|
||||
type WorkflowAttachmentChipProps = {
|
||||
file: WorkflowAttachment;
|
||||
@@ -66,8 +67,6 @@ export const WorkflowAttachmentChip = ({
|
||||
readonly = false,
|
||||
}: WorkflowAttachmentChipProps) => {
|
||||
const iconColors = useFileCategoryColors();
|
||||
const { theme } = useContext(ThemeContext);
|
||||
|
||||
return (
|
||||
<StyledChip data-chip deletable={!readonly}>
|
||||
<AvatarOrIcon
|
||||
@@ -78,7 +77,12 @@ export const WorkflowAttachmentChip = ({
|
||||
|
||||
{!readonly && (
|
||||
<StyledDelete onClick={onRemove}>
|
||||
<IconX size={theme.icon.size.sm} stroke={theme.icon.stroke.sm} />
|
||||
<IconX
|
||||
size={resolveThemeVariableAsNumber(themeCssVariables.icon.size.sm)}
|
||||
stroke={resolveThemeVariableAsNumber(
|
||||
themeCssVariables.icon.stroke.sm,
|
||||
)}
|
||||
/>
|
||||
</StyledDelete>
|
||||
)}
|
||||
</StyledChip>
|
||||
|
||||
+10
-6
@@ -4,12 +4,14 @@ import { InputLabel } from '@/ui/input/components/InputLabel';
|
||||
|
||||
import { styled } from '@linaria/react';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { type ChangeEvent, useContext, useRef } from 'react';
|
||||
import { type ChangeEvent, useRef } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { type WorkflowAttachment } from 'twenty-shared/workflow';
|
||||
import { IconUpload } from 'twenty-ui/display';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
import {
|
||||
resolveThemeVariableAsNumber,
|
||||
themeCssVariables,
|
||||
} from 'twenty-ui/theme-constants';
|
||||
|
||||
type WorkflowSendEmailAttachmentsProps = {
|
||||
files: WorkflowAttachment[];
|
||||
@@ -70,8 +72,6 @@ export const WorkflowSendEmailAttachments = ({
|
||||
const fileInputRef = useRef<HTMLInputElement>(null);
|
||||
const { uploadWorkflowFile } = useUploadWorkflowFile();
|
||||
const { t } = useLingui();
|
||||
const { theme } = useContext(ThemeContext);
|
||||
|
||||
const handleAddFileClick = (e: React.MouseEvent) => {
|
||||
const target = e.target as HTMLElement;
|
||||
|
||||
@@ -141,7 +141,11 @@ export const WorkflowSendEmailAttachments = ({
|
||||
</StyledChipsContainer>
|
||||
) : (
|
||||
<StyledUploadAreaLabel>
|
||||
<IconUpload size={theme.icon.size.sm} />
|
||||
<IconUpload
|
||||
size={resolveThemeVariableAsNumber(
|
||||
themeCssVariables.icon.size.sm,
|
||||
)}
|
||||
/>
|
||||
<span>{t`Upload file`}</span>
|
||||
</StyledUploadAreaLabel>
|
||||
)}
|
||||
|
||||
@@ -7,11 +7,12 @@ import { LazyMarkdownRenderer } from '@/ai/components/LazyMarkdownRenderer';
|
||||
import { ToolStepRenderer } from '@/ai/components/ToolStepRenderer';
|
||||
import { groupContiguousThinkingStepParts } from '@/ai/utils/groupContiguousThinkingStepParts';
|
||||
import { styled } from '@linaria/react';
|
||||
import { useContext } from 'react';
|
||||
import { isToolUIPart, type ToolUIPart } from 'ai';
|
||||
import { type ExtendedUIMessagePart } from 'twenty-shared/ai';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
import {
|
||||
resolveThemeVariableAsNumber,
|
||||
themeCssVariables,
|
||||
} from 'twenty-ui/theme-constants';
|
||||
|
||||
const StyledMessagePartsContainer = styled.div`
|
||||
display: flex;
|
||||
@@ -28,17 +29,20 @@ const StyledLoadingIconContainer = styled.div`
|
||||
padding-inline: ${themeCssVariables.spacing[1]};
|
||||
`;
|
||||
|
||||
const StyledLoadingIcon = styled(IconDotsVertical)`
|
||||
const StyledLoadingIconWrapper = styled.span`
|
||||
color: ${themeCssVariables.font.color.light};
|
||||
transform: rotate(90deg);
|
||||
display: flex;
|
||||
`;
|
||||
|
||||
const InitialLoadingIndicator = () => {
|
||||
const { theme } = useContext(ThemeContext);
|
||||
|
||||
return (
|
||||
<StyledLoadingIconContainer>
|
||||
<StyledLoadingIcon size={theme.icon.size.xl} />
|
||||
<StyledLoadingIconWrapper>
|
||||
<IconDotsVertical
|
||||
size={resolveThemeVariableAsNumber(themeCssVariables.icon.size.xl)}
|
||||
/>
|
||||
</StyledLoadingIconWrapper>
|
||||
</StyledLoadingIconContainer>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import { useAgentChatContextOrThrow } from '@/ai/hooks/useAgentChatContextOrThrow';
|
||||
import { styled } from '@linaria/react';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { useContext } from 'react';
|
||||
import { IconAlertCircle, IconRefresh } from 'twenty-ui/display';
|
||||
import { Button } from 'twenty-ui/input';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
import {
|
||||
resolveThemeVariableAsNumber,
|
||||
themeCssVariables,
|
||||
} from 'twenty-ui/theme-constants';
|
||||
|
||||
const StyledErrorContainer = styled.div`
|
||||
align-items: center;
|
||||
@@ -47,13 +48,14 @@ type AIChatErrorMessageProps = {
|
||||
};
|
||||
|
||||
export const AIChatErrorMessage = ({ error }: AIChatErrorMessageProps) => {
|
||||
const { theme } = useContext(ThemeContext);
|
||||
const { handleRetry, isStreaming } = useAgentChatContextOrThrow();
|
||||
|
||||
return (
|
||||
<StyledErrorContainer>
|
||||
<StyledErrorIcon>
|
||||
<IconAlertCircle size={theme.icon.size.md} />
|
||||
<IconAlertCircle
|
||||
size={resolveThemeVariableAsNumber(themeCssVariables.icon.size.md)}
|
||||
/>
|
||||
</StyledErrorIcon>
|
||||
<StyledErrorContent>
|
||||
<StyledErrorTitle>{t`Failed to get response`}</StyledErrorTitle>
|
||||
|
||||
@@ -100,14 +100,17 @@ const StyledEditorWrapper = styled.div`
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledScrollWrapper = styled(ScrollWrapper)`
|
||||
const StyledScrollWrapperContainer = styled.div`
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
gap: ${themeCssVariables.spacing[2]};
|
||||
overflow-y: auto;
|
||||
padding: ${themeCssVariables.spacing[3]};
|
||||
width: calc(100% - 24px) !important;
|
||||
overflow: hidden;
|
||||
|
||||
> div {
|
||||
gap: ${themeCssVariables.spacing[2]};
|
||||
padding: ${themeCssVariables.spacing[3]};
|
||||
width: calc(100% - 24px) !important;
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledButtonsContainer = styled.div`
|
||||
@@ -129,12 +132,14 @@ const StyledRightButtonsContainer = styled.div`
|
||||
gap: ${themeCssVariables.spacing[1]};
|
||||
`;
|
||||
|
||||
const StyledReadOnlyModelButton = styled(LightButton)`
|
||||
cursor: default;
|
||||
const StyledReadOnlyModelButtonContainer = styled.div`
|
||||
& > button {
|
||||
cursor: default;
|
||||
|
||||
&:hover,
|
||||
&:active {
|
||||
background: transparent;
|
||||
&:hover,
|
||||
&:active {
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -167,31 +172,32 @@ export const AIChatTab = () => {
|
||||
{!isDraggingFile && (
|
||||
<>
|
||||
{hasMessages && (
|
||||
<StyledScrollWrapper
|
||||
componentInstanceId={AI_CHAT_SCROLL_WRAPPER_ID}
|
||||
>
|
||||
{messages.map((message, index) => {
|
||||
const isLastMessage = index === messages.length - 1;
|
||||
const isLastMessageStreaming = isStreaming && isLastMessage;
|
||||
const isLastAssistantMessage =
|
||||
isLastMessage && message.role === AgentMessageRole.ASSISTANT;
|
||||
const shouldShowError = error && isLastAssistantMessage;
|
||||
<StyledScrollWrapperContainer>
|
||||
<ScrollWrapper componentInstanceId={AI_CHAT_SCROLL_WRAPPER_ID}>
|
||||
{messages.map((message, index) => {
|
||||
const isLastMessage = index === messages.length - 1;
|
||||
const isLastMessageStreaming = isStreaming && isLastMessage;
|
||||
const isLastAssistantMessage =
|
||||
isLastMessage &&
|
||||
message.role === AgentMessageRole.ASSISTANT;
|
||||
const shouldShowError = error && isLastAssistantMessage;
|
||||
|
||||
return (
|
||||
<AIChatMessage
|
||||
isLastMessageStreaming={isLastMessageStreaming}
|
||||
message={message}
|
||||
key={message.id}
|
||||
error={shouldShowError ? error : null}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
{error &&
|
||||
!isStreaming &&
|
||||
messages.at(-1)?.role === AgentMessageRole.USER && (
|
||||
<AIChatStandaloneError error={error} />
|
||||
)}
|
||||
</StyledScrollWrapper>
|
||||
return (
|
||||
<AIChatMessage
|
||||
isLastMessageStreaming={isLastMessageStreaming}
|
||||
message={message}
|
||||
key={message.id}
|
||||
error={shouldShowError ? error : null}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
{error &&
|
||||
!isStreaming &&
|
||||
messages.at(-1)?.role === AgentMessageRole.USER && (
|
||||
<AIChatStandaloneError error={error} />
|
||||
)}
|
||||
</ScrollWrapper>
|
||||
</StyledScrollWrapperContainer>
|
||||
)}
|
||||
{!hasMessages && !error && !isLoading && (
|
||||
<AIChatEmptyState editor={editor} />
|
||||
@@ -213,10 +219,9 @@ export const AIChatTab = () => {
|
||||
{hasMessages && <AIChatContextUsageButton />}
|
||||
</StyledLeftButtonsContainer>
|
||||
<StyledRightButtonsContainer>
|
||||
<StyledReadOnlyModelButton
|
||||
accent="tertiary"
|
||||
title={smartModelLabel}
|
||||
/>
|
||||
<StyledReadOnlyModelButtonContainer>
|
||||
<LightButton accent="tertiary" title={smartModelLabel} />
|
||||
</StyledReadOnlyModelButtonContainer>
|
||||
<SendMessageButton onSend={handleSendAndClear} />
|
||||
</StyledRightButtonsContainer>
|
||||
</StyledButtonsContainer>
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import { useAIChatThreadClick } from '@/ai/hooks/useAIChatThreadClick';
|
||||
import { styled } from '@linaria/react';
|
||||
import { useContext } from 'react';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { IconSparkles } from 'twenty-ui/display';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
import {
|
||||
resolveThemeVariable,
|
||||
resolveThemeVariableAsNumber,
|
||||
themeCssVariables,
|
||||
} from 'twenty-ui/theme-constants';
|
||||
import { type AgentChatThread } from '~/generated-metadata/graphql';
|
||||
|
||||
const StyledThreadsList = styled.div`
|
||||
@@ -74,7 +76,6 @@ export const AIChatThreadGroup = ({
|
||||
title: string;
|
||||
}) => {
|
||||
const { t } = useLingui();
|
||||
const { theme } = useContext(ThemeContext);
|
||||
const { handleThreadClick } = useAIChatThreadClick();
|
||||
|
||||
if (threads.length === 0) {
|
||||
@@ -92,8 +93,10 @@ export const AIChatThreadGroup = ({
|
||||
>
|
||||
<StyledSparkleIcon>
|
||||
<IconSparkles
|
||||
size={theme.icon.size.md}
|
||||
color={theme.color.blue}
|
||||
size={resolveThemeVariableAsNumber(
|
||||
themeCssVariables.icon.size.md,
|
||||
)}
|
||||
color={resolveThemeVariable(themeCssVariables.color.blue)}
|
||||
/>
|
||||
</StyledSparkleIcon>
|
||||
<StyledThreadContent>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { TerminalOutput } from '@/ai/components/TerminalOutput';
|
||||
import { styled } from '@linaria/react';
|
||||
import { useContext, useState } from 'react';
|
||||
import { useState } from 'react';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import {
|
||||
IconChevronDown,
|
||||
@@ -15,8 +15,11 @@ import {
|
||||
} from 'twenty-ui/display';
|
||||
import { CodeEditor, LightIconButton } from 'twenty-ui/input';
|
||||
import { AnimatedExpandableContainer } from 'twenty-ui/layout';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
import {
|
||||
resolveThemeVariable,
|
||||
resolveThemeVariableAsNumber,
|
||||
themeCssVariables,
|
||||
} from 'twenty-ui/theme-constants';
|
||||
import { useCopyToClipboard } from '~/hooks/useCopyToClipboard';
|
||||
|
||||
const StyledContainer = styled.div`
|
||||
@@ -203,7 +206,6 @@ export const CodeExecutionDisplay = ({
|
||||
isRunning = false,
|
||||
}: CodeExecutionDisplayProps) => {
|
||||
const { t } = useLingui();
|
||||
const { theme } = useContext(ThemeContext);
|
||||
const { copyToClipboard } = useCopyToClipboard();
|
||||
const [isCodeExpanded, setIsCodeExpanded] = useState(false);
|
||||
const [isOutputExpanded, setIsOutputExpanded] = useState(true);
|
||||
@@ -235,12 +237,18 @@ export const CodeExecutionDisplay = ({
|
||||
<StyledContainer>
|
||||
<StyledHeader status={status}>
|
||||
<StyledHeaderLeft>
|
||||
<IconCode size={theme.icon.size.md} />
|
||||
<IconCode
|
||||
size={resolveThemeVariableAsNumber(themeCssVariables.icon.size.md)}
|
||||
/>
|
||||
<StyledTitle>{t`Python Code Execution`}</StyledTitle>
|
||||
</StyledHeaderLeft>
|
||||
<StyledHeaderRight>
|
||||
<StyledStatusBadge status={status}>
|
||||
<StatusIcon size={theme.icon.size.sm} />
|
||||
<StatusIcon
|
||||
size={resolveThemeVariableAsNumber(
|
||||
themeCssVariables.icon.size.sm,
|
||||
)}
|
||||
/>
|
||||
{statusText}
|
||||
</StyledStatusBadge>
|
||||
</StyledHeaderRight>
|
||||
@@ -249,7 +257,11 @@ export const CodeExecutionDisplay = ({
|
||||
<StyledSection>
|
||||
<StyledSectionHeader onClick={() => setIsCodeExpanded(!isCodeExpanded)}>
|
||||
<StyledSectionHeaderLeft>
|
||||
<IconCode size={theme.icon.size.sm} />
|
||||
<IconCode
|
||||
size={resolveThemeVariableAsNumber(
|
||||
themeCssVariables.icon.size.sm,
|
||||
)}
|
||||
/>
|
||||
{t`Code`}
|
||||
</StyledSectionHeaderLeft>
|
||||
<StyledHeaderRight>
|
||||
@@ -264,9 +276,17 @@ export const CodeExecutionDisplay = ({
|
||||
accent="tertiary"
|
||||
/>
|
||||
{isCodeExpanded ? (
|
||||
<IconChevronUp size={theme.icon.size.sm} />
|
||||
<IconChevronUp
|
||||
size={resolveThemeVariableAsNumber(
|
||||
themeCssVariables.icon.size.sm,
|
||||
)}
|
||||
/>
|
||||
) : (
|
||||
<IconChevronDown size={theme.icon.size.sm} />
|
||||
<IconChevronDown
|
||||
size={resolveThemeVariableAsNumber(
|
||||
themeCssVariables.icon.size.sm,
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
</StyledHeaderRight>
|
||||
</StyledSectionHeader>
|
||||
@@ -296,9 +316,17 @@ export const CodeExecutionDisplay = ({
|
||||
>
|
||||
<StyledSectionHeaderLeft>{t`Output`}</StyledSectionHeaderLeft>
|
||||
{isOutputExpanded ? (
|
||||
<IconChevronUp size={theme.icon.size.sm} />
|
||||
<IconChevronUp
|
||||
size={resolveThemeVariableAsNumber(
|
||||
themeCssVariables.icon.size.sm,
|
||||
)}
|
||||
/>
|
||||
) : (
|
||||
<IconChevronDown size={theme.icon.size.sm} />
|
||||
<IconChevronDown
|
||||
size={resolveThemeVariableAsNumber(
|
||||
themeCssVariables.icon.size.sm,
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
</StyledSectionHeader>
|
||||
<AnimatedExpandableContainer
|
||||
@@ -320,13 +348,25 @@ export const CodeExecutionDisplay = ({
|
||||
onClick={() => setIsFilesExpanded(!isFilesExpanded)}
|
||||
>
|
||||
<StyledSectionHeaderLeft>
|
||||
<IconFile size={theme.icon.size.sm} />
|
||||
<IconFile
|
||||
size={resolveThemeVariableAsNumber(
|
||||
themeCssVariables.icon.size.sm,
|
||||
)}
|
||||
/>
|
||||
{t`Generated Files`} ({files.length})
|
||||
</StyledSectionHeaderLeft>
|
||||
{isFilesExpanded ? (
|
||||
<IconChevronUp size={theme.icon.size.sm} />
|
||||
<IconChevronUp
|
||||
size={resolveThemeVariableAsNumber(
|
||||
themeCssVariables.icon.size.sm,
|
||||
)}
|
||||
/>
|
||||
) : (
|
||||
<IconChevronDown size={theme.icon.size.sm} />
|
||||
<IconChevronDown
|
||||
size={resolveThemeVariableAsNumber(
|
||||
themeCssVariables.icon.size.sm,
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
</StyledSectionHeader>
|
||||
<AnimatedExpandableContainer
|
||||
@@ -347,7 +387,12 @@ export const CodeExecutionDisplay = ({
|
||||
loading="lazy"
|
||||
/>
|
||||
) : (
|
||||
<IconFile size={48} color={theme.font.color.tertiary} />
|
||||
<IconFile
|
||||
size={48}
|
||||
color={resolveThemeVariable(
|
||||
themeCssVariables.font.color.tertiary,
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
</StyledFilePreview>
|
||||
<StyledFileInfo>
|
||||
@@ -361,7 +406,11 @@ export const CodeExecutionDisplay = ({
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<IconDownload size={theme.icon.size.sm} />
|
||||
<IconDownload
|
||||
size={resolveThemeVariableAsNumber(
|
||||
themeCssVariables.icon.size.sm,
|
||||
)}
|
||||
/>
|
||||
</StyledDownloadLink>
|
||||
</StyledFileInfo>
|
||||
</StyledFileCard>
|
||||
|
||||
@@ -10,10 +10,13 @@ import {
|
||||
StyledSkeletonContainer,
|
||||
StyledTableScrollContainer,
|
||||
} from '@/ai/components/LazyMarkdownRendererStyledComponents';
|
||||
import { lazy, Suspense, useContext } from 'react';
|
||||
import { lazy, Suspense } from 'react';
|
||||
import Skeleton, { SkeletonTheme } from 'react-loading-skeleton';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
import {
|
||||
resolveThemeVariable,
|
||||
themeCssVariables,
|
||||
} from 'twenty-ui/theme-constants';
|
||||
|
||||
const TextWithRecordLinks = ({ text }: { text: string }) => {
|
||||
const parts: React.ReactNode[] = [];
|
||||
@@ -131,13 +134,13 @@ const MarkdownRenderer = lazy(async () => {
|
||||
});
|
||||
|
||||
const LoadingSkeleton = () => {
|
||||
const { theme } = useContext(ThemeContext);
|
||||
|
||||
return (
|
||||
<SkeletonTheme
|
||||
baseColor={theme.background.tertiary}
|
||||
highlightColor={theme.background.transparent.lighter}
|
||||
borderRadius={theme.border.radius.sm}
|
||||
baseColor={resolveThemeVariable(themeCssVariables.background.tertiary)}
|
||||
highlightColor={resolveThemeVariable(
|
||||
themeCssVariables.background.transparent.lighter,
|
||||
)}
|
||||
borderRadius={resolveThemeVariable(themeCssVariables.border.radius.sm)}
|
||||
>
|
||||
<StyledSkeletonContainer>
|
||||
<Skeleton
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import { styled } from '@linaria/react';
|
||||
import { useContext, useState } from 'react';
|
||||
import { useState } from 'react';
|
||||
|
||||
import { IconBrain, IconChevronDown, IconChevronUp } from 'twenty-ui/display';
|
||||
import { AnimatedExpandableContainer } from 'twenty-ui/layout';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
import {
|
||||
resolveThemeVariableAsNumber,
|
||||
themeCssVariables,
|
||||
} from 'twenty-ui/theme-constants';
|
||||
|
||||
import { ShimmeringText } from '@/ai/components/ShimmeringText';
|
||||
import { t } from '@lingui/core/macro';
|
||||
@@ -67,7 +69,6 @@ export const ReasoningSummaryDisplay = ({
|
||||
content: string;
|
||||
isThinking?: boolean;
|
||||
}) => {
|
||||
const { theme } = useContext(ThemeContext);
|
||||
const [isExpanded, setIsExpanded] = useState(false);
|
||||
|
||||
const hasContent = content.trim().length > 0;
|
||||
@@ -82,7 +83,11 @@ export const ReasoningSummaryDisplay = ({
|
||||
<>
|
||||
<ShimmeringText>
|
||||
<StyledIconContainer>
|
||||
<IconBrain size={theme.icon.size.sm} />
|
||||
<IconBrain
|
||||
size={resolveThemeVariableAsNumber(
|
||||
themeCssVariables.icon.size.sm,
|
||||
)}
|
||||
/>
|
||||
<StyledThinkingText>{t`Thinking...`}</StyledThinkingText>
|
||||
</StyledIconContainer>
|
||||
</ShimmeringText>
|
||||
@@ -96,13 +101,25 @@ export const ReasoningSummaryDisplay = ({
|
||||
<>
|
||||
<StyledToggleButton onClick={() => setIsExpanded(!isExpanded)}>
|
||||
<StyledIconContainer>
|
||||
<IconBrain size={theme.icon.size.sm} />
|
||||
<IconBrain
|
||||
size={resolveThemeVariableAsNumber(
|
||||
themeCssVariables.icon.size.sm,
|
||||
)}
|
||||
/>
|
||||
<span>{t`Finished thinking`}</span>
|
||||
</StyledIconContainer>
|
||||
{isExpanded ? (
|
||||
<IconChevronUp size={theme.icon.size.sm} />
|
||||
<IconChevronUp
|
||||
size={resolveThemeVariableAsNumber(
|
||||
themeCssVariables.icon.size.sm,
|
||||
)}
|
||||
/>
|
||||
) : (
|
||||
<IconChevronDown size={theme.icon.size.sm} />
|
||||
<IconChevronDown
|
||||
size={resolveThemeVariableAsNumber(
|
||||
themeCssVariables.icon.size.sm,
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
</StyledToggleButton>
|
||||
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import { styled } from '@linaria/react';
|
||||
import { useContext, useState } from 'react';
|
||||
import { useState } from 'react';
|
||||
|
||||
import { IconChevronDown, IconChevronUp } from 'twenty-ui/display';
|
||||
import { JsonTree } from 'twenty-ui/json-visualizer';
|
||||
import { AnimatedExpandableContainer } from 'twenty-ui/layout';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
import {
|
||||
resolveThemeVariableAsNumber,
|
||||
themeCssVariables,
|
||||
} from 'twenty-ui/theme-constants';
|
||||
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { type DataMessagePart } from 'twenty-shared/ai';
|
||||
@@ -324,7 +326,6 @@ type RoutingDebugDisplayProps = {
|
||||
|
||||
export const RoutingDebugDisplay = ({ debug }: RoutingDebugDisplayProps) => {
|
||||
const { t } = useLingui();
|
||||
const { theme } = useContext(ThemeContext);
|
||||
const { copyToClipboard } = useCopyToClipboard();
|
||||
const [isExpanded, setIsExpanded] = useState(false);
|
||||
const [activeTab, setActiveTab] = useState<TabType>('timing');
|
||||
@@ -334,9 +335,13 @@ export const RoutingDebugDisplay = ({ debug }: RoutingDebugDisplayProps) => {
|
||||
<StyledToggleButton onClick={() => setIsExpanded(!isExpanded)}>
|
||||
<StyledTimingLabel>{t`Debug Info`}</StyledTimingLabel>
|
||||
{isExpanded ? (
|
||||
<IconChevronUp size={theme.icon.size.sm} />
|
||||
<IconChevronUp
|
||||
size={resolveThemeVariableAsNumber(themeCssVariables.icon.size.sm)}
|
||||
/>
|
||||
) : (
|
||||
<IconChevronDown size={theme.icon.size.sm} />
|
||||
<IconChevronDown
|
||||
size={resolveThemeVariableAsNumber(themeCssVariables.icon.size.sm)}
|
||||
/>
|
||||
)}
|
||||
</StyledToggleButton>
|
||||
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
import { RoutingDebugDisplay } from '@/ai/components/RoutingDebugDisplay';
|
||||
import { ShimmeringText } from '@/ai/components/ShimmeringText';
|
||||
import { styled } from '@linaria/react';
|
||||
import { useContext, useState } from 'react';
|
||||
import { useState } from 'react';
|
||||
import { type DataMessagePart } from 'twenty-shared/ai';
|
||||
import { IconChevronDown, IconChevronUp, IconCpu } from 'twenty-ui/display';
|
||||
import { AnimatedExpandableContainer } from 'twenty-ui/layout';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
import {
|
||||
resolveThemeVariableAsNumber,
|
||||
themeCssVariables,
|
||||
} from 'twenty-ui/theme-constants';
|
||||
|
||||
const StyledContainer = styled.div`
|
||||
display: flex;
|
||||
@@ -62,7 +64,6 @@ export const RoutingStatusDisplay = ({
|
||||
}: {
|
||||
data: DataMessagePart['routing-status'];
|
||||
}) => {
|
||||
const { theme } = useContext(ThemeContext);
|
||||
const [isExpanded, setIsExpanded] = useState(false);
|
||||
const isLoading = data.state === 'loading';
|
||||
const isDebugMode = process.env.IS_DEBUG_MODE === 'true';
|
||||
@@ -76,7 +77,9 @@ export const RoutingStatusDisplay = ({
|
||||
return (
|
||||
<StyledContainer>
|
||||
<StyledIconTextContainer>
|
||||
<IconCpu size={theme.icon.size.sm} />
|
||||
<IconCpu
|
||||
size={resolveThemeVariableAsNumber(themeCssVariables.icon.size.sm)}
|
||||
/>
|
||||
<ShimmeringText>
|
||||
<StyledDisplayMessage>{data.text}</StyledDisplayMessage>
|
||||
</ShimmeringText>
|
||||
@@ -92,14 +95,24 @@ export const RoutingStatusDisplay = ({
|
||||
isExpandable={!!isExpandable}
|
||||
>
|
||||
<StyledIconTextContainer>
|
||||
<IconCpu size={theme.icon.size.sm} />
|
||||
<IconCpu
|
||||
size={resolveThemeVariableAsNumber(themeCssVariables.icon.size.sm)}
|
||||
/>
|
||||
<StyledDisplayMessage>{data.text}</StyledDisplayMessage>
|
||||
</StyledIconTextContainer>
|
||||
{isExpandable &&
|
||||
(isExpanded ? (
|
||||
<IconChevronUp size={theme.icon.size.sm} />
|
||||
<IconChevronUp
|
||||
size={resolveThemeVariableAsNumber(
|
||||
themeCssVariables.icon.size.sm,
|
||||
)}
|
||||
/>
|
||||
) : (
|
||||
<IconChevronDown size={theme.icon.size.sm} />
|
||||
<IconChevronDown
|
||||
size={resolveThemeVariableAsNumber(
|
||||
themeCssVariables.icon.size.sm,
|
||||
)}
|
||||
/>
|
||||
))}
|
||||
</StyledToggleButton>
|
||||
|
||||
|
||||
@@ -140,7 +140,7 @@ const StyledReasoningText = styled.p`
|
||||
white-space: pre-wrap;
|
||||
`;
|
||||
|
||||
const StyledOrbitLoaderIcon = styled(ThinkingOrbitLoaderIcon)`
|
||||
const StyledOrbitLoaderIconWrapper = styled.span`
|
||||
color: ${themeCssVariables.font.color.tertiary};
|
||||
`;
|
||||
|
||||
@@ -214,9 +214,11 @@ const StyledToolDetailsContainer = styled.div`
|
||||
overflow: hidden;
|
||||
`;
|
||||
|
||||
const StyledToolTabList = styled(TabList)`
|
||||
background-color: ${themeCssVariables.background.secondary};
|
||||
padding-left: ${themeCssVariables.spacing[1]};
|
||||
const StyledToolTabListContainer = styled.div`
|
||||
& > div {
|
||||
background-color: ${themeCssVariables.background.secondary};
|
||||
padding-left: ${themeCssVariables.spacing[1]};
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledToolDetailsContent = styled.div`
|
||||
@@ -334,11 +336,13 @@ const ThinkingToolStepRow = ({
|
||||
<StyledToolErrorText>{part.errorText}</StyledToolErrorText>
|
||||
) : (
|
||||
<StyledToolDetailsContent>
|
||||
<StyledToolTabList
|
||||
tabs={toolTabs}
|
||||
behaveAsLinks={false}
|
||||
componentInstanceId={toolTabListComponentInstanceId}
|
||||
/>
|
||||
<StyledToolTabListContainer>
|
||||
<TabList
|
||||
tabs={toolTabs}
|
||||
behaveAsLinks={false}
|
||||
componentInstanceId={toolTabListComponentInstanceId}
|
||||
/>
|
||||
</StyledToolTabListContainer>
|
||||
<StyledToolJsonContent>
|
||||
<StyledJsonTreeContainer>
|
||||
<JsonTree
|
||||
@@ -388,7 +392,13 @@ const ThinkingStepRow = ({
|
||||
return (
|
||||
<StyledRow>
|
||||
<StyledIconContainer>
|
||||
{isActive ? <StyledOrbitLoaderIcon /> : <IconCpu size={14} />}
|
||||
{isActive ? (
|
||||
<StyledOrbitLoaderIconWrapper>
|
||||
<ThinkingOrbitLoaderIcon />
|
||||
</StyledOrbitLoaderIconWrapper>
|
||||
) : (
|
||||
<IconCpu size={14} />
|
||||
)}
|
||||
</StyledIconContainer>
|
||||
<StyledRowLabelContainer>
|
||||
<StyledRowLabel>{isActive ? t`Thinking` : t`Thought`}</StyledRowLabel>
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import { styled } from '@linaria/react';
|
||||
import { useContext, useState } from 'react';
|
||||
import { useState } from 'react';
|
||||
|
||||
import { IconChevronDown, IconChevronUp } from 'twenty-ui/display';
|
||||
import { JsonTree } from 'twenty-ui/json-visualizer';
|
||||
import { AnimatedExpandableContainer } from 'twenty-ui/layout';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
import {
|
||||
resolveThemeVariableAsNumber,
|
||||
themeCssVariables,
|
||||
} from 'twenty-ui/theme-constants';
|
||||
|
||||
import { CodeExecutionDisplay } from '@/ai/components/CodeExecutionDisplay';
|
||||
import { ShimmeringText } from '@/ai/components/ShimmeringText';
|
||||
@@ -138,7 +140,6 @@ export const ToolStepRenderer = ({
|
||||
isStreaming: boolean;
|
||||
}) => {
|
||||
const { t } = useLingui();
|
||||
const { theme } = useContext(ThemeContext);
|
||||
const { copyToClipboard } = useCopyToClipboard();
|
||||
const [isExpanded, setIsExpanded] = useState(false);
|
||||
const [activeTab, setActiveTab] = useState<TabType>('output');
|
||||
@@ -193,7 +194,11 @@ export const ToolStepRenderer = ({
|
||||
<StyledToggleButton isExpandable={false}>
|
||||
<StyledLeftContent>
|
||||
<StyledIconTextContainer>
|
||||
<ToolIcon size={theme.icon.size.sm} />
|
||||
<ToolIcon
|
||||
size={resolveThemeVariableAsNumber(
|
||||
themeCssVariables.icon.size.sm,
|
||||
)}
|
||||
/>
|
||||
{isStreaming ? (
|
||||
<ShimmeringText>
|
||||
<StyledDisplayMessage>{displayText}</StyledDisplayMessage>
|
||||
@@ -242,7 +247,11 @@ export const ToolStepRenderer = ({
|
||||
>
|
||||
<StyledLeftContent>
|
||||
<StyledIconTextContainer>
|
||||
<ToolIcon size={theme.icon.size.sm} />
|
||||
<ToolIcon
|
||||
size={resolveThemeVariableAsNumber(
|
||||
themeCssVariables.icon.size.sm,
|
||||
)}
|
||||
/>
|
||||
<StyledDisplayMessage>{displayMessage}</StyledDisplayMessage>
|
||||
</StyledIconTextContainer>
|
||||
</StyledLeftContent>
|
||||
@@ -250,9 +259,17 @@ export const ToolStepRenderer = ({
|
||||
<StyledToolName>{toolName}</StyledToolName>
|
||||
{isExpandable &&
|
||||
(isExpanded ? (
|
||||
<IconChevronUp size={theme.icon.size.sm} />
|
||||
<IconChevronUp
|
||||
size={resolveThemeVariableAsNumber(
|
||||
themeCssVariables.icon.size.sm,
|
||||
)}
|
||||
/>
|
||||
) : (
|
||||
<IconChevronDown size={theme.icon.size.sm} />
|
||||
<IconChevronDown
|
||||
size={resolveThemeVariableAsNumber(
|
||||
themeCssVariables.icon.size.sm,
|
||||
)}
|
||||
/>
|
||||
))}
|
||||
</StyledRightContent>
|
||||
</StyledToggleButton>
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { THEME_LIGHT, ThemeContextProvider } from 'twenty-ui/theme';
|
||||
import { ColorSchemeProvider } from 'twenty-ui/theme-constants';
|
||||
import { type ExtendedUIMessagePart } from 'twenty-shared/ai';
|
||||
|
||||
import { AIChatAssistantMessageRenderer } from '@/ai/components/AIChatAssistantMessageRenderer';
|
||||
@@ -42,12 +42,12 @@ jest.mock('@/ai/components/CodeExecutionDisplay', () => ({
|
||||
|
||||
const renderAssistantRenderer = (messageParts: ExtendedUIMessagePart[]) => {
|
||||
return render(
|
||||
<ThemeContextProvider theme={THEME_LIGHT}>
|
||||
<ColorSchemeProvider colorScheme="light">
|
||||
<AIChatAssistantMessageRenderer
|
||||
messageParts={messageParts}
|
||||
isLastMessageStreaming={false}
|
||||
/>
|
||||
</ThemeContextProvider>,
|
||||
</ColorSchemeProvider>,
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
import { render, screen, waitFor } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { THEME_LIGHT, ThemeContextProvider } from 'twenty-ui/theme';
|
||||
import { ColorSchemeProvider } from 'twenty-ui/theme-constants';
|
||||
|
||||
import { ThinkingStepsDisplay } from '@/ai/components/ThinkingStepsDisplay';
|
||||
import { type ThinkingStepPart } from '@/ai/utils/thinkingStepPart';
|
||||
@@ -80,13 +80,13 @@ const renderThinkingStepsDisplay = ({
|
||||
hasAssistantTextResponseStarted?: boolean;
|
||||
}) => {
|
||||
return render(
|
||||
<ThemeContextProvider theme={THEME_LIGHT}>
|
||||
<ColorSchemeProvider colorScheme="light">
|
||||
<ThinkingStepsDisplay
|
||||
parts={parts}
|
||||
isLastMessageStreaming={isLastMessageStreaming}
|
||||
hasAssistantTextResponseStarted={hasAssistantTextResponseStarted}
|
||||
/>
|
||||
</ThemeContextProvider>,
|
||||
</ColorSchemeProvider>,
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
+21
-10
@@ -1,12 +1,14 @@
|
||||
import { styled } from '@linaria/react';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { useContext, useState } from 'react';
|
||||
import { useState } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { HorizontalSeparator } from 'twenty-ui/display';
|
||||
import { ProgressBar } from 'twenty-ui/feedback';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
import {
|
||||
themeCssVariables,
|
||||
resolveThemeVariable,
|
||||
} from 'twenty-ui/theme-constants';
|
||||
|
||||
import { ContextUsageProgressRing } from '@/ai/components/internal/ContextUsageProgressRing';
|
||||
import { SettingsBillingLabelValueItem } from '@/billing/components/internal/SettingsBillingLabelValueItem';
|
||||
@@ -114,7 +116,6 @@ const getCachedLabel = (lastMessage: AgentChatLastMessageUsage): string => {
|
||||
|
||||
export const AIChatContextUsageButton = () => {
|
||||
const { t } = useLingui();
|
||||
const { theme } = useContext(ThemeContext);
|
||||
const [isHovered, setIsHovered] = useState(false);
|
||||
const agentChatUsage = useAtomStateValue(agentChatUsageState);
|
||||
|
||||
@@ -165,19 +166,26 @@ export const AIChatContextUsageButton = () => {
|
||||
value={percentage}
|
||||
barColor={
|
||||
percentage > 80
|
||||
? theme.color.red
|
||||
? resolveThemeVariable(themeCssVariables.color.red)
|
||||
: percentage > 60
|
||||
? theme.color.orange
|
||||
: theme.color.blue
|
||||
? resolveThemeVariable(themeCssVariables.color.orange)
|
||||
: resolveThemeVariable(themeCssVariables.color.blue)
|
||||
}
|
||||
backgroundColor={theme.background.tertiary}
|
||||
backgroundColor={resolveThemeVariable(
|
||||
themeCssVariables.background.tertiary,
|
||||
)}
|
||||
withBorderRadius
|
||||
/>
|
||||
</StyledSection>
|
||||
|
||||
{isDefined(lastMessage) && (
|
||||
<>
|
||||
<HorizontalSeparator noMargin color={theme.background.tertiary} />
|
||||
<HorizontalSeparator
|
||||
noMargin
|
||||
color={resolveThemeVariable(
|
||||
themeCssVariables.background.tertiary,
|
||||
)}
|
||||
/>
|
||||
<StyledSection>
|
||||
<StyledSectionTitle>{t`Last message`}</StyledSectionTitle>
|
||||
<SettingsBillingLabelValueItem
|
||||
@@ -196,7 +204,10 @@ export const AIChatContextUsageButton = () => {
|
||||
</>
|
||||
)}
|
||||
|
||||
<HorizontalSeparator noMargin color={theme.background.tertiary} />
|
||||
<HorizontalSeparator
|
||||
noMargin
|
||||
color={resolveThemeVariable(themeCssVariables.background.tertiary)}
|
||||
/>
|
||||
<StyledSection>
|
||||
<StyledSectionTitle>{t`Conversation`}</StyledSectionTitle>
|
||||
<SettingsBillingLabelValueItem
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { styled } from '@linaria/react';
|
||||
import { useContext } from 'react';
|
||||
import Skeleton, { SkeletonTheme } from 'react-loading-skeleton';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
import {
|
||||
themeCssVariables,
|
||||
resolveThemeVariable,
|
||||
} from 'twenty-ui/theme-constants';
|
||||
|
||||
const StyledSkeletonContainer = styled.div`
|
||||
display: flex;
|
||||
@@ -25,12 +26,12 @@ const StyledMessageSkeleton = styled.div`
|
||||
const NUMBER_OF_SKELETONS = 6;
|
||||
|
||||
export const AIChatSkeletonLoader = () => {
|
||||
const { theme } = useContext(ThemeContext);
|
||||
|
||||
return (
|
||||
<SkeletonTheme
|
||||
baseColor={theme.background.tertiary}
|
||||
highlightColor={theme.background.transparent.lighter}
|
||||
baseColor={resolveThemeVariable(themeCssVariables.background.tertiary)}
|
||||
highlightColor={resolveThemeVariable(
|
||||
themeCssVariables.background.transparent.lighter,
|
||||
)}
|
||||
borderRadius={4}
|
||||
>
|
||||
<StyledSkeletonContainer>
|
||||
|
||||
@@ -7,13 +7,16 @@ import { filePreviewState } from '@/ui/field/display/states/filePreviewState';
|
||||
import { useSetAtomState } from '@/ui/utilities/state/jotai/hooks/useSetAtomState';
|
||||
import { styled } from '@linaria/react';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { useCallback, useContext } from 'react';
|
||||
import { useCallback } from 'react';
|
||||
import { type ExtendedFileUIPart } from 'twenty-shared/ai';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { AvatarOrIcon, Chip, ChipVariant } from 'twenty-ui/components';
|
||||
import { type IconComponent, IconX } from 'twenty-ui/display';
|
||||
import { Loader } from 'twenty-ui/feedback';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
import {
|
||||
resolveThemeVariable,
|
||||
themeCssVariables,
|
||||
} from 'twenty-ui/theme-constants';
|
||||
|
||||
const StyledClickableContainer = styled.div<{ clickable: boolean }>`
|
||||
cursor: ${({ clickable }: { clickable: boolean }) =>
|
||||
@@ -31,7 +34,6 @@ export const AgentChatFilePreview = ({
|
||||
onRemove?: () => void;
|
||||
isUploading?: boolean;
|
||||
}) => {
|
||||
const { theme } = useContext(ThemeContext);
|
||||
const iconColors: Record<AttachmentFileCategory, string> =
|
||||
useFileCategoryColors();
|
||||
const setFilePreview = useSetAtomState(filePreviewState);
|
||||
@@ -74,7 +76,7 @@ export const AgentChatFilePreview = ({
|
||||
const rightComponent = onRemove ? (
|
||||
<AvatarOrIcon
|
||||
Icon={IconX}
|
||||
IconColor={theme.font.color.secondary}
|
||||
IconColor={resolveThemeVariable(themeCssVariables.font.color.secondary)}
|
||||
onClick={onRemove}
|
||||
/>
|
||||
) : undefined;
|
||||
|
||||
+7
-8
@@ -1,7 +1,8 @@
|
||||
import { styled } from '@linaria/react';
|
||||
import { useContext } from 'react';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
import {
|
||||
themeCssVariables,
|
||||
resolveThemeVariable,
|
||||
} from 'twenty-ui/theme-constants';
|
||||
|
||||
type ContextUsageProgressRingProps = {
|
||||
percentage: number;
|
||||
@@ -32,8 +33,6 @@ export const ContextUsageProgressRing = ({
|
||||
size = 16,
|
||||
strokeWidth = 2,
|
||||
}: ContextUsageProgressRingProps) => {
|
||||
const { theme } = useContext(ThemeContext);
|
||||
|
||||
const normalizedPercentage = Math.min(Math.max(percentage, 0), 100);
|
||||
const radius = (size - strokeWidth) / 2;
|
||||
const circumference = 2 * Math.PI * radius;
|
||||
@@ -42,10 +41,10 @@ export const ContextUsageProgressRing = ({
|
||||
|
||||
const progressColor =
|
||||
normalizedPercentage > 80
|
||||
? theme.color.red
|
||||
? resolveThemeVariable(themeCssVariables.color.red)
|
||||
: normalizedPercentage > 60
|
||||
? theme.color.orange
|
||||
: theme.color.blue;
|
||||
? resolveThemeVariable(themeCssVariables.color.orange)
|
||||
: resolveThemeVariable(themeCssVariables.color.blue);
|
||||
|
||||
return (
|
||||
<StyledSvg width={size} height={size}>
|
||||
|
||||
+9
-8
@@ -29,7 +29,7 @@ const StyledTitle = styled.div`
|
||||
padding: 0 ${themeCssVariables.spacing[2]};
|
||||
`;
|
||||
|
||||
const StyledSuggestedPromptButton = styled(LightButton)`
|
||||
const StyledSuggestedPromptButtonContainer = styled.div`
|
||||
align-self: flex-start;
|
||||
`;
|
||||
|
||||
@@ -62,13 +62,14 @@ export const AIChatSuggestedPrompts = ({
|
||||
<StyledContainer>
|
||||
<StyledTitle>{t`What can I help you with?`}</StyledTitle>
|
||||
{DEFAULT_SUGGESTED_PROMPTS.map((prompt) => (
|
||||
<StyledSuggestedPromptButton
|
||||
key={prompt.id}
|
||||
Icon={prompt.Icon}
|
||||
title={resolveMessage(prompt.label)}
|
||||
accent="secondary"
|
||||
onClick={() => handleClick(prompt)}
|
||||
/>
|
||||
<StyledSuggestedPromptButtonContainer key={prompt.id}>
|
||||
<LightButton
|
||||
Icon={prompt.Icon}
|
||||
title={resolveMessage(prompt.label)}
|
||||
accent="secondary"
|
||||
onClick={() => handleClick(prompt)}
|
||||
/>
|
||||
</StyledSuggestedPromptButtonContainer>
|
||||
))}
|
||||
</StyledContainer>
|
||||
);
|
||||
|
||||
+19
-7
@@ -23,15 +23,16 @@ import { DEFAULT_WORKSPACE_LOGO } from '@/ui/navigation/navigation-drawer/consta
|
||||
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
|
||||
import { isNonEmptyString } from '@sniptt/guards';
|
||||
import { motion } from 'framer-motion';
|
||||
import { useContext } from 'react';
|
||||
import {
|
||||
Avatar,
|
||||
HorizontalSeparator,
|
||||
IconChevronRight,
|
||||
IconPlus,
|
||||
} from 'twenty-ui/display';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
import {
|
||||
resolveThemeVariableAsNumber,
|
||||
themeCssVariables,
|
||||
} from 'twenty-ui/theme-constants';
|
||||
import { type AvailableWorkspace } from '~/generated-metadata/graphql';
|
||||
import { getWorkspaceUrl } from '~/utils/getWorkspaceUrl';
|
||||
|
||||
@@ -139,7 +140,6 @@ export const SignInUpGlobalScopeForm = () => {
|
||||
const signInUpStep = useAtomStateValue(signInUpStepState);
|
||||
const { buildWorkspaceUrl } = useBuildWorkspaceUrl();
|
||||
const { signOut } = useAuth();
|
||||
const { theme } = useContext(ThemeContext);
|
||||
|
||||
const { createWorkspace } = useSignUpInNewWorkspace();
|
||||
const availableWorkspaces = useAtomStateValue(availableWorkspacesState);
|
||||
@@ -201,7 +201,11 @@ export const SignInUpGlobalScopeForm = () => {
|
||||
</StyledWorkspaceUrl>
|
||||
</StyledWorkspaceTextContainer>
|
||||
<StyledChevronIcon>
|
||||
<IconChevronRight size={theme.icon.size.md} />
|
||||
<IconChevronRight
|
||||
size={resolveThemeVariableAsNumber(
|
||||
themeCssVariables.icon.size.md,
|
||||
)}
|
||||
/>
|
||||
</StyledChevronIcon>
|
||||
</StyledWorkspaceContent>
|
||||
</StyledWorkspaceItem>
|
||||
@@ -210,13 +214,21 @@ export const SignInUpGlobalScopeForm = () => {
|
||||
<StyledWorkspaceItem onClick={() => createWorkspace()}>
|
||||
<StyledWorkspaceContent>
|
||||
<StyledWorkspaceLogo>
|
||||
<IconPlus size={theme.icon.size.lg} />
|
||||
<IconPlus
|
||||
size={resolveThemeVariableAsNumber(
|
||||
themeCssVariables.icon.size.lg,
|
||||
)}
|
||||
/>
|
||||
</StyledWorkspaceLogo>
|
||||
<StyledWorkspaceTextContainer>
|
||||
<StyledWorkspaceName>{t`Create a workspace`}</StyledWorkspaceName>
|
||||
</StyledWorkspaceTextContainer>
|
||||
<StyledChevronIcon>
|
||||
<IconChevronRight size={theme.icon.size.md} />
|
||||
<IconChevronRight
|
||||
size={resolveThemeVariableAsNumber(
|
||||
themeCssVariables.icon.size.md,
|
||||
)}
|
||||
/>
|
||||
</StyledChevronIcon>
|
||||
</StyledWorkspaceContent>
|
||||
</StyledWorkspaceItem>
|
||||
|
||||
+6
-12
@@ -3,11 +3,7 @@ import { I18nProvider } from '@lingui/react';
|
||||
import { fireEvent, render, screen } from '@testing-library/react';
|
||||
import { Provider as JotaiProvider } from 'jotai';
|
||||
import { SOURCE_LOCALE } from 'twenty-shared/translations';
|
||||
import {
|
||||
THEME_LIGHT,
|
||||
ThemeContextProvider,
|
||||
ThemeProvider,
|
||||
} from 'twenty-ui/theme';
|
||||
import { ColorSchemeProvider } from 'twenty-ui/theme-constants';
|
||||
|
||||
import { SignInUpGlobalScopeForm } from '@/auth/sign-in-up/components/SignInUpGlobalScopeForm';
|
||||
import {
|
||||
@@ -98,13 +94,11 @@ describe('SignInUpGlobalScopeForm', () => {
|
||||
|
||||
render(
|
||||
<JotaiProvider store={jotaiStore}>
|
||||
<ThemeProvider theme={THEME_LIGHT}>
|
||||
<ThemeContextProvider theme={THEME_LIGHT}>
|
||||
<I18nProvider i18n={i18n}>
|
||||
<SignInUpGlobalScopeForm />
|
||||
</I18nProvider>
|
||||
</ThemeContextProvider>
|
||||
</ThemeProvider>
|
||||
<ColorSchemeProvider colorScheme="light">
|
||||
<I18nProvider i18n={i18n}>
|
||||
<SignInUpGlobalScopeForm />
|
||||
</I18nProvider>
|
||||
</ColorSchemeProvider>
|
||||
</JotaiProvider>,
|
||||
);
|
||||
|
||||
|
||||
+7
-5
@@ -4,11 +4,12 @@ import { SettingsTextInput } from '@/ui/input/components/SettingsTextInput';
|
||||
import { styled } from '@linaria/react';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { motion } from 'framer-motion';
|
||||
import { useContext } from 'react';
|
||||
import { Controller, useFormContext } from 'react-hook-form';
|
||||
import { StyledText } from 'twenty-ui/display';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
import {
|
||||
themeCssVariables,
|
||||
resolveThemeVariable,
|
||||
} from 'twenty-ui/theme-constants';
|
||||
|
||||
const StyledFullWidthMotionDiv = styled(motion.div)`
|
||||
width: 100%;
|
||||
@@ -26,7 +27,6 @@ export const SignInUpPasswordField = ({
|
||||
signInUpMode: SignInUpMode;
|
||||
}) => {
|
||||
const { t } = useLingui();
|
||||
const { theme } = useContext(ThemeContext);
|
||||
const form = useFormContext<Form>();
|
||||
|
||||
return (
|
||||
@@ -61,7 +61,9 @@ export const SignInUpPasswordField = ({
|
||||
{signInUpMode === SignInUpMode.SignUp && (
|
||||
<StyledText
|
||||
text={t`At least 8 characters long.`}
|
||||
color={theme.font.color.secondary}
|
||||
color={resolveThemeVariable(
|
||||
themeCssVariables.font.color.secondary,
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
</StyledInputContainer>
|
||||
|
||||
+9
-5
@@ -7,14 +7,15 @@ import {
|
||||
import { extractSecretFromOtpUri } from '@/settings/two-factor-authentication/utils/extractSecretFromOtpUri';
|
||||
import { styled } from '@linaria/react';
|
||||
import { Trans, useLingui } from '@lingui/react/macro';
|
||||
import { useContext } from 'react';
|
||||
import QRCode from 'react-qr-code';
|
||||
import { useSetAtomState } from '@/ui/utilities/state/jotai/hooks/useSetAtomState';
|
||||
import { IconCopy } from 'twenty-ui/display';
|
||||
import { Loader } from 'twenty-ui/feedback';
|
||||
import { MainButton } from 'twenty-ui/input';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
import {
|
||||
resolveThemeVariableAsNumber,
|
||||
themeCssVariables,
|
||||
} from 'twenty-ui/theme-constants';
|
||||
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
|
||||
import { useCopyToClipboard } from '~/hooks/useCopyToClipboard';
|
||||
|
||||
@@ -70,7 +71,6 @@ const StyledCopySetupKeyLink = styled.button`
|
||||
|
||||
export const SignInUpTwoFactorAuthenticationProvision = () => {
|
||||
const { t } = useLingui();
|
||||
const { theme } = useContext(ThemeContext);
|
||||
const { copyToClipboard } = useCopyToClipboard();
|
||||
const qrCode = useAtomStateValue(qrCodeState);
|
||||
const setSignInUpStep = useSetAtomState(signInUpStepState);
|
||||
@@ -102,7 +102,11 @@ export const SignInUpTwoFactorAuthenticationProvision = () => {
|
||||
{!qrCode ? <Loader /> : <QRCode value={qrCode} />}
|
||||
{qrCode && (
|
||||
<StyledCopySetupKeyLink onClick={handleCopySetupKey}>
|
||||
<IconCopy size={theme.icon.size.sm} />
|
||||
<IconCopy
|
||||
size={resolveThemeVariableAsNumber(
|
||||
themeCssVariables.icon.size.sm,
|
||||
)}
|
||||
/>
|
||||
<Trans>Copy Setup Key</Trans>
|
||||
</StyledCopySetupKeyLink>
|
||||
)}
|
||||
|
||||
+10
-5
@@ -8,18 +8,23 @@ import {
|
||||
import { AuthenticatedMethod } from '@/auth/types/AuthenticatedMethod.enum';
|
||||
import { type SocialSSOSignInUpActionType } from '@/auth/types/socialSSOSignInUp.type';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { memo, useContext } from 'react';
|
||||
import { memo } from 'react';
|
||||
import { HorizontalSeparator, IconGoogle } from 'twenty-ui/display';
|
||||
import { MainButton } from 'twenty-ui/input';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
import { useAtomState } from '@/ui/utilities/state/jotai/hooks/useAtomState';
|
||||
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
|
||||
import { LastUsedPill } from './LastUsedPill';
|
||||
import { StyledSSOButtonContainer } from './SignInUpSSOButtonStyles';
|
||||
|
||||
import {
|
||||
resolveThemeVariableAsNumber,
|
||||
themeCssVariables,
|
||||
} from 'twenty-ui/theme-constants';
|
||||
const GoogleIcon = memo(() => {
|
||||
const { theme } = useContext(ThemeContext);
|
||||
return <IconGoogle size={theme.icon.size.md} />;
|
||||
return (
|
||||
<IconGoogle
|
||||
size={resolveThemeVariableAsNumber(themeCssVariables.icon.size.md)}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
export const SignInUpWithGoogle = ({
|
||||
|
||||
+11
-4
@@ -8,14 +8,16 @@ import {
|
||||
import { AuthenticatedMethod } from '@/auth/types/AuthenticatedMethod.enum';
|
||||
import { type SocialSSOSignInUpActionType } from '@/auth/types/socialSSOSignInUp.type';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { useContext } from 'react';
|
||||
import { HorizontalSeparator, IconMicrosoft } from 'twenty-ui/display';
|
||||
import { MainButton } from 'twenty-ui/input';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
import { useAtomState } from '@/ui/utilities/state/jotai/hooks/useAtomState';
|
||||
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
|
||||
import { LastUsedPill } from './LastUsedPill';
|
||||
import { StyledSSOButtonContainer } from './SignInUpSSOButtonStyles';
|
||||
import {
|
||||
resolveThemeVariableAsNumber,
|
||||
themeCssVariables,
|
||||
} from 'twenty-ui/theme-constants';
|
||||
|
||||
export const SignInUpWithMicrosoft = ({
|
||||
action,
|
||||
@@ -24,7 +26,6 @@ export const SignInUpWithMicrosoft = ({
|
||||
action: SocialSSOSignInUpActionType;
|
||||
isGlobalScope?: boolean;
|
||||
}) => {
|
||||
const { theme } = useContext(ThemeContext);
|
||||
const { t } = useLingui();
|
||||
|
||||
const signInUpStep = useAtomStateValue(signInUpStepState);
|
||||
@@ -45,7 +46,13 @@ export const SignInUpWithMicrosoft = ({
|
||||
<>
|
||||
<StyledSSOButtonContainer>
|
||||
<MainButton
|
||||
Icon={() => <IconMicrosoft size={theme.icon.size.md} />}
|
||||
Icon={() => (
|
||||
<IconMicrosoft
|
||||
size={resolveThemeVariableAsNumber(
|
||||
themeCssVariables.icon.size.md,
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
title={t`Continue with Microsoft`}
|
||||
onClick={handleClick}
|
||||
variant={signInUpStep === SignInUpStep.Init ? undefined : 'secondary'}
|
||||
|
||||
+11
-4
@@ -11,16 +11,17 @@ import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomState
|
||||
import { useAtomState } from '@/ui/utilities/state/jotai/hooks/useAtomState';
|
||||
import { useSetAtomState } from '@/ui/utilities/state/jotai/hooks/useSetAtomState';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { useContext } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { HorizontalSeparator, IconLock } from 'twenty-ui/display';
|
||||
import { MainButton } from 'twenty-ui/input';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
import { LastUsedPill } from './LastUsedPill';
|
||||
import { StyledSSOButtonContainer } from './SignInUpSSOButtonStyles';
|
||||
import {
|
||||
resolveThemeVariableAsNumber,
|
||||
themeCssVariables,
|
||||
} from 'twenty-ui/theme-constants';
|
||||
|
||||
export const SignInUpWithSSO = () => {
|
||||
const { theme } = useContext(ThemeContext);
|
||||
const { t } = useLingui();
|
||||
const setSignInUpStep = useSetAtomState(signInUpStepState);
|
||||
const workspaceAuthProviders = useAtomStateValue(workspaceAuthProvidersState);
|
||||
@@ -50,7 +51,13 @@ export const SignInUpWithSSO = () => {
|
||||
<>
|
||||
<StyledSSOButtonContainer>
|
||||
<MainButton
|
||||
Icon={() => <IconLock size={theme.icon.size.md} />}
|
||||
Icon={() => (
|
||||
<IconLock
|
||||
size={resolveThemeVariableAsNumber(
|
||||
themeCssVariables.icon.size.md,
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
title={t`Single sign-on (SSO)`}
|
||||
onClick={signInWithSSO}
|
||||
variant={signInUpStep === SignInUpStep.Init ? undefined : 'secondary'}
|
||||
|
||||
+22
-8
@@ -9,12 +9,14 @@ import { useGetWorkflowNodeExecutionUsage } from '@/billing/hooks/useGetWorkflow
|
||||
import { useNumberFormat } from '@/localization/hooks/useNumberFormat';
|
||||
import { useSubscriptionStatus } from '@/workspace/hooks/useSubscriptionStatus';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { useContext } from 'react';
|
||||
import { formatToShortNumber } from 'twenty-shared/utils';
|
||||
import { H2Title, HorizontalSeparator } from 'twenty-ui/display';
|
||||
import { ProgressBar } from 'twenty-ui/feedback';
|
||||
import { Section } from 'twenty-ui/layout';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
import {
|
||||
resolveThemeVariable,
|
||||
themeCssVariables,
|
||||
} from 'twenty-ui/theme-constants';
|
||||
import { SubscriptionStatus } from '~/generated-metadata/graphql';
|
||||
|
||||
export const SettingsBillingCreditsSection = ({
|
||||
@@ -60,8 +62,6 @@ export const SettingsBillingCreditsSection = ({
|
||||
currentBillingSubscription.interval,
|
||||
);
|
||||
|
||||
const { theme } = useContext(ThemeContext);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Section>
|
||||
@@ -77,15 +77,24 @@ export const SettingsBillingCreditsSection = ({
|
||||
<ProgressBar
|
||||
value={displayedProgressBarValue}
|
||||
barColor={
|
||||
progressBarValue > 100 ? theme.color.red8 : theme.color.blue
|
||||
progressBarValue > 100
|
||||
? resolveThemeVariable(themeCssVariables.color.red8)
|
||||
: resolveThemeVariable(themeCssVariables.color.blue)
|
||||
}
|
||||
backgroundColor={theme.background.tertiary}
|
||||
backgroundColor={resolveThemeVariable(
|
||||
themeCssVariables.background.tertiary,
|
||||
)}
|
||||
withBorderRadius={true}
|
||||
/>
|
||||
|
||||
{!isTrialing && (
|
||||
<>
|
||||
<HorizontalSeparator noMargin color={theme.background.tertiary} />
|
||||
<HorizontalSeparator
|
||||
noMargin
|
||||
color={resolveThemeVariable(
|
||||
themeCssVariables.background.tertiary,
|
||||
)}
|
||||
/>
|
||||
<SettingsBillingLabelValueItem
|
||||
label={t`Base Credits`}
|
||||
value={formatNumber(grantedCredits, {
|
||||
@@ -111,7 +120,12 @@ export const SettingsBillingCreditsSection = ({
|
||||
})}
|
||||
/>
|
||||
)}
|
||||
<HorizontalSeparator noMargin color={theme.background.tertiary} />
|
||||
<HorizontalSeparator
|
||||
noMargin
|
||||
color={resolveThemeVariable(
|
||||
themeCssVariables.background.tertiary,
|
||||
)}
|
||||
/>
|
||||
<SettingsBillingLabelValueItem
|
||||
label={t`Extra Credits Used`}
|
||||
value={`${formatToShortNumber(extraCreditsUsed)}`}
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import { styled } from '@linaria/react';
|
||||
import React, { useContext } from 'react';
|
||||
import React from 'react';
|
||||
import { IconCheck } from 'twenty-ui/display';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
import {
|
||||
themeCssVariables,
|
||||
resolveThemeVariable,
|
||||
} from 'twenty-ui/theme-constants';
|
||||
|
||||
const StyledBenefitContainer = styled.div`
|
||||
color: ${themeCssVariables.font.color.secondary};
|
||||
@@ -24,11 +26,13 @@ type SubscriptionBenefitProps = {
|
||||
children: React.ReactNode;
|
||||
};
|
||||
export const SubscriptionBenefit = ({ children }: SubscriptionBenefitProps) => {
|
||||
const { theme } = useContext(ThemeContext);
|
||||
return (
|
||||
<StyledBenefitContainer>
|
||||
<StyledCheckContainer>
|
||||
<IconCheck color={theme.grayScale.gray11} size={14} />
|
||||
<IconCheck
|
||||
color={resolveThemeVariable(themeCssVariables.grayScale.gray11)}
|
||||
size={14}
|
||||
/>
|
||||
</StyledCheckContainer>
|
||||
{children}
|
||||
</StyledBenefitContainer>
|
||||
|
||||
+25
-21
@@ -31,11 +31,11 @@ const StyledRow = styled.div`
|
||||
gap: ${themeCssVariables.spacing[2]};
|
||||
`;
|
||||
|
||||
const StyledSelect = styled(Select<string>)`
|
||||
const StyledSelectWrapper = styled.div`
|
||||
flex: 1 1;
|
||||
`;
|
||||
|
||||
const StyledButton = styled(Button)`
|
||||
const StyledButtonContainer = styled.div`
|
||||
flex: 0 0 auto;
|
||||
`;
|
||||
|
||||
@@ -160,26 +160,30 @@ export const MeteredPriceSelector = ({
|
||||
description={t`Number of new credits allocated every ${recurringInterval}`}
|
||||
/>
|
||||
<StyledRow>
|
||||
<StyledSelect
|
||||
dropdownId="settings_billing-metered-price"
|
||||
options={options}
|
||||
value={selectedPriceId ?? currentMeteredPrice.stripePriceId}
|
||||
onChange={handleChange}
|
||||
disabled={isUpdating || isTrialing}
|
||||
description={
|
||||
isTrialing ? t`Please start your subscription first` : undefined
|
||||
}
|
||||
fullWidth
|
||||
/>
|
||||
{isChanged && (
|
||||
<StyledButton
|
||||
title={isUpgrade() ? t`Upgrade` : t`Downgrade`}
|
||||
onClick={handleOpenConfirm}
|
||||
variant="primary"
|
||||
isLoading={isUpdating}
|
||||
disabled={!isChanged}
|
||||
accent={isUpgrade() ? 'blue' : 'danger'}
|
||||
<StyledSelectWrapper>
|
||||
<Select<string>
|
||||
dropdownId="settings_billing-metered-price"
|
||||
options={options}
|
||||
value={selectedPriceId ?? currentMeteredPrice.stripePriceId}
|
||||
onChange={handleChange}
|
||||
disabled={isUpdating || isTrialing}
|
||||
description={
|
||||
isTrialing ? t`Please start your subscription first` : undefined
|
||||
}
|
||||
fullWidth
|
||||
/>
|
||||
</StyledSelectWrapper>
|
||||
{isChanged && (
|
||||
<StyledButtonContainer>
|
||||
<Button
|
||||
title={isUpgrade() ? t`Upgrade` : t`Downgrade`}
|
||||
onClick={handleOpenConfirm}
|
||||
variant="primary"
|
||||
isLoading={isUpdating}
|
||||
disabled={!isChanged}
|
||||
accent={isUpgrade() ? 'blue' : 'danger'}
|
||||
/>
|
||||
</StyledButtonContainer>
|
||||
)}
|
||||
</StyledRow>
|
||||
<ConfirmationModal
|
||||
|
||||
+8
-5
@@ -1,9 +1,11 @@
|
||||
import { type IconComponent } from 'twenty-ui/display';
|
||||
import React, { useContext } from 'react';
|
||||
import React from 'react';
|
||||
import { styled } from '@linaria/react';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
import {
|
||||
resolveThemeVariableAsNumber,
|
||||
themeCssVariables,
|
||||
} from 'twenty-ui/theme-constants';
|
||||
|
||||
type SubscriptionInfoRowContainerProps = {
|
||||
Icon: IconComponent;
|
||||
@@ -55,11 +57,12 @@ export const SubscriptionInfoRowContainer = ({
|
||||
currentValue,
|
||||
nextValue,
|
||||
}: SubscriptionInfoRowContainerProps) => {
|
||||
const { theme } = useContext(ThemeContext);
|
||||
return (
|
||||
<StyledContainer>
|
||||
<StyledIconLabelContainer>
|
||||
<Icon size={theme.icon.size.md} />
|
||||
<Icon
|
||||
size={resolveThemeVariableAsNumber(themeCssVariables.icon.size.md)}
|
||||
/>
|
||||
<StyledLabelContainer>{label}</StyledLabelContainer>
|
||||
</StyledIconLabelContainer>
|
||||
{currentValue}
|
||||
|
||||
+27
-19
@@ -11,16 +11,20 @@ import { Chip, ChipVariant } from 'twenty-ui/components';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
|
||||
|
||||
const StyledRecordChip = styled(RecordChip)`
|
||||
height: auto;
|
||||
margin: 0;
|
||||
padding: 0 ${themeCssVariables.spacing[1]};
|
||||
const StyledRecordChipContainer = styled.span`
|
||||
> * {
|
||||
height: auto;
|
||||
margin: 0;
|
||||
padding: 0 ${themeCssVariables.spacing[1]};
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledInlineMentionRecordChip = styled(MentionRecordChip)`
|
||||
height: auto;
|
||||
margin: 0;
|
||||
padding: 0 ${themeCssVariables.spacing[1]};
|
||||
const StyledMentionRecordChipContainer = styled.span`
|
||||
> * {
|
||||
height: auto;
|
||||
margin: 0;
|
||||
padding: 0 ${themeCssVariables.spacing[1]};
|
||||
}
|
||||
`;
|
||||
|
||||
const LegacyMentionRenderer = ({
|
||||
@@ -69,11 +73,13 @@ const LegacyMentionRenderer = ({
|
||||
}
|
||||
|
||||
return (
|
||||
<StyledRecordChip
|
||||
objectNameSingular={objectMetadataItem.nameSingular}
|
||||
record={record}
|
||||
forceDisableClick={false}
|
||||
/>
|
||||
<StyledRecordChipContainer>
|
||||
<RecordChip
|
||||
objectNameSingular={objectMetadataItem.nameSingular}
|
||||
record={record}
|
||||
forceDisableClick={false}
|
||||
/>
|
||||
</StyledRecordChipContainer>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -112,12 +118,14 @@ export const MentionInlineContent = createReactInlineContentSpec(
|
||||
// New notes store objectNameSingular + label + imageUrl directly
|
||||
if (isNonEmptyString(objectNameSingular) && isNonEmptyString(label)) {
|
||||
return (
|
||||
<StyledInlineMentionRecordChip
|
||||
recordId={recordId}
|
||||
objectNameSingular={objectNameSingular}
|
||||
label={label}
|
||||
imageUrl={imageUrl}
|
||||
/>
|
||||
<StyledMentionRecordChipContainer>
|
||||
<MentionRecordChip
|
||||
recordId={recordId}
|
||||
objectNameSingular={objectNameSingular}
|
||||
label={label}
|
||||
imageUrl={imageUrl}
|
||||
/>
|
||||
</StyledMentionRecordChipContainer>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,9 +3,6 @@ import { BlockNoteView } from '@blocknote/mantine';
|
||||
import { SuggestionMenuController } from '@blocknote/react';
|
||||
import { styled } from '@linaria/react';
|
||||
import { type ClipboardEvent, useContext } from 'react';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
import { type BLOCK_SCHEMA } from '@/blocknote-editor/blocks/Schema';
|
||||
import { getSlashMenu } from '@/blocknote-editor/utils/getSlashMenu';
|
||||
import { CustomMentionMenu } from '@/blocknote-editor/components/CustomMentionMenu';
|
||||
@@ -15,6 +12,10 @@ import {
|
||||
type SuggestionItem,
|
||||
} from '@/blocknote-editor/components/CustomSlashMenu';
|
||||
import { useMentionMenu } from '@/mention/hooks/useMentionMenu';
|
||||
import {
|
||||
ColorSchemeContext,
|
||||
themeCssVariables,
|
||||
} from 'twenty-ui/theme-constants';
|
||||
|
||||
interface BlockEditorProps {
|
||||
editor: typeof BLOCK_SCHEMA.BlockNoteEditor;
|
||||
@@ -142,8 +143,9 @@ export const BlockEditor = ({
|
||||
onPaste,
|
||||
readonly,
|
||||
}: BlockEditorProps) => {
|
||||
const { theme } = useContext(ThemeContext);
|
||||
const blockNoteTheme = theme.name === 'light' ? 'light' : 'dark';
|
||||
const { colorScheme } = useContext(ColorSchemeContext);
|
||||
|
||||
const blockNoteTheme = colorScheme === 'light' ? 'light' : 'dark';
|
||||
const getMentionItems = useMentionMenu(editor);
|
||||
|
||||
const handleFocus = () => {
|
||||
|
||||
+6
-6
@@ -1,8 +1,9 @@
|
||||
import { styled } from '@linaria/react';
|
||||
import { useContext } from 'react';
|
||||
import { type IconComponent } from 'twenty-ui/display';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
import {
|
||||
resolveThemeVariableAsNumber,
|
||||
themeCssVariables,
|
||||
} from 'twenty-ui/theme-constants';
|
||||
|
||||
const StyledContainer = styled.div<{ Variant: Variants }>`
|
||||
color: ${({ Variant }) =>
|
||||
@@ -28,12 +29,11 @@ export const CustomSideMenuOptions = ({
|
||||
Variant,
|
||||
text,
|
||||
}: CustomSideMenuOptionsProps) => {
|
||||
const { theme } = useContext(ThemeContext);
|
||||
return (
|
||||
<StyledContainer Variant={Variant}>
|
||||
<LeftIcon
|
||||
size={theme.icon.size.md}
|
||||
stroke={theme.icon.stroke.sm}
|
||||
size={resolveThemeVariableAsNumber(themeCssVariables.icon.size.md)}
|
||||
stroke={resolveThemeVariableAsNumber(themeCssVariables.icon.stroke.sm)}
|
||||
></LeftIcon>
|
||||
<StyledTextContainer>{text}</StyledTextContainer>
|
||||
</StyledContainer>
|
||||
|
||||
@@ -3,7 +3,7 @@ import React from 'react';
|
||||
import { Label } from 'twenty-ui/display';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
const StyledGroupHeading = styled(Label)`
|
||||
const StyledGroupHeadingContainer = styled.div`
|
||||
align-items: center;
|
||||
padding-bottom: ${themeCssVariables.spacing[1]};
|
||||
padding-left: ${themeCssVariables.spacing[1]};
|
||||
@@ -29,7 +29,9 @@ export const CommandGroup = ({ heading, children }: CommandGroupProps) => {
|
||||
}
|
||||
return (
|
||||
<>
|
||||
<StyledGroupHeading>{heading}</StyledGroupHeading>
|
||||
<StyledGroupHeadingContainer>
|
||||
<Label>{heading}</Label>
|
||||
</StyledGroupHeadingContainer>
|
||||
<StyledGroup>{children}</StyledGroup>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -19,7 +19,7 @@ const StyledNavigationIcon = styled.div`
|
||||
justify-content: center;
|
||||
`;
|
||||
|
||||
const StyledIconChevronLeft = styled(IconChevronLeft)`
|
||||
const StyledIconButtonContainer = styled.span`
|
||||
color: ${themeCssVariables.font.color.secondary};
|
||||
`;
|
||||
|
||||
@@ -52,12 +52,14 @@ export const CommandMenuBackButton = () => {
|
||||
<Dropdown
|
||||
clickableComponent={
|
||||
<StyledNavigationIcon onContextMenu={handleBackButtonContextMenu}>
|
||||
<IconButton
|
||||
Icon={StyledIconChevronLeft}
|
||||
size="small"
|
||||
variant="tertiary"
|
||||
onClick={goBackFromCommandMenu}
|
||||
/>
|
||||
<StyledIconButtonContainer>
|
||||
<IconButton
|
||||
Icon={IconChevronLeft}
|
||||
size="small"
|
||||
variant="tertiary"
|
||||
onClick={goBackFromCommandMenu}
|
||||
/>
|
||||
</StyledIconButtonContainer>
|
||||
</StyledNavigationIcon>
|
||||
}
|
||||
dropdownComponents={
|
||||
|
||||
+8
-8
@@ -4,10 +4,10 @@ import { useRecordChipData } from '@/object-record/hooks/useRecordChipData';
|
||||
import { type ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||
import { styled } from '@linaria/react';
|
||||
import { Avatar } from 'twenty-ui/display';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
import { useContext } from 'react';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
|
||||
import {
|
||||
resolveThemeVariableAsNumber,
|
||||
themeCssVariables,
|
||||
} from 'twenty-ui/theme-constants';
|
||||
const StyledIconWrapper = styled.div<{ withIconBackground?: boolean }>`
|
||||
background: ${({ withIconBackground }) =>
|
||||
withIconBackground ? themeCssVariables.background.primary : 'unset'};
|
||||
@@ -39,15 +39,15 @@ export const CommandMenuContextRecordChipAvatars = ({
|
||||
const { Icon, IconColor } = useGetStandardObjectIcon(
|
||||
objectMetadataItem.nameSingular,
|
||||
);
|
||||
|
||||
const { theme } = useContext(ThemeContext);
|
||||
|
||||
return (
|
||||
<StyledIconWrapper
|
||||
withIconBackground={recordChipData.avatarType !== 'rounded'}
|
||||
>
|
||||
{Icon ? (
|
||||
<Icon color={IconColor} size={theme.icon.size.sm} />
|
||||
<Icon
|
||||
color={IconColor}
|
||||
size={resolveThemeVariableAsNumber(themeCssVariables.icon.size.sm)}
|
||||
/>
|
||||
) : (
|
||||
<Avatar
|
||||
avatarUrl={recordChipData.avatarUrl}
|
||||
|
||||
+15
-13
@@ -25,7 +25,7 @@ type CommandMenuItemNumberInputProps = {
|
||||
placeholder?: string;
|
||||
};
|
||||
|
||||
const StyledRightAlignedTextInput = styled(TextInput)`
|
||||
const StyledRightAlignedTextInputContainer = styled.div`
|
||||
input {
|
||||
text-align: right;
|
||||
}
|
||||
@@ -132,18 +132,20 @@ export const CommandMenuItemNumberInput = ({
|
||||
Icon={Icon}
|
||||
onClick={focusInput}
|
||||
RightComponent={
|
||||
<StyledRightAlignedTextInput
|
||||
ref={inputRef}
|
||||
value={draftValue}
|
||||
sizeVariant="sm"
|
||||
onChange={handleChange}
|
||||
onFocus={handleFocus}
|
||||
onBlur={handleBlur}
|
||||
placeholder={placeholder}
|
||||
error={hasError ? ' ' : undefined}
|
||||
noErrorHelper
|
||||
textClickOutsideId={focusId}
|
||||
/>
|
||||
<StyledRightAlignedTextInputContainer>
|
||||
<TextInput
|
||||
ref={inputRef}
|
||||
value={draftValue}
|
||||
sizeVariant="sm"
|
||||
onChange={handleChange}
|
||||
onFocus={handleFocus}
|
||||
onBlur={handleBlur}
|
||||
placeholder={placeholder}
|
||||
error={hasError ? ' ' : undefined}
|
||||
noErrorHelper
|
||||
textClickOutsideId={focusId}
|
||||
/>
|
||||
</StyledRightAlignedTextInputContainer>
|
||||
}
|
||||
/>
|
||||
);
|
||||
|
||||
+13
-11
@@ -19,7 +19,7 @@ type CommandMenuItemTextInputProps = {
|
||||
placeholder?: string;
|
||||
};
|
||||
|
||||
const StyledRightAlignedTextInput = styled(TextInput)`
|
||||
const StyledRightAlignedTextInputContainer = styled.div`
|
||||
input {
|
||||
text-align: right;
|
||||
}
|
||||
@@ -96,16 +96,18 @@ export const CommandMenuItemTextInput = ({
|
||||
Icon={Icon}
|
||||
onClick={focusInput}
|
||||
RightComponent={
|
||||
<StyledRightAlignedTextInput
|
||||
ref={inputRef}
|
||||
value={draftValue}
|
||||
sizeVariant="sm"
|
||||
onChange={setDraftValue}
|
||||
onFocus={handleFocus}
|
||||
onBlur={handleBlur}
|
||||
placeholder={placeholder}
|
||||
textClickOutsideId={focusId}
|
||||
/>
|
||||
<StyledRightAlignedTextInputContainer>
|
||||
<TextInput
|
||||
ref={inputRef}
|
||||
value={draftValue}
|
||||
sizeVariant="sm"
|
||||
onChange={setDraftValue}
|
||||
onFocus={handleFocus}
|
||||
onBlur={handleBlur}
|
||||
placeholder={placeholder}
|
||||
textClickOutsideId={focusId}
|
||||
/>
|
||||
</StyledRightAlignedTextInputContainer>
|
||||
}
|
||||
/>
|
||||
);
|
||||
|
||||
+14
-6
@@ -4,8 +4,11 @@ import { getActionLabel } from '@/action-menu/utils/getActionLabel';
|
||||
import { CommandMenuPageInfoLayout } from '@/command-menu/components/CommandMenuPageInfoLayout';
|
||||
import { useFindManyRecordsSelectedInContextStore } from '@/context-store/hooks/useFindManyRecordsSelectedInContextStore';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { useContext } from 'react';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
import {
|
||||
resolveThemeVariable,
|
||||
resolveThemeVariableAsNumber,
|
||||
themeCssVariables,
|
||||
} from 'twenty-ui/theme-constants';
|
||||
|
||||
type CommandMenuMultipleRecordsInfoProps = {
|
||||
commandMenuPageInstanceId: string;
|
||||
@@ -14,8 +17,6 @@ type CommandMenuMultipleRecordsInfoProps = {
|
||||
export const CommandMenuMultipleRecordsInfo = ({
|
||||
commandMenuPageInstanceId,
|
||||
}: CommandMenuMultipleRecordsInfoProps) => {
|
||||
const { theme } = useContext(ThemeContext);
|
||||
|
||||
const { totalCount } = useFindManyRecordsSelectedInContextStore({
|
||||
instanceId: commandMenuPageInstanceId,
|
||||
limit: 1,
|
||||
@@ -26,8 +27,15 @@ export const CommandMenuMultipleRecordsInfo = ({
|
||||
|
||||
return (
|
||||
<CommandMenuPageInfoLayout
|
||||
icon={<Icon size={theme.icon.size.md} stroke={theme.icon.stroke.sm} />}
|
||||
iconColor={theme.font.color.tertiary}
|
||||
icon={
|
||||
<Icon
|
||||
size={resolveThemeVariableAsNumber(themeCssVariables.icon.size.md)}
|
||||
stroke={resolveThemeVariableAsNumber(
|
||||
themeCssVariables.icon.stroke.sm,
|
||||
)}
|
||||
/>
|
||||
}
|
||||
iconColor={resolveThemeVariable(themeCssVariables.font.color.tertiary)}
|
||||
title={getActionLabel(label)}
|
||||
label={t`${totalCount} selected`}
|
||||
/>
|
||||
|
||||
+10
-8
@@ -20,12 +20,13 @@ import { WORKFLOW_DIAGRAM_EDGE_OPTIONS_CLICK_OUTSIDE_ID } from '@/workflow/workf
|
||||
|
||||
import { styled } from '@linaria/react';
|
||||
import { motion } from 'framer-motion';
|
||||
import { useCallback, useContext, useRef } from 'react';
|
||||
import { useCallback, useRef } from 'react';
|
||||
import { LINK_CHIP_CLICK_OUTSIDE_ID } from 'twenty-ui/components';
|
||||
import { useIsMobile } from 'twenty-ui/utilities';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
|
||||
import {
|
||||
themeCssVariables,
|
||||
resolveThemeVariable,
|
||||
} from 'twenty-ui/theme-constants';
|
||||
const StyledCommandMenuBase = styled.div`
|
||||
background: ${themeCssVariables.background.primary};
|
||||
border-left: 1px solid ${themeCssVariables.border.color.medium};
|
||||
@@ -51,9 +52,6 @@ export const CommandMenuOpenContainer = ({
|
||||
const targetVariantForAnimation: CommandMenuAnimationVariant = isMobile
|
||||
? 'fullScreen'
|
||||
: 'normal';
|
||||
|
||||
const { theme } = useContext(ThemeContext);
|
||||
|
||||
const { closeCommandMenu } = useCommandMenu();
|
||||
|
||||
const commandMenuRef = useRef<HTMLDivElement>(null);
|
||||
@@ -100,7 +98,11 @@ export const CommandMenuOpenContainer = ({
|
||||
initial="closed"
|
||||
exit="closed"
|
||||
variants={COMMAND_MENU_ANIMATION_VARIANTS}
|
||||
transition={{ duration: theme.animation.duration.normal }}
|
||||
transition={{
|
||||
duration: resolveThemeVariable(
|
||||
themeCssVariables.animation.duration.normal,
|
||||
),
|
||||
}}
|
||||
onAnimationStart={() => setIsSidePanelAnimating(true)}
|
||||
onAnimationComplete={() => setIsSidePanelAnimating(false)}
|
||||
>
|
||||
|
||||
@@ -21,10 +21,11 @@ import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomState
|
||||
import { CommandMenuPages } from 'twenty-shared/types';
|
||||
|
||||
import { type CommandMenuContextChipProps } from './CommandMenuContextChip';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
import { useContext } from 'react';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
|
||||
import {
|
||||
resolveThemeVariable,
|
||||
resolveThemeVariableAsNumber,
|
||||
themeCssVariables,
|
||||
} from 'twenty-ui/theme-constants';
|
||||
const StyledPageTitle = styled.div`
|
||||
color: ${themeCssVariables.font.color.primary};
|
||||
font-size: ${themeCssVariables.font.size.sm};
|
||||
@@ -36,7 +37,6 @@ type CommandMenuPageInfoProps = {
|
||||
};
|
||||
|
||||
export const CommandMenuPageInfo = ({ pageChip }: CommandMenuPageInfoProps) => {
|
||||
const { theme } = useContext(ThemeContext);
|
||||
const selectedNavigationMenuItemInEditMode = useAtomStateValue(
|
||||
selectedNavigationMenuItemInEditModeState,
|
||||
);
|
||||
@@ -134,8 +134,8 @@ export const CommandMenuPageInfo = ({ pageChip }: CommandMenuPageInfoProps) => {
|
||||
<CommandMenuPageInfoLayout
|
||||
icon={
|
||||
<IconColumnInsertRight
|
||||
size={theme.icon.size.md}
|
||||
color={theme.font.color.tertiary}
|
||||
size={resolveThemeVariableAsNumber(themeCssVariables.icon.size.md)}
|
||||
color={resolveThemeVariable(themeCssVariables.font.color.tertiary)}
|
||||
/>
|
||||
}
|
||||
title={<OverflowingTextWithTooltip text={pageChip.text ?? ''} />}
|
||||
|
||||
+11
-5
@@ -13,19 +13,20 @@ import { useAtomComponentState } from '@/ui/utilities/state/jotai/hooks/useAtomC
|
||||
import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue';
|
||||
import { isNonEmptyString } from '@sniptt/guards';
|
||||
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
|
||||
import { useContext, useState } from 'react';
|
||||
import { useState } from 'react';
|
||||
import { CommandMenuPages } from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { useIcons } from 'twenty-ui/display';
|
||||
import { CommandMenuPageInfoLayout } from './CommandMenuPageInfoLayout';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
|
||||
import {
|
||||
resolveThemeVariableAsNumber,
|
||||
themeCssVariables,
|
||||
} from 'twenty-ui/theme-constants';
|
||||
export const CommandMenuPageLayoutInfoContent = ({
|
||||
pageLayoutId,
|
||||
}: {
|
||||
pageLayoutId: string;
|
||||
}) => {
|
||||
const { theme } = useContext(ThemeContext);
|
||||
const { getIcon } = useIcons();
|
||||
const commandMenuPage = useAtomStateValue(commandMenuPageState);
|
||||
const commandMenuPageInfo = useAtomStateValue(commandMenuPageInfoState);
|
||||
@@ -121,7 +122,12 @@ export const CommandMenuPageLayoutInfoContent = ({
|
||||
<CommandMenuPageInfoLayout
|
||||
icon={
|
||||
isDefined(headerIcon) ? (
|
||||
<Icon size={theme.icon.size.md} stroke={theme.icon.stroke.sm} />
|
||||
<Icon
|
||||
size={resolveThemeVariableAsNumber(themeCssVariables.icon.size.md)}
|
||||
stroke={resolveThemeVariableAsNumber(
|
||||
themeCssVariables.icon.stroke.sm,
|
||||
)}
|
||||
/>
|
||||
) : undefined
|
||||
}
|
||||
iconColor={headerIconColor}
|
||||
|
||||
@@ -9,8 +9,10 @@ import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomState
|
||||
import { styled } from '@linaria/react';
|
||||
import { motion } from 'framer-motion';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { useContext } from 'react';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
import {
|
||||
resolveThemeVariable,
|
||||
themeCssVariables,
|
||||
} from 'twenty-ui/theme-constants';
|
||||
|
||||
const StyledCommandMenuContent = styled.div`
|
||||
flex: 1;
|
||||
@@ -26,9 +28,6 @@ export const CommandMenuRouter = () => {
|
||||
) : (
|
||||
<></>
|
||||
);
|
||||
|
||||
const { theme } = useContext(ThemeContext);
|
||||
|
||||
return (
|
||||
<CommandMenuContainer>
|
||||
<CommandMenuPageComponentInstanceContext.Provider
|
||||
@@ -39,7 +38,9 @@ export const CommandMenuRouter = () => {
|
||||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
transition={{
|
||||
duration: theme.animation.duration.instant,
|
||||
duration: resolveThemeVariable(
|
||||
themeCssVariables.animation.duration.instant,
|
||||
),
|
||||
delay: 0.1,
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -18,13 +18,15 @@ import { useLingui } from '@lingui/react/macro';
|
||||
import { AnimatePresence, motion } from 'framer-motion';
|
||||
import { useAtomState } from '@/ui/utilities/state/jotai/hooks/useAtomState';
|
||||
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
|
||||
import { useContext, useRef } from 'react';
|
||||
import { useRef } from 'react';
|
||||
import { CommandMenuPages } from 'twenty-shared/types';
|
||||
import { IconX } from 'twenty-ui/display';
|
||||
import { IconButton } from 'twenty-ui/input';
|
||||
import { useIsMobile } from 'twenty-ui/utilities';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
import {
|
||||
resolveThemeVariableAsNumber,
|
||||
themeCssVariables,
|
||||
} from 'twenty-ui/theme-constants';
|
||||
|
||||
const StyledInputContainer = styled.div<{ isMobile: boolean }>`
|
||||
align-items: center;
|
||||
@@ -101,8 +103,6 @@ export const CommandMenuTopBar = () => {
|
||||
commandMenuNavigationStackState,
|
||||
);
|
||||
|
||||
const { theme } = useContext(ThemeContext);
|
||||
|
||||
const { contextChips } = useCommandMenuContextChips();
|
||||
|
||||
const { pushFocusItemToFocusStack } = usePushFocusItemToFocusStack();
|
||||
@@ -145,7 +145,9 @@ export const CommandMenuTopBar = () => {
|
||||
<motion.div
|
||||
exit={{ opacity: 0, width: 0 }}
|
||||
transition={{
|
||||
duration: theme.animation.duration.instant,
|
||||
duration: resolveThemeVariableAsNumber(
|
||||
themeCssVariables.animation.duration.instant,
|
||||
),
|
||||
}}
|
||||
>
|
||||
<CommandMenuBackButton />
|
||||
@@ -155,7 +157,9 @@ export const CommandMenuTopBar = () => {
|
||||
<motion.div
|
||||
exit={{ opacity: 0, width: 0 }}
|
||||
transition={{
|
||||
duration: theme.animation.duration.instant,
|
||||
duration: resolveThemeVariableAsNumber(
|
||||
themeCssVariables.animation.duration.instant,
|
||||
),
|
||||
}}
|
||||
>
|
||||
<IconButton
|
||||
|
||||
+18
-14
@@ -13,7 +13,7 @@ import { FeatureFlagKey } from '~/generated-metadata/graphql';
|
||||
import { useCreateNewAIChatThread } from '@/ai/hooks/useCreateNewAIChatThread';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
const StyledIconButton = styled(IconButton)`
|
||||
const StyledIconButtonContainer = styled.span`
|
||||
color: ${themeCssVariables.font.color.secondary};
|
||||
`;
|
||||
|
||||
@@ -35,22 +35,26 @@ export const CommandMenuTopBarRightCornerIcon = () => {
|
||||
|
||||
if (!isOnAskAIPage) {
|
||||
return (
|
||||
<StyledIconButton
|
||||
onClick={() => openAskAIPage({ resetNavigationStack: false })}
|
||||
Icon={IconSparkles}
|
||||
variant="tertiary"
|
||||
size="small"
|
||||
/>
|
||||
<StyledIconButtonContainer>
|
||||
<IconButton
|
||||
onClick={() => openAskAIPage({ resetNavigationStack: false })}
|
||||
Icon={IconSparkles}
|
||||
variant="tertiary"
|
||||
size="small"
|
||||
/>
|
||||
</StyledIconButtonContainer>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<StyledIconButton
|
||||
Icon={IconEdit}
|
||||
size="small"
|
||||
variant="tertiary"
|
||||
onClick={() => createChatThread()}
|
||||
ariaLabel={t`New conversation`}
|
||||
/>
|
||||
<StyledIconButtonContainer>
|
||||
<IconButton
|
||||
Icon={IconEdit}
|
||||
size="small"
|
||||
variant="tertiary"
|
||||
onClick={() => createChatThread()}
|
||||
ariaLabel={t`New conversation`}
|
||||
/>
|
||||
</StyledIconButtonContainer>
|
||||
);
|
||||
};
|
||||
|
||||
+10
-2
@@ -23,8 +23,11 @@ import { CommandMenuPages, CoreObjectNameSingular } from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { TRIGGER_STEP_ID } from 'twenty-shared/workflow';
|
||||
import { useIcons } from 'twenty-ui/display';
|
||||
import { ICON_SIZES, ICON_STROKES } from 'twenty-ui/theme-constants';
|
||||
import { CommandMenuPageInfoLayout } from './CommandMenuPageInfoLayout';
|
||||
import {
|
||||
resolveThemeVariableAsNumber,
|
||||
themeCssVariables,
|
||||
} from 'twenty-ui/theme-constants';
|
||||
|
||||
export const CommandMenuWorkflowStepInfo = ({
|
||||
commandMenuPageInstanceId,
|
||||
@@ -169,7 +172,12 @@ export const CommandMenuWorkflowStepInfo = ({
|
||||
<CommandMenuPageInfoLayout
|
||||
icon={
|
||||
headerIcon ? (
|
||||
<Icon size={ICON_SIZES.md} stroke={ICON_STROKES.sm} />
|
||||
<Icon
|
||||
size={resolveThemeVariableAsNumber(themeCssVariables.icon.size.md)}
|
||||
stroke={resolveThemeVariableAsNumber(
|
||||
themeCssVariables.icon.stroke.sm,
|
||||
)}
|
||||
/>
|
||||
) : undefined
|
||||
}
|
||||
iconColor={headerIconColor}
|
||||
|
||||
+5
-4
@@ -13,8 +13,10 @@ import {
|
||||
IconPlus,
|
||||
type IconComponent,
|
||||
} from 'twenty-ui/display';
|
||||
import { useContext } from 'react';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
import {
|
||||
resolveThemeVariable,
|
||||
themeCssVariables,
|
||||
} from 'twenty-ui/theme-constants';
|
||||
|
||||
type PageLayoutHeaderInfo = {
|
||||
headerIcon: IconComponent | undefined;
|
||||
@@ -43,8 +45,7 @@ export const usePageLayoutHeaderInfo = ({
|
||||
openTabId,
|
||||
editedTitle,
|
||||
}: UsePageLayoutHeaderInfoParams): PageLayoutHeaderInfo | null => {
|
||||
const { theme } = useContext(ThemeContext);
|
||||
const iconColor = theme.font.color.tertiary;
|
||||
const iconColor = resolveThemeVariable(themeCssVariables.font.color.tertiary);
|
||||
|
||||
switch (commandMenuPage) {
|
||||
case CommandMenuPages.PageLayoutTabSettings: {
|
||||
|
||||
+7
-3
@@ -1,4 +1,8 @@
|
||||
import { THEME_COMMON } from 'twenty-ui/theme';
|
||||
import {
|
||||
resolveThemeVariable,
|
||||
themeCssVariables,
|
||||
} from 'twenty-ui/theme-constants';
|
||||
|
||||
export const COMMAND_MENU_ANIMATION_VARIANTS = {
|
||||
fullScreen: {
|
||||
x: '0%',
|
||||
@@ -9,14 +13,14 @@ export const COMMAND_MENU_ANIMATION_VARIANTS = {
|
||||
},
|
||||
normal: {
|
||||
x: '0%',
|
||||
width: THEME_COMMON.rightDrawerWidth,
|
||||
width: resolveThemeVariable(themeCssVariables.rightDrawerWidth),
|
||||
height: '100%',
|
||||
bottom: '0',
|
||||
top: '0',
|
||||
},
|
||||
closed: {
|
||||
x: '100%',
|
||||
width: THEME_COMMON.rightDrawerWidth,
|
||||
width: resolveThemeVariable(themeCssVariables.rightDrawerWidth),
|
||||
height: '100%',
|
||||
bottom: '0',
|
||||
top: 'auto',
|
||||
|
||||
+19
-9
@@ -9,10 +9,14 @@ import { recordStoreIdentifiersFamilySelector } from '@/object-record/record-sto
|
||||
import { recordStoreRecordsSelector } from '@/object-record/record-store/states/selectors/recordStoreRecordsSelector';
|
||||
import { useAtomFamilySelectorValue } from '@/ui/utilities/state/jotai/hooks/useAtomFamilySelectorValue';
|
||||
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
|
||||
import { useContext, useMemo } from 'react';
|
||||
import { useMemo } from 'react';
|
||||
import { CommandMenuPages } from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
import {
|
||||
resolveThemeVariable,
|
||||
resolveThemeVariableAsNumber,
|
||||
themeCssVariables,
|
||||
} from 'twenty-ui/theme-constants';
|
||||
|
||||
export const useCommandMenuContextChips = () => {
|
||||
const commandMenuNavigationStack = useAtomStateValue(
|
||||
@@ -27,8 +31,6 @@ export const useCommandMenuContextChips = () => {
|
||||
|
||||
const { navigateCommandMenuHistory } = useCommandMenuHistory();
|
||||
|
||||
const { theme } = useContext(ThemeContext);
|
||||
|
||||
const commandMenuNavigationMorphItemsByPage = useAtomStateValue(
|
||||
commandMenuNavigationMorphItemsByPageState,
|
||||
);
|
||||
@@ -111,16 +113,26 @@ export const useCommandMenuContextChips = () => {
|
||||
return {
|
||||
page,
|
||||
Icons: isLastChip
|
||||
? [<page.pageIcon size={theme.icon.size.sm} />]
|
||||
? [
|
||||
<page.pageIcon
|
||||
size={resolveThemeVariableAsNumber(
|
||||
themeCssVariables.icon.size.sm,
|
||||
)}
|
||||
/>,
|
||||
]
|
||||
: [
|
||||
<CommandMenuContextChipIconWrapper>
|
||||
<page.pageIcon
|
||||
size={theme.icon.size.sm}
|
||||
size={resolveThemeVariableAsNumber(
|
||||
themeCssVariables.icon.size.sm,
|
||||
)}
|
||||
color={
|
||||
isDefined(page.pageIconColor) &&
|
||||
page.pageIconColor !== 'currentColor'
|
||||
? page.pageIconColor
|
||||
: theme.font.color.tertiary
|
||||
: resolveThemeVariable(
|
||||
themeCssVariables.font.color.tertiary,
|
||||
)
|
||||
}
|
||||
/>
|
||||
</CommandMenuContextChipIconWrapper>,
|
||||
@@ -141,8 +153,6 @@ export const useCommandMenuContextChips = () => {
|
||||
objectMetadataItems,
|
||||
recordIdentifiers,
|
||||
records,
|
||||
theme.font.color.tertiary,
|
||||
theme.icon.size.sm,
|
||||
]);
|
||||
|
||||
return {
|
||||
|
||||
+5
-3
@@ -15,9 +15,11 @@ import {
|
||||
DEFAULT_COLOR_LABELS,
|
||||
MenuItemSelectColor,
|
||||
} from 'twenty-ui/navigation';
|
||||
import { MAIN_COLOR_NAMES, type ThemeColor } from 'twenty-ui/theme';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
import {
|
||||
type ThemeColor,
|
||||
MAIN_COLOR_NAMES,
|
||||
themeCssVariables,
|
||||
} from 'twenty-ui/theme-constants';
|
||||
const NAVIGATION_MENU_ITEM_COLOR_DROPDOWN_ID = 'navigation-menu-item-color';
|
||||
|
||||
const StyledMenuStyleText = styled.span`
|
||||
|
||||
+7
-4
@@ -18,8 +18,10 @@ import { useAddLinkToNavigationMenu } from '@/command-menu/pages/navigation-menu
|
||||
import { NavigationMenuItemStyleIcon } from '@/navigation-menu-item/components/NavigationMenuItemStyleIcon';
|
||||
import { NavigationMenuItemType } from '@/navigation-menu-item/constants/NavigationMenuItemType';
|
||||
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
|
||||
import { useContext } from 'react';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
import {
|
||||
resolveThemeVariable,
|
||||
themeCssVariables,
|
||||
} from 'twenty-ui/theme-constants';
|
||||
|
||||
type CommandMenuNewSidebarItemMainMenuProps = {
|
||||
onSelectObject: () => void;
|
||||
@@ -33,7 +35,6 @@ export const CommandMenuNewSidebarItemMainMenu = ({
|
||||
onSelectRecord,
|
||||
}: CommandMenuNewSidebarItemMainMenuProps) => {
|
||||
const { t } = useLingui();
|
||||
const { theme } = useContext(ThemeContext);
|
||||
const { handleAddFolder } = useAddFolderToNavigationMenu();
|
||||
const { handleAddLink } = useAddLinkToNavigationMenu();
|
||||
|
||||
@@ -86,7 +87,9 @@ export const CommandMenuNewSidebarItemMainMenu = ({
|
||||
<Avatar
|
||||
placeholder="L"
|
||||
type="rounded"
|
||||
backgroundColor={theme.color.green4}
|
||||
backgroundColor={resolveThemeVariable(
|
||||
themeCssVariables.color.green4,
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
label={t`Record`}
|
||||
|
||||
+1
-3
@@ -5,9 +5,7 @@ import { SelectableListItem } from '@/ui/layout/selectable-list/components/Selec
|
||||
import { styled } from '@linaria/react';
|
||||
import { ColorSample } from 'twenty-ui/display';
|
||||
import { MenuItemSelect } from 'twenty-ui/navigation';
|
||||
import { type ThemeColor } from 'twenty-ui/theme';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
import { type ThemeColor, themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
type ChartColorGradientOptionProps = {
|
||||
colorOption: {
|
||||
id: string;
|
||||
|
||||
+1
-3
@@ -6,10 +6,8 @@ import { styled } from '@linaria/react';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { ColorSample } from 'twenty-ui/display';
|
||||
import { MenuItemSelect } from 'twenty-ui/navigation';
|
||||
import { type ThemeColor } from 'twenty-ui/theme';
|
||||
import { getMainColorNameFromPaletteColorName } from 'twenty-ui/utilities';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
|
||||
import { type ThemeColor, themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
type ChartColorPaletteOptionProps = {
|
||||
selectedItemId: string | null;
|
||||
currentColor: string | null | undefined;
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@ import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/use
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { useState } from 'react';
|
||||
import { capitalize, isDefined } from 'twenty-shared/utils';
|
||||
import { MAIN_COLOR_NAMES, type ThemeColor } from 'twenty-ui/theme';
|
||||
import { type ThemeColor, MAIN_COLOR_NAMES } from 'twenty-ui/theme-constants';
|
||||
import { filterBySearchQuery } from '~/utils/filterBySearchQuery';
|
||||
|
||||
type ColorOption = {
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@ import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states
|
||||
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
|
||||
import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue';
|
||||
import { MenuItemSelectTag } from 'twenty-ui/navigation';
|
||||
import { type ThemeColor } from 'twenty-ui/theme';
|
||||
import { type ThemeColor } from 'twenty-ui/theme-constants';
|
||||
import { AggregateOperations } from '~/generated-metadata/graphql';
|
||||
|
||||
export const ChartRatioOptionSelectSelectableListItem = ({
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@ import { t } from '@lingui/core/macro';
|
||||
import { useState } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { IconChevronLeft } from 'twenty-ui/display';
|
||||
import { type ThemeColor } from 'twenty-ui/theme';
|
||||
import { type ThemeColor } from 'twenty-ui/theme-constants';
|
||||
import { FieldMetadataType } from '~/generated-metadata/graphql';
|
||||
import { filterBySearchQuery } from '~/utils/filterBySearchQuery';
|
||||
|
||||
|
||||
+10
-8
@@ -2,11 +2,13 @@ import { SKELETON_LOADER_HEIGHT_SIZES } from '@/activities/components/SkeletonLo
|
||||
import { viewableRichTextComponentState } from '@/command-menu/pages/rich-text-page/states/viewableRichTextComponentState';
|
||||
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
|
||||
import { styled } from '@linaria/react';
|
||||
import { lazy, Suspense, useContext } from 'react';
|
||||
import { lazy, Suspense } from 'react';
|
||||
import Skeleton, { SkeletonTheme } from 'react-loading-skeleton';
|
||||
import { CoreObjectNameSingular } from 'twenty-shared/types';
|
||||
import { ThemeContext } from 'twenty-ui/theme';
|
||||
import { themeCssVariables } from 'twenty-ui/theme-constants';
|
||||
import {
|
||||
themeCssVariables,
|
||||
resolveThemeVariable,
|
||||
} from 'twenty-ui/theme-constants';
|
||||
|
||||
const ActivityRichTextEditor = lazy(() =>
|
||||
import('@/activities/components/ActivityRichTextEditor').then((module) => ({
|
||||
@@ -22,13 +24,13 @@ const StyledContainer = styled.div`
|
||||
`;
|
||||
|
||||
const LoadingSkeleton = () => {
|
||||
const { theme } = useContext(ThemeContext);
|
||||
|
||||
return (
|
||||
<SkeletonTheme
|
||||
baseColor={theme.background.tertiary}
|
||||
highlightColor={theme.background.transparent.lighter}
|
||||
borderRadius={theme.border.radius.sm}
|
||||
baseColor={resolveThemeVariable(themeCssVariables.background.tertiary)}
|
||||
highlightColor={resolveThemeVariable(
|
||||
themeCssVariables.background.transparent.lighter,
|
||||
)}
|
||||
borderRadius={resolveThemeVariable(themeCssVariables.border.radius.sm)}
|
||||
>
|
||||
<Skeleton height={SKELETON_LOADER_HEIGHT_SIZES.standard.s} />
|
||||
</SkeletonTheme>
|
||||
|
||||
+14
-8
@@ -35,9 +35,11 @@ const StyledContainer = styled.div`
|
||||
height: 100%;
|
||||
`;
|
||||
|
||||
const StyledTabList = styled(TabList)`
|
||||
background-color: ${themeCssVariables.background.secondary};
|
||||
padding-left: ${themeCssVariables.spacing[2]};
|
||||
const StyledTabListContainer = styled.div`
|
||||
& > div {
|
||||
background-color: ${themeCssVariables.background.secondary};
|
||||
padding-left: ${themeCssVariables.spacing[2]};
|
||||
}
|
||||
`;
|
||||
|
||||
type TabId = WorkflowRunTabIdType;
|
||||
@@ -131,11 +133,15 @@ export const CommandMenuWorkflowRunViewStepContent = () => {
|
||||
/>
|
||||
) : (
|
||||
<>
|
||||
<StyledTabList
|
||||
tabs={tabs}
|
||||
behaveAsLinks={false}
|
||||
componentInstanceId={commandMenuPageComponentInstance.instanceId}
|
||||
/>
|
||||
<StyledTabListContainer>
|
||||
<TabList
|
||||
tabs={tabs}
|
||||
behaveAsLinks={false}
|
||||
componentInstanceId={
|
||||
commandMenuPageComponentInstance.instanceId
|
||||
}
|
||||
/>
|
||||
</StyledTabListContainer>
|
||||
|
||||
{activeTabId === WorkflowRunTabId.OUTPUT ? (
|
||||
<WorkflowRunStepOutputDetail
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user