Skip to content
This repository has been archived by the owner on Nov 7, 2022. It is now read-only.

Commit

Permalink
fix(formula): runtime error i18n support
Browse files Browse the repository at this point in the history
  • Loading branch information
shiyuhang committed Jul 19, 2022
1 parent 1c4555a commit 74a4354
Show file tree
Hide file tree
Showing 46 changed files with 266 additions and 140 deletions.
8 changes: 6 additions & 2 deletions apps/client-web/src/docs_legacy/pages/DocumentContentPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,12 @@ import { useFormulaActions } from './hooks/useFormulaActions'
import { AppError404 } from '@/routes/_shared/AppError'
import { type DocMeta, DocMetaProvider } from '../store/DocMeta'
import { MashcardEventBus, BlockMetaUpdated, ReloadDocument } from '@mashcard/schema'
import { formulaI18n } from '@mashcard/editor/src/helpers'
import { useFormulaI18n } from '@mashcard/editor/src/hooks/useFormulaI18n'

export const DocumentContentPage: FC = () => {
const { t } = useDocsI18n()
const { t: formulaT } = useFormulaI18n()
const { domain, docId, historyId } = useParams() as unknown as {
domain: string
docId?: string
Expand Down Expand Up @@ -141,8 +144,9 @@ export const DocumentContentPage: FC = () => {

useEffect(() => {
const functionClauses = generateFormulaFunctionClauses()
const formulaContext = FormulaContext.getInstance({
domain,
const formulaContext = FormulaContext.getFormulaInstance({
username: domain,
i18n: formulaI18n(formulaT),
backendActions: { commit: commitFormula },
functionClauses,
features: featureFlags
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -759,7 +759,7 @@ exports[`FormulaDisplay [partial error 2] basic "=custom::ADD(1)" 2`] = `
class="mashcard-formula-borderless"
style="color: rgb(207, 31, 40);"
>
#<Error> errors.parse.not_found.function,[object Object]
#<Error> errors.parse.not_found.function {"key":"custom::ADD"}
</span>
</span>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2410,7 +2410,7 @@ exports[`FormulaResult chain "={a:1}.b" -> [object Object] 1`] = `
class="mashcard-formula-borderless"
style="color: rgb(207, 31, 40);"
>
#&lt;Error&gt; errors.interpret.not_found.key,[object Object]
#&lt;Error&gt; errors.interpret.not_found.key {"key":"b"}
</span>
<span
class="formula-result-ok-icon"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1025,7 +1025,7 @@ exports[`FormulaValue [partial error 2] basic "=custom::ADD(1)" 1`] = `
class="mashcard-formula-borderless"
style="color: rgb(207, 31, 40);"
>
#&lt;Error&gt; errors.parse.not_found.function,[object Object]
#&lt;Error&gt; errors.parse.not_found.function {"key":"custom::ADD"}
</span>
</div>
`;
Expand Down Expand Up @@ -1063,7 +1063,7 @@ exports[`FormulaValue [partial error 2] basic "=custom::ADD(1)" 3`] = `
class="mashcard-formula-borderless"
style="color: rgb(207, 31, 40);"
>
#&lt;Error&gt; errors.parse.not_found.function,[object Object]
#&lt;Error&gt; errors.parse.not_found.function {"key":"custom::ADD"}
</span>
</div>
`;
Expand All @@ -1074,7 +1074,7 @@ exports[`FormulaValue [partial error 2] basic "=custom::ADD(1)" 4`] = `
class="mashcard-formula-borderless"
style="color: rgb(207, 31, 40);"
>
#&lt;Error&gt; errors.parse.not_found.function,[object Object]
#&lt;Error&gt; errors.parse.not_found.function {"key":"custom::ADD"}
</span>
</div>
`;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -505,12 +505,12 @@ export const useFormula = ({
setReferences(e.payload.meta)
},
{
eventId: `${formulaContext?.domain}#${namespaceId},${variableId}`,
eventId: `${formulaContext?.username}#${namespaceId},${variableId}`,
subscribeId: `UseFormula#${namespaceId},${variableId}`
}
)
return () => listener.unsubscribe()
}, [formulaContext?.domain, namespaceId, variableId])
}, [formulaContext?.username, namespaceId, variableId])

React.useEffect(() => {
const listener = MashcardEventBus.subscribe(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ export const SpreadsheetCell: React.FC<SpreadsheetCellProps> = ({
async (variable: VariableInterface | undefined): Promise<void> => {
if (!variable) return
// TODO check no persist
const value = display(fetchResult(variable.t)).result
const value = display(fetchResult(variable.t), formulaContext!).result
const oldValue = block.text
if (value === oldValue) return
devLog('Spreadsheet cell formula updated', { cellId, value, rootId })
Expand All @@ -98,7 +98,7 @@ export const SpreadsheetCell: React.FC<SpreadsheetCellProps> = ({
},
meta: null,
namespaceId: rootId,
username: formulaContext.domain,
username: formulaContext.username,
key: variable?.currentUUID ?? tableId
})
)
Expand Down Expand Up @@ -194,7 +194,9 @@ export const SpreadsheetCell: React.FC<SpreadsheetCellProps> = ({
latestEditing.current = false
}

const displayResult = savedVariableT ? display(fetchResult(savedVariableT)).result : currentBlock.text
const displayResult = savedVariableT
? display(fetchResult(savedVariableT), formulaContext!).result
: currentBlock.text
const fallbackDisplayData: VariableDisplayData | undefined = displayResult
? {
definition: displayResult,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
SpreadsheetCellContainer,
SpreadsheetColumnEditable
} from './SpreadsheetView'
import { display, VariableDisplayData } from '@mashcard/formula'
import { display, SpreadsheetType, VariableDisplayData } from '@mashcard/formula'
import React from 'react'
import { FormulaDisplay } from '../../ui/Formula'
import { styled } from '@mashcard/design-system'
Expand All @@ -29,7 +29,7 @@ export interface Column {
}

export interface SpreadsheetRenderProps {
title: string
spreadsheet: SpreadsheetType
rows: Row[]
valuesMatrix: Map<string, Map<string, VariableDisplayData | undefined>>
columns: Column[]
Expand All @@ -38,7 +38,7 @@ export interface SpreadsheetRenderProps {

export const SpreadsheetRender: React.FC<SpreadsheetRenderProps> = ({
rows,
title,
spreadsheet,
columns,
valuesMatrix,
defaultSelection
Expand All @@ -56,7 +56,7 @@ export const SpreadsheetRender: React.FC<SpreadsheetRenderProps> = ({
new Map(
columns.map(c => {
const displayData = valuesMatrix.get(rowId)?.get(c.columnId)
return [c.columnId, displayData ? display(displayData.result).result : '']
return [c.columnId, displayData ? display(displayData.result, spreadsheet._formulaContext).result : '']
})
)
]
Expand Down Expand Up @@ -99,7 +99,8 @@ export const SpreadsheetRender: React.FC<SpreadsheetRenderProps> = ({
context={spreadsheetContext}
columnId={column.columnId}
columnActions={[]}
draggable={false}>
draggable={false}
>
<SpreadsheetColumnEditable
context={spreadsheetContext}
index={i}
Expand All @@ -119,7 +120,8 @@ export const SpreadsheetRender: React.FC<SpreadsheetRenderProps> = ({
<SpreadsheetCellContainer
key={column.columnId}
context={spreadsheetContext}
cellId={{ rowId: rowBlock.rowId, columnId: column.columnId }}>
cellId={{ rowId: rowBlock.rowId, columnId: column.columnId }}
>
<div className="cell">
<FormulaDisplay
displayData={valuesMatrix.get(rowBlock.rowId)?.get(column.columnId)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,28 +65,28 @@ export function useFormulaSpreadsheet({
spreadsheetId,
title,
namespaceId: rootId,
username: formulaContext?.domain
username: formulaContext?.username
})
}, [formulaContext?.domain, rootId, spreadsheetId, title])
}, [formulaContext?.username, rootId, spreadsheetId, title])

React.useEffect(() => {
// TODO: remove this when switch pages
void dispatchFormulaSpreadsheetRowChange({
spreadsheetId,
namespaceId: rootId,
rows: rowData,
username: formulaContext?.domain
username: formulaContext?.username
})
}, [rootId, spreadsheetId, rowData, formulaContext?.domain])
}, [rootId, spreadsheetId, rowData, formulaContext?.username])

React.useEffect(() => {
void dispatchFormulaSpreadsheetColumnChange({
spreadsheetId,
namespaceId: rootId,
columns: columnData,
username: formulaContext?.domain
username: formulaContext?.username
})
}, [rootId, spreadsheetId, columnData, formulaContext?.domain])
}, [rootId, spreadsheetId, columnData, formulaContext?.username])

React.useEffect(() => {
if (!formulaContext) return
Expand Down Expand Up @@ -123,7 +123,7 @@ export function useFormulaSpreadsheet({

return {
deleteSpreadsheet: () => {
void dispatchFormulaSpreadsheetRemove({ id: spreadsheetId, username: formulaContext?.domain })
void dispatchFormulaSpreadsheetRemove({ id: spreadsheetId, username: formulaContext?.username })
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ describe('AutocompleteList', () => {
})

it('renders variable kind correctly', async () => {
const formulaContext = FormulaContext.getInstance({ domain: 'test' })
const formulaContext = FormulaContext.getFormulaInstance({ username: 'test' })
const interpretContext = { ctx: {}, arguments: [] }

const namespaceId = '37198be0-d10d-42dc-ae8b-20d45a95401b'
Expand Down
9 changes: 2 additions & 7 deletions packages/editor/src/components/ui/Formula/FormulaError.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { FC } from 'react'
import { ErrorMessage } from '@mashcard/formula'
import { formulaI18n } from '../../../helpers'
import { useFormulaI18n } from '../../../hooks/useFormulaI18n'

export interface FormulaErrorProps {
Expand All @@ -8,13 +9,7 @@ export interface FormulaErrorProps {

export const FormulaError: FC<FormulaErrorProps> = ({ error }) => {
const { t } = useFormulaI18n()

let errorMessage: string
if (typeof error.message === 'string') {
errorMessage = t(error.message)
} else {
errorMessage = t(error.message[0], error.message[1])
}
const errorMessage = formulaI18n(t)(error.message)

return (
<>
Expand Down
8 changes: 6 additions & 2 deletions packages/editor/src/components/ui/Formula/FormulaValue.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { FC, ReactElement } from 'react'
import { resultToColorType, VariableDisplayData, display } from '@mashcard/formula'
import { cx, Icon, Tooltip } from '@mashcard/design-system'
import { SelectedType } from '../../blockViews/FormulaView'
import { getFormulaContext, SelectedType } from '../../blockViews/FormulaView'
import { FORMULA_COLOR_METAS, FORMULA_ICONS, FORMULA_STYLES } from './color'
import * as Root from './Formula.style'
import { useEditorContext } from '../../../hooks'

export interface FormulaValueProps {
displayData: VariableDisplayData
Expand All @@ -20,11 +21,14 @@ export const FormulaValue: FC<FormulaValueProps> = ({
disablePopover,
displayData: { result, type }
}) => {
const { editor } = useEditorContext()
const formulaContext = getFormulaContext(editor)

const colorType = resultToColorType(result)
const { colorCode } = FORMULA_COLOR_METAS[colorType]
const icon = FORMULA_ICONS[colorType]
const hasBorder = type === 'normal' && border
const displayResult = display(result).result
const displayResult = display(result, formulaContext!).result

if (!hasBorder) {
return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export const FormulaSpreadsheet: React.FC<FormulaSpreadsheetProps> = ({

return (
<SpreadsheetRender
title={spreadsheet.name()}
spreadsheet={spreadsheet}
valuesMatrix={valuesMatrix}
rows={rows}
columns={columns}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,31 @@
import { buildTestCases, dumpDisplayResultForDisplay, makeContext } from '@mashcard/formula'
import { render } from '@testing-library/react'
import { FormulaDisplay } from '..'
import { Formula } from '../../../../extensions'
import { mockEditor } from '../../../../test'
import * as editorHooks from '../../../../hooks/useEditorContext'

const [input] = buildTestCases(['basic'])

jest.mock('../../../../hooks/useEditorContext', () => {
const { useEditorContext } = jest.requireActual('../../../../hooks/useEditorContext')
return { useEditorContext: jest.fn().mockImplementation(useEditorContext) }
})

describe('FormulaDisplay', () => {
let ctx: Awaited<ReturnType<typeof makeContext>>
beforeAll(async () => {
jest.useRealTimers()
ctx = await makeContext(input.options)
jest.clearAllTimers()

const editor = mockEditor({
extensionManager: {
extensions: [{ name: Formula.name, options: { formulaContext: ctx.formulaContext } }]
}
})

jest.spyOn(editorHooks, 'useEditorContext').mockImplementation(() => ({ editor, documentEditable: true }))
})

it.each(input.basicTestCases)('$jestTitle', async args => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { BasicNames, buildTestCases, makeContext, TestCaseInput } from '@mashcard/formula'
import { render } from '@testing-library/react'
import { Formula } from '../../../../extensions'
import { mockEditor } from '../../../../test'
import { FormulaResult } from '../FormulaResult'
import * as editorHooks from '../../../../hooks/useEditorContext'

const [input, testCases] = buildTestCases<TestCaseInput['basicTestCases'][0]>(BasicNames)

Expand All @@ -17,12 +20,25 @@ jest.mock('react-i18next', () => ({
}
}))

jest.mock('../../../../hooks/useEditorContext', () => {
const { useEditorContext } = jest.requireActual('../../../../hooks/useEditorContext')
return { useEditorContext: jest.fn().mockImplementation(useEditorContext) }
})

describe('FormulaResult', () => {
let ctx: Awaited<ReturnType<typeof makeContext>>
beforeAll(async () => {
jest.useRealTimers()
ctx = await makeContext(input.options)
jest.clearAllTimers()

const editor = mockEditor({
extensionManager: {
extensions: [{ name: Formula.name, options: { formulaContext: ctx.formulaContext } }]
}
})

jest.spyOn(editorHooks, 'useEditorContext').mockImplementation(() => ({ editor, documentEditable: true }))
})

it.each(testCases)('$jestTitle', async args => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,31 @@
import { render } from '@testing-library/react'
import { buildTestCases, dumpDisplayResultForDisplay, makeContext } from '@mashcard/formula'
import { FormulaValue } from '../FormulaValue'
import { mockEditor } from '../../../../test'
import { Formula } from '../../../../extensions'
import * as editorHooks from '../../../../hooks/useEditorContext'

const [input] = buildTestCases(['basic'])

jest.mock('../../../../hooks/useEditorContext', () => {
const { useEditorContext } = jest.requireActual('../../../../hooks/useEditorContext')
return { useEditorContext: jest.fn().mockImplementation(useEditorContext) }
})

describe('FormulaValue', () => {
let ctx: Awaited<ReturnType<typeof makeContext>>
beforeAll(async () => {
jest.useRealTimers()
ctx = await makeContext(input.options)
jest.clearAllTimers()

const editor = mockEditor({
extensionManager: {
extensions: [{ name: Formula.name, options: { formulaContext: ctx.formulaContext } }]
}
})

jest.spyOn(editorHooks, 'useEditorContext').mockImplementation(() => ({ editor, documentEditable: true }))
})

it.each(input.basicTestCases)('$jestTitle', async args => {
Expand Down
Loading

0 comments on commit 74a4354

Please sign in to comment.