Merge main
This commit is contained in:
		
				
					committed by
					
						
						Adam Chalmers
					
				
			
			
				
	
			
			
			
						parent
						
							956f00c5a1
						
					
				
				
					commit
					b54a17a4fa
				
			
							
								
								
									
										10
									
								
								.github/workflows/playwright.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								.github/workflows/playwright.yml
									
									
									
									
										vendored
									
									
								
							@ -33,8 +33,18 @@ jobs:
 | 
			
		||||
            rust:
 | 
			
		||||
              - 'src/wasm-lib/**'
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
  playwright-chrome:
 | 
			
		||||
    timeout-minutes: ${{ matrix.os == 'macos-14' && 60 || 40 }}
 | 
			
		||||
||||||| parent of 1f27643b (Merge main)
 | 
			
		||||
  playwright-ubuntu:
 | 
			
		||||
    timeout-minutes: 30
 | 
			
		||||
    runs-on: ubuntu-latest-8-cores
 | 
			
		||||
=======
 | 
			
		||||
  playwright-ubuntu:
 | 
			
		||||
    timeout-minutes: 30
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
>>>>>>> 1f27643b (Merge main)
 | 
			
		||||
    strategy:
 | 
			
		||||
      fail-fast: false
 | 
			
		||||
      matrix:
 | 
			
		||||
 | 
			
		||||
@ -314,6 +314,7 @@ export function normaliseKclNumbers(code: string, ignoreZero = true): string {
 | 
			
		||||
  return replaceNumbers(code)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
export async function getUtils(page: Page, test_?: typeof test) {
 | 
			
		||||
  if (!test) {
 | 
			
		||||
    console.warn(
 | 
			
		||||
@ -321,6 +322,11 @@ export async function getUtils(page: Page, test_?: typeof test) {
 | 
			
		||||
    )
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
||||||| parent of 1f27643b (Merge main)
 | 
			
		||||
export async function getUtils(page: Page) {
 | 
			
		||||
=======
 | 
			
		||||
export async function getUtils(page: Page) {
 | 
			
		||||
>>>>>>> 1f27643b (Merge main)
 | 
			
		||||
  // Chrome devtools protocol session only works in Chromium
 | 
			
		||||
  const browserType = page.context().browser()?.browserType().name()
 | 
			
		||||
  const cdpSession =
 | 
			
		||||
 | 
			
		||||
@ -755,7 +755,8 @@ const part001 = startSketchOn('XZ')
 | 
			
		||||
      await clickConstrained({
 | 
			
		||||
        hoverPos: { x: tangentialArcTo.x, y: tangentialArcTo.y },
 | 
			
		||||
        constraintType: 'xAbsolute',
 | 
			
		||||
        expectBeforeUnconstrained: 'tangentialArcTo([3.14 + 13, -3.14], false, %)',
 | 
			
		||||
        expectBeforeUnconstrained:
 | 
			
		||||
          'tangentialArcTo([3.14 + 13, -3.14], false, %)',
 | 
			
		||||
        expectAfterUnconstrained: 'tangentialArcTo([16.14, -3.14], false, %)',
 | 
			
		||||
        expectFinal: 'tangentialArcTo([xAbs001, -3.14], false, %)',
 | 
			
		||||
        ang: ang + 180,
 | 
			
		||||
@ -766,8 +767,10 @@ const part001 = startSketchOn('XZ')
 | 
			
		||||
      await clickUnconstrained({
 | 
			
		||||
        hoverPos: { x: tangentialArcTo.x, y: tangentialArcTo.y },
 | 
			
		||||
        constraintType: 'yAbsolute',
 | 
			
		||||
        expectBeforeUnconstrained: 'tangentialArcTo([xAbs001, -3.14], false, %)',
 | 
			
		||||
        expectAfterUnconstrained: 'tangentialArcTo([xAbs001, yAbs001], false, %)',
 | 
			
		||||
        expectBeforeUnconstrained:
 | 
			
		||||
          'tangentialArcTo([xAbs001, -3.14], false, %)',
 | 
			
		||||
        expectAfterUnconstrained:
 | 
			
		||||
          'tangentialArcTo([xAbs001, yAbs001], false, %)',
 | 
			
		||||
        expectFinal: 'tangentialArcTo([xAbs001, -3.14], false, %)',
 | 
			
		||||
        ang: ang + 180,
 | 
			
		||||
        steps: 10,
 | 
			
		||||
 | 
			
		||||
@ -77,7 +77,17 @@ test.describe('Testing settings', () => {
 | 
			
		||||
      exact: true,
 | 
			
		||||
    })
 | 
			
		||||
    const inputLocator = page.locator('input[name="modeling-showDebugPanel"]')
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
||||||| parent of 1f27643b (Merge main)
 | 
			
		||||
    // Open the settings modal with the browser keyboard shortcut
 | 
			
		||||
    await page.keyboard.press('Meta+Shift+,')
 | 
			
		||||
=======
 | 
			
		||||
 | 
			
		||||
    // Open the settings modal with the browser keyboard shortcut
 | 
			
		||||
    await page.keyboard.press('Meta+Shift+,')
 | 
			
		||||
>>>>>>> 1f27643b (Merge main)
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    // Open the settings modal with the browser keyboard shortcut
 | 
			
		||||
    await page.keyboard.press('ControlOrMeta+Shift+,')
 | 
			
		||||
 | 
			
		||||
@ -128,7 +138,58 @@ test.describe('Testing settings', () => {
 | 
			
		||||
    const u = await getUtils(page)
 | 
			
		||||
    await page.setViewportSize({ width: 1200, height: 500 })
 | 
			
		||||
    await u.waitForAuthSkipAppStart()
 | 
			
		||||
||||||| parent of 1f27643b (Merge main)
 | 
			
		||||
    await expect(
 | 
			
		||||
      page.getByRole('heading', { name: 'Settings', exact: true })
 | 
			
		||||
    ).toBeVisible()
 | 
			
		||||
    await page
 | 
			
		||||
      .locator('select[name="app-theme"]')
 | 
			
		||||
      .selectOption({ value: 'light' })
 | 
			
		||||
 | 
			
		||||
    // Verify the toast appeared
 | 
			
		||||
    await expect(
 | 
			
		||||
      page.getByText(`Set theme to "light" for this project`)
 | 
			
		||||
    ).toBeVisible()
 | 
			
		||||
    // Check that the theme changed
 | 
			
		||||
    await expect(page.locator('body')).not.toHaveClass(`body-bg dark`)
 | 
			
		||||
 | 
			
		||||
    // Check that the user setting was not changed
 | 
			
		||||
    await page.getByRole('radio', { name: 'User' }).click()
 | 
			
		||||
    await expect(page.locator('select[name="app-theme"]')).toHaveValue('dark')
 | 
			
		||||
 | 
			
		||||
    // Roll back to default "system" theme
 | 
			
		||||
    await page
 | 
			
		||||
      .getByText(
 | 
			
		||||
        'themeRoll back themeRoll back to match defaultThe overall appearance of the appl'
 | 
			
		||||
      )
 | 
			
		||||
      .hover()
 | 
			
		||||
    await page
 | 
			
		||||
      .getByRole('button', {
 | 
			
		||||
        name: 'Roll back theme',
 | 
			
		||||
      })
 | 
			
		||||
      .click()
 | 
			
		||||
    await expect(page.locator('select[name="app-theme"]')).toHaveValue('system')
 | 
			
		||||
 | 
			
		||||
    // Check that the project setting did not change
 | 
			
		||||
    await page.getByRole('radio', { name: 'Project' }).click()
 | 
			
		||||
    await expect(page.locator('select[name="app-theme"]')).toHaveValue('light')
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  test('Project settings can be opened with keybinding from the editor', async ({
 | 
			
		||||
    page,
 | 
			
		||||
  }) => {
 | 
			
		||||
    const u = await getUtils(page)
 | 
			
		||||
    await page.setViewportSize({ width: 1200, height: 500 })
 | 
			
		||||
    await u.waitForAuthSkipAppStart()
 | 
			
		||||
    await page
 | 
			
		||||
      .getByRole('button', { name: 'Start Sketch' })
 | 
			
		||||
      .waitFor({ state: 'visible' })
 | 
			
		||||
=======
 | 
			
		||||
    await expect(headingLocator).toBeVisible()
 | 
			
		||||
    await page.locator('#showDebugPanel').getByText('OffOn').click()
 | 
			
		||||
>>>>>>> 1f27643b (Merge main)
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    await test.step('Open keybindings settings', async () => {
 | 
			
		||||
      // Open the settings modal with the browser keyboard shortcut
 | 
			
		||||
      await page.keyboard.press('ControlOrMeta+Shift+,')
 | 
			
		||||
@ -141,7 +202,31 @@ test.describe('Testing settings', () => {
 | 
			
		||||
    // Go to the hotkey for Command Palette.
 | 
			
		||||
    const commandPalette = page.getByText('Toggle Command Palette')
 | 
			
		||||
    await commandPalette.scrollIntoViewIfNeeded()
 | 
			
		||||
||||||| parent of 1f27643b (Merge main)
 | 
			
		||||
    // Put the cursor in the editor
 | 
			
		||||
    await page.locator('.cm-content').click()
 | 
			
		||||
 | 
			
		||||
    // Open the settings modal with the browser keyboard shortcut
 | 
			
		||||
    await page.keyboard.press('Meta+Shift+,')
 | 
			
		||||
 | 
			
		||||
    await expect(
 | 
			
		||||
      page.getByRole('heading', { name: 'Settings', exact: true })
 | 
			
		||||
    ).toBeVisible()
 | 
			
		||||
    await page
 | 
			
		||||
      .locator('select[name="app-theme"]')
 | 
			
		||||
      .selectOption({ value: 'light' })
 | 
			
		||||
=======
 | 
			
		||||
    // Close it and open again with keyboard shortcut, while KCL editor is focused
 | 
			
		||||
    // Put the cursor in the editor
 | 
			
		||||
    await test.step('Open settings with keyboard shortcut', async () => {
 | 
			
		||||
      await page.getByTestId('settings-close-button').click()
 | 
			
		||||
      await page.locator('.cm-content').click()
 | 
			
		||||
      await page.keyboard.press('Meta+Shift+,')
 | 
			
		||||
      await expect(headingLocator).toBeVisible()
 | 
			
		||||
    })
 | 
			
		||||
>>>>>>> 1f27643b (Merge main)
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    // The heading is above it and should be in view now.
 | 
			
		||||
    const commandPaletteHeading = page.getByRole('heading', {
 | 
			
		||||
      name: 'Command Palette',
 | 
			
		||||
@ -150,6 +235,63 @@ test.describe('Testing settings', () => {
 | 
			
		||||
    const hotkey = commandPaletteHeading.locator('+ div kbd')
 | 
			
		||||
    const text = process.platform === 'darwin' ? 'Command+K' : 'Control+K'
 | 
			
		||||
    await expect(hotkey).toHaveText(text)
 | 
			
		||||
||||||| parent of 1f27643b (Merge main)
 | 
			
		||||
    // Verify the toast appeared
 | 
			
		||||
    await expect(
 | 
			
		||||
      page.getByText(`Set theme to "light" for this project`)
 | 
			
		||||
    ).toBeVisible()
 | 
			
		||||
    // Check that the theme changed
 | 
			
		||||
    await expect(page.locator('body')).not.toHaveClass(`body-bg dark`)
 | 
			
		||||
 | 
			
		||||
    // Check that the user setting was not changed
 | 
			
		||||
    await page.getByRole('radio', { name: 'User' }).click()
 | 
			
		||||
    await expect(page.locator('select[name="app-theme"]')).toHaveValue('dark')
 | 
			
		||||
 | 
			
		||||
    // Roll back to default "system" theme
 | 
			
		||||
    await page
 | 
			
		||||
      .getByText(
 | 
			
		||||
        'themeRoll back themeRoll back to match defaultThe overall appearance of the appl'
 | 
			
		||||
      )
 | 
			
		||||
      .hover()
 | 
			
		||||
    await page
 | 
			
		||||
      .getByRole('button', {
 | 
			
		||||
        name: 'Roll back theme',
 | 
			
		||||
      })
 | 
			
		||||
      .click()
 | 
			
		||||
    await expect(page.locator('select[name="app-theme"]')).toHaveValue('system')
 | 
			
		||||
 | 
			
		||||
    // Check that the project setting did not change
 | 
			
		||||
    await page.getByRole('radio', { name: 'Project' }).click()
 | 
			
		||||
    await expect(page.locator('select[name="app-theme"]')).toHaveValue('light')
 | 
			
		||||
=======
 | 
			
		||||
    // Verify the toast appeared
 | 
			
		||||
    await expect(
 | 
			
		||||
      page.getByText(`Set show debug panel to "false" for this project`)
 | 
			
		||||
    ).toBeVisible()
 | 
			
		||||
    // Check that the theme changed
 | 
			
		||||
    await expect(paneButtonLocator).not.toBeVisible()
 | 
			
		||||
 | 
			
		||||
    // Check that the user setting was not changed
 | 
			
		||||
    await page.getByRole('radio', { name: 'User' }).click()
 | 
			
		||||
    await expect(inputLocator).toBeChecked()
 | 
			
		||||
 | 
			
		||||
    // Roll back to default of "off"
 | 
			
		||||
    await await page
 | 
			
		||||
      .getByText('show debug panelRoll back show debug panelRoll back to match')
 | 
			
		||||
      .hover()
 | 
			
		||||
    await page
 | 
			
		||||
      .getByRole('button', {
 | 
			
		||||
        name: 'Roll back show debug panel',
 | 
			
		||||
      })
 | 
			
		||||
      .click()
 | 
			
		||||
    await expect(inputLocator).not.toBeChecked()
 | 
			
		||||
 | 
			
		||||
    // Check that the project setting did not change
 | 
			
		||||
    await page.getByRole('radio', { name: 'Project' }).click()
 | 
			
		||||
    await expect(
 | 
			
		||||
      page.locator('input[name="modeling-showDebugPanel"]')
 | 
			
		||||
    ).not.toBeChecked()
 | 
			
		||||
>>>>>>> 1f27643b (Merge main)
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  test('Project and user settings can be reset', async ({ page }) => {
 | 
			
		||||
@ -186,6 +328,7 @@ test.describe('Testing settings', () => {
 | 
			
		||||
 | 
			
		||||
      // Set project-level value to 50
 | 
			
		||||
      await themeColorSetting.fill(settingValues.project)
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
 | 
			
		||||
      // Set user-level value to 120
 | 
			
		||||
      await userSettingsTab.click()
 | 
			
		||||
@ -375,7 +518,14 @@ test.describe('Testing settings', () => {
 | 
			
		||||
    await page
 | 
			
		||||
      .getByRole('button', { name: 'Start Sketch' })
 | 
			
		||||
      .waitFor({ state: 'visible' })
 | 
			
		||||
||||||| parent of 1f27643b (Merge main)
 | 
			
		||||
    await page
 | 
			
		||||
      .locator('select[name="app-theme"]')
 | 
			
		||||
      .selectOption({ value: 'light' })
 | 
			
		||||
=======
 | 
			
		||||
>>>>>>> 1f27643b (Merge main)
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    const userSettingsTab = page.getByRole('radio', { name: 'User' })
 | 
			
		||||
 | 
			
		||||
    // Open the settings modal with lower-right button
 | 
			
		||||
@ -383,13 +533,39 @@ test.describe('Testing settings', () => {
 | 
			
		||||
    await expect(
 | 
			
		||||
      page.getByRole('heading', { name: 'Settings', exact: true })
 | 
			
		||||
    ).toBeVisible()
 | 
			
		||||
||||||| parent of 1f27643b (Merge main)
 | 
			
		||||
    // Verify the toast appeared
 | 
			
		||||
    await expect(
 | 
			
		||||
      page.getByText(`Set theme to "light" for this project`)
 | 
			
		||||
    ).toBeVisible()
 | 
			
		||||
    // Check that the theme changed
 | 
			
		||||
    await expect(page.locator('body')).not.toHaveClass(`body-bg dark`)
 | 
			
		||||
    await expect(page.locator('select[name="app-theme"]')).toHaveValue('light')
 | 
			
		||||
=======
 | 
			
		||||
      // Set user-level value to 120
 | 
			
		||||
      await userSettingsTab.click()
 | 
			
		||||
      await themeColorSetting.fill(settingValues.user)
 | 
			
		||||
      await projectSettingsTab.click()
 | 
			
		||||
    })
 | 
			
		||||
>>>>>>> 1f27643b (Merge main)
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    const resetButton = page.getByRole('button', {
 | 
			
		||||
      name: 'Restore default settings',
 | 
			
		||||
    })
 | 
			
		||||
    // Default unit should be mm
 | 
			
		||||
    await resetButton.click()
 | 
			
		||||
||||||| parent of 1f27643b (Merge main)
 | 
			
		||||
    // Check that the user setting was not changed
 | 
			
		||||
    await page.getByRole('radio', { name: 'User' }).click()
 | 
			
		||||
    await expect(page.locator('select[name="app-theme"]')).toHaveValue('system')
 | 
			
		||||
=======
 | 
			
		||||
    await test.step('Reset project settings', async () => {
 | 
			
		||||
      // Click the reset settings button.
 | 
			
		||||
      await resetButton.click()
 | 
			
		||||
>>>>>>> 1f27643b (Merge main)
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    await test.step('Change modeling default unit within project tab', async () => {
 | 
			
		||||
      const changeUnitOfMeasureInProjectTab = async (unitOfMeasure: string) => {
 | 
			
		||||
        await test.step(`Set modeling default unit to ${unitOfMeasure}`, async () => {
 | 
			
		||||
@ -409,7 +585,15 @@ test.describe('Testing settings', () => {
 | 
			
		||||
      await changeUnitOfMeasureInProjectTab('cm')
 | 
			
		||||
      await changeUnitOfMeasureInProjectTab('m')
 | 
			
		||||
    })
 | 
			
		||||
||||||| parent of 1f27643b (Merge main)
 | 
			
		||||
    // Click the reset settings button.
 | 
			
		||||
    await page.getByRole('button', { name: 'Restore default settings' }).click()
 | 
			
		||||
=======
 | 
			
		||||
      // Verify it is now set to the inherited user value
 | 
			
		||||
      await expect(themeColorSetting).toHaveValue(settingValues.default)
 | 
			
		||||
>>>>>>> 1f27643b (Merge main)
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    // Go to the user tab
 | 
			
		||||
    await userSettingsTab.click()
 | 
			
		||||
    await test.step('Change modeling default unit within user tab', async () => {
 | 
			
		||||
@ -431,11 +615,33 @@ test.describe('Testing settings', () => {
 | 
			
		||||
      await changeUnitOfMeasureInUserTab('cm')
 | 
			
		||||
      await changeUnitOfMeasureInUserTab('m')
 | 
			
		||||
    })
 | 
			
		||||
||||||| parent of 1f27643b (Merge main)
 | 
			
		||||
    // Verify it is now set to the default value
 | 
			
		||||
    await expect(page.locator('select[name="app-theme"]')).toHaveValue('system')
 | 
			
		||||
=======
 | 
			
		||||
      // Check that the user setting also rolled back
 | 
			
		||||
      await userSettingsTab.click()
 | 
			
		||||
      await expect(themeColorSetting).toHaveValue(settingValues.default)
 | 
			
		||||
      await projectSettingsTab.click()
 | 
			
		||||
>>>>>>> 1f27643b (Merge main)
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    // Close settings
 | 
			
		||||
    const settingsCloseButton = page.getByTestId('settings-close-button')
 | 
			
		||||
    await settingsCloseButton.click()
 | 
			
		||||
||||||| parent of 1f27643b (Merge main)
 | 
			
		||||
    // Set the user theme to light.
 | 
			
		||||
    await page
 | 
			
		||||
      .locator('select[name="app-theme"]')
 | 
			
		||||
      .selectOption({ value: 'light' })
 | 
			
		||||
=======
 | 
			
		||||
      // Set project-level value to 50 again to test the user-level reset
 | 
			
		||||
      await themeColorSetting.fill(settingValues.project)
 | 
			
		||||
      await userSettingsTab.click()
 | 
			
		||||
    })
 | 
			
		||||
>>>>>>> 1f27643b (Merge main)
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    await test.step('Change modeling default unit within command bar', async () => {
 | 
			
		||||
      const commands = page.getByRole('button', { name: 'Commands' })
 | 
			
		||||
      const changeUnitOfMeasureInCommandBar = async (unitOfMeasure: string) => {
 | 
			
		||||
@ -445,13 +651,36 @@ test.describe('Testing settings', () => {
 | 
			
		||||
          'Settings · modeling · default unit'
 | 
			
		||||
        )
 | 
			
		||||
        await settingsModelingDefaultUnitCommand.click()
 | 
			
		||||
||||||| parent of 1f27643b (Merge main)
 | 
			
		||||
    // Verify the toast appeared
 | 
			
		||||
    await expect(
 | 
			
		||||
      page.getByText(`Set theme to "light" as a user default`)
 | 
			
		||||
    ).toBeVisible()
 | 
			
		||||
    // Check that the theme changed
 | 
			
		||||
    await expect(page.locator('body')).not.toHaveClass(`body-bg dark`)
 | 
			
		||||
    await expect(page.locator('select[name="app-theme"]')).toHaveValue('light')
 | 
			
		||||
=======
 | 
			
		||||
    await test.step('Reset user settings', async () => {
 | 
			
		||||
      // Change the setting and click the reset settings button.
 | 
			
		||||
      await themeColorSetting.fill(settingValues.user)
 | 
			
		||||
      await resetButton.click()
 | 
			
		||||
>>>>>>> 1f27643b (Merge main)
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
        const commandOption = page.getByRole('option', {
 | 
			
		||||
          name: unitOfMeasure,
 | 
			
		||||
          exact: true,
 | 
			
		||||
        })
 | 
			
		||||
        await commandOption.click()
 | 
			
		||||
||||||| parent of 1f27643b (Merge main)
 | 
			
		||||
    await page.getByRole('radio', { name: 'Project' }).click()
 | 
			
		||||
    await expect(page.locator('select[name="app-theme"]')).toHaveValue('light')
 | 
			
		||||
=======
 | 
			
		||||
      // Verify it is now set to the default value
 | 
			
		||||
      await expect(themeColorSetting).toHaveValue(settingValues.default)
 | 
			
		||||
>>>>>>> 1f27643b (Merge main)
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
        const toastMessage = page.getByText(
 | 
			
		||||
          `Set default unit to "${unitOfMeasure}" for this project`
 | 
			
		||||
        )
 | 
			
		||||
@ -491,6 +720,25 @@ test.describe('Testing settings', () => {
 | 
			
		||||
      await changeUnitOfMeasureInGizmo('mm', 'Millimeters')
 | 
			
		||||
      await changeUnitOfMeasureInGizmo('cm', 'Centimeters')
 | 
			
		||||
      await changeUnitOfMeasureInGizmo('m', 'Meters')
 | 
			
		||||
||||||| parent of 1f27643b (Merge main)
 | 
			
		||||
    // Click the reset settings button.
 | 
			
		||||
    await page.getByRole('button', { name: 'Restore default settings' }).click()
 | 
			
		||||
    // Verify it is now set to the default value
 | 
			
		||||
    await expect(page.locator('select[name="app-theme"]')).toHaveValue('system')
 | 
			
		||||
 | 
			
		||||
    await page.getByRole('radio', { name: 'User' }).click()
 | 
			
		||||
    await expect(page.locator('select[name="app-theme"]')).toHaveValue('system')
 | 
			
		||||
 | 
			
		||||
    // Click the reset settings button.
 | 
			
		||||
    await page.getByRole('button', { name: 'Restore default settings' }).click()
 | 
			
		||||
 | 
			
		||||
    // Verify it is now set to the default value
 | 
			
		||||
    await expect(page.locator('select[name="app-theme"]')).toHaveValue('system')
 | 
			
		||||
=======
 | 
			
		||||
      // Check that the project setting also changed
 | 
			
		||||
      await projectSettingsTab.click()
 | 
			
		||||
      await expect(themeColorSetting).toHaveValue(settingValues.default)
 | 
			
		||||
>>>>>>> 1f27643b (Merge main)
 | 
			
		||||
    })
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										7295
									
								
								src-tauri/Cargo.lock
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										7295
									
								
								src-tauri/Cargo.lock
									
									
									
										generated
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										47
									
								
								src-tauri/Cargo.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								src-tauri/Cargo.toml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,47 @@
 | 
			
		||||
[package]
 | 
			
		||||
name = "app"
 | 
			
		||||
version = "0.1.0"
 | 
			
		||||
description = "The Zoo Modeling App"
 | 
			
		||||
authors = ["Zoo Engineers <eng@zoo.dev>"]
 | 
			
		||||
license = ""
 | 
			
		||||
repository = "https://github.com/KittyCAD/modeling-app"
 | 
			
		||||
default-run = "app"
 | 
			
		||||
edition = "2021"
 | 
			
		||||
rust-version = "1.70"
 | 
			
		||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 | 
			
		||||
 | 
			
		||||
[build-dependencies]
 | 
			
		||||
tauri-build = { version = "2.0.0-beta.18", features = [] }
 | 
			
		||||
 | 
			
		||||
[dependencies]
 | 
			
		||||
anyhow = "1"
 | 
			
		||||
kcl-lib = { version = "0.2", path = "../src/wasm-lib/kcl" }
 | 
			
		||||
kittycad = "0.3.12"
 | 
			
		||||
log = "0.4.21"
 | 
			
		||||
mdns-sd = "0.11.1"
 | 
			
		||||
oauth2 = "4.4.2"
 | 
			
		||||
reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls"] }
 | 
			
		||||
serde_json = "1.0"
 | 
			
		||||
tauri = { version = "2.0.0-beta.23", features = [ "devtools", "unstable"] }
 | 
			
		||||
tauri-plugin-cli = { version = "2.0.0-beta.7" }
 | 
			
		||||
tauri-plugin-deep-link = { version = "2.0.0-beta.8" }
 | 
			
		||||
tauri-plugin-dialog = { version = "2.0.0-beta.6" }
 | 
			
		||||
tauri-plugin-fs = { version = "2.0.0-beta.10" }
 | 
			
		||||
tauri-plugin-http = { version = "2.0.0-beta.11" }
 | 
			
		||||
tauri-plugin-log = { version = "2.0.0-beta.7" }
 | 
			
		||||
tauri-plugin-os = { version = "2.0.0-beta.7" }
 | 
			
		||||
tauri-plugin-persisted-scope = { version = "2.0.0-beta.10" }
 | 
			
		||||
tauri-plugin-process = { version = "2.0.0-beta.7" }
 | 
			
		||||
tauri-plugin-shell = { version = "2.0.0-beta.8" }
 | 
			
		||||
tauri-plugin-updater = { version = "2.0.0-beta.9" }
 | 
			
		||||
tokio = { version = "1.37.0", features = ["time", "fs", "process"] }
 | 
			
		||||
toml = "0.8.2"
 | 
			
		||||
url = "2.5.0"
 | 
			
		||||
 | 
			
		||||
[features]
 | 
			
		||||
default = ["updater"]
 | 
			
		||||
# this feature is used for production builds or when `devPath` points to the filesystem and the built-in dev server is disabled.
 | 
			
		||||
# If you use cargo directly instead of tauri's cli you can use this feature flag to switch between tauri's `dev` and `build` modes.
 | 
			
		||||
# DO NOT REMOVE!!
 | 
			
		||||
custom-protocol = ["tauri/custom-protocol"]
 | 
			
		||||
updater = []
 | 
			
		||||
							
								
								
									
										13
									
								
								src/App.tsx
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								src/App.tsx
									
									
									
									
									
								
							@ -28,6 +28,12 @@ import { CoreDumpManager } from 'lib/coredump'
 | 
			
		||||
import { UnitsMenu } from 'components/UnitsMenu'
 | 
			
		||||
 | 
			
		||||
export function App() {
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
||||||| parent of 1f27643b (Merge main)
 | 
			
		||||
  useRefreshSettings(paths.FILE + 'SETTINGS')
 | 
			
		||||
=======
 | 
			
		||||
  useRefreshSettings(PATHS.FILE + 'SETTINGS')
 | 
			
		||||
>>>>>>> 1f27643b (Merge main)
 | 
			
		||||
  const { project, file } = useLoaderData() as IndexLoaderData
 | 
			
		||||
  useRefreshSettings(PATHS.FILE + 'SETTINGS')
 | 
			
		||||
  const navigate = useNavigate()
 | 
			
		||||
@ -62,7 +68,14 @@ export function App() {
 | 
			
		||||
    e.preventDefault()
 | 
			
		||||
  })
 | 
			
		||||
  useHotkeyWrapper(
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    [isDesktop() ? 'mod + ,' : 'shift + mod + ,'],
 | 
			
		||||
||||||| parent of 1f27643b (Merge main)
 | 
			
		||||
    [isTauri() ? 'mod + ,' : 'shift + mod + ,'],
 | 
			
		||||
    () => navigate(filePath + paths.SETTINGS),
 | 
			
		||||
=======
 | 
			
		||||
    [isTauri() ? 'mod + ,' : 'shift + mod + ,'],
 | 
			
		||||
>>>>>>> 1f27643b (Merge main)
 | 
			
		||||
    () => navigate(filePath + PATHS.SETTINGS),
 | 
			
		||||
    {
 | 
			
		||||
      splitKey: '|',
 | 
			
		||||
 | 
			
		||||
@ -76,13 +76,27 @@ const router = createRouter([
 | 
			
		||||
              // Redirect to the file if we have a file path.
 | 
			
		||||
              if (projectStartupFile.length > 0) {
 | 
			
		||||
                return redirect(
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
                  PATHS.FILE + '/' + encodeURIComponent(projectStartupFile)
 | 
			
		||||
||||||| parent of 1f27643b (Merge main)
 | 
			
		||||
                  paths.FILE + '/' + encodeURIComponent(appState.current_file)
 | 
			
		||||
=======
 | 
			
		||||
                  PATHS.FILE + '/' + encodeURIComponent(appState.current_file)
 | 
			
		||||
>>>>>>> 1f27643b (Merge main)
 | 
			
		||||
                )
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
          return onDesktop
 | 
			
		||||
||||||| parent of 1f27643b (Merge main)
 | 
			
		||||
          return inTauri
 | 
			
		||||
            ? redirect(paths.HOME)
 | 
			
		||||
            : redirect(paths.FILE + '/%2F' + BROWSER_PROJECT_NAME)
 | 
			
		||||
=======
 | 
			
		||||
          return inTauri
 | 
			
		||||
>>>>>>> 1f27643b (Merge main)
 | 
			
		||||
            ? redirect(PATHS.HOME)
 | 
			
		||||
            : redirect(PATHS.FILE + '/%2F' + BROWSER_PROJECT_NAME)
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
@ -53,10 +53,18 @@ export const FileMachineProvider = ({
 | 
			
		||||
        if (event.data && 'name' in event.data) {
 | 
			
		||||
          commandBarSend({ type: 'Close' })
 | 
			
		||||
          navigate(
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
            `..${PATHS.FILE}/${encodeURIComponent(
 | 
			
		||||
              context.selectedDirectory +
 | 
			
		||||
                window.electron.path.sep +
 | 
			
		||||
                event.data.name
 | 
			
		||||
||||||| parent of 1f27643b (Merge main)
 | 
			
		||||
            `${paths.FILE}/${encodeURIComponent(
 | 
			
		||||
              context.selectedDirectory + sep() + event.data.name
 | 
			
		||||
=======
 | 
			
		||||
            `${PATHS.FILE}/${encodeURIComponent(
 | 
			
		||||
              context.selectedDirectory + sep() + event.data.name
 | 
			
		||||
>>>>>>> 1f27643b (Merge main)
 | 
			
		||||
            )}`
 | 
			
		||||
          )
 | 
			
		||||
        } else if (
 | 
			
		||||
@ -65,7 +73,13 @@ export const FileMachineProvider = ({
 | 
			
		||||
          event.data.path.endsWith(FILE_EXT)
 | 
			
		||||
        ) {
 | 
			
		||||
          // Don't navigate to newly created directories
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
          navigate(`..${PATHS.FILE}/${encodeURIComponent(event.data.path)}`)
 | 
			
		||||
||||||| parent of 1f27643b (Merge main)
 | 
			
		||||
          navigate(`${paths.FILE}/${encodeURIComponent(event.data.path)}`)
 | 
			
		||||
=======
 | 
			
		||||
          navigate(`${PATHS.FILE}/${encodeURIComponent(event.data.path)}`)
 | 
			
		||||
>>>>>>> 1f27643b (Merge main)
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      addFileToRenamingQueue: assign({
 | 
			
		||||
@ -198,13 +212,29 @@ export const FileMachineProvider = ({
 | 
			
		||||
 | 
			
		||||
        if (oldPath === file.path && project?.path) {
 | 
			
		||||
          // If we just renamed the current file, navigate to the new path
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
          navigate(`..${PATHS.FILE}/${encodeURIComponent(newPath)}`)
 | 
			
		||||
||||||| parent of 1f27643b (Merge main)
 | 
			
		||||
          navigate(paths.FILE + '/' + encodeURIComponent(newPath))
 | 
			
		||||
=======
 | 
			
		||||
          navigate(PATHS.FILE + '/' + encodeURIComponent(newPath))
 | 
			
		||||
>>>>>>> 1f27643b (Merge main)
 | 
			
		||||
        } else if (file?.path.includes(oldPath)) {
 | 
			
		||||
          // If we just renamed a directory that the current file is in, navigate to the new path
 | 
			
		||||
          navigate(
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
            `..${PATHS.FILE}/${encodeURIComponent(
 | 
			
		||||
              file.path.replace(oldPath, newPath)
 | 
			
		||||
            )}`
 | 
			
		||||
||||||| parent of 1f27643b (Merge main)
 | 
			
		||||
            paths.FILE +
 | 
			
		||||
              '/' +
 | 
			
		||||
              encodeURIComponent(file.path.replace(oldPath, newDirPath))
 | 
			
		||||
=======
 | 
			
		||||
            PATHS.FILE +
 | 
			
		||||
              '/' +
 | 
			
		||||
              encodeURIComponent(file.path.replace(oldPath, newDirPath))
 | 
			
		||||
>>>>>>> 1f27643b (Merge main)
 | 
			
		||||
          )
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -260,7 +290,13 @@ export const FileMachineProvider = ({
 | 
			
		||||
            file?.path.includes(event.data.path)) &&
 | 
			
		||||
          project?.path
 | 
			
		||||
        ) {
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
          navigate(`../${PATHS.FILE}/${encodeURIComponent(project.path)}`)
 | 
			
		||||
||||||| parent of 1f27643b (Merge main)
 | 
			
		||||
          navigate(paths.FILE + '/' + encodeURIComponent(project.path))
 | 
			
		||||
=======
 | 
			
		||||
          navigate(PATHS.FILE + '/' + encodeURIComponent(project.path))
 | 
			
		||||
>>>>>>> 1f27643b (Merge main)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return `Successfully deleted ${isDir ? 'folder' : 'file'} "${
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,11 @@
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
import type { IndexLoaderData } from 'lib/types'
 | 
			
		||||
||||||| parent of 1f27643b (Merge main)
 | 
			
		||||
import type { FileEntry, IndexLoaderData } from 'lib/types'
 | 
			
		||||
import { paths } from 'lib/paths'
 | 
			
		||||
=======
 | 
			
		||||
import type { FileEntry, IndexLoaderData } from 'lib/types'
 | 
			
		||||
>>>>>>> 1f27643b (Merge main)
 | 
			
		||||
import { PATHS } from 'lib/paths'
 | 
			
		||||
import { ActionButton } from './ActionButton'
 | 
			
		||||
import Tooltip from './Tooltip'
 | 
			
		||||
@ -476,10 +483,16 @@ export const FileTreeInner = ({
 | 
			
		||||
  }, [documentHasFocus])
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    <div
 | 
			
		||||
      className="overflow-auto pb-12 absolute inset-0"
 | 
			
		||||
      data-testid="file-pane-scroll-container"
 | 
			
		||||
    >
 | 
			
		||||
||||||| parent of 1f27643b (Merge main)
 | 
			
		||||
    <div className="overflow-auto max-h-full pb-12">
 | 
			
		||||
=======
 | 
			
		||||
    <div className="overflow-auto pb-12 absolute inset-0">
 | 
			
		||||
>>>>>>> 1f27643b (Merge main)
 | 
			
		||||
      <ul
 | 
			
		||||
        className="m-0 p-0 text-sm"
 | 
			
		||||
        onClickCapture={(e) => {
 | 
			
		||||
 | 
			
		||||
@ -3,8 +3,16 @@ import Tooltip from './Tooltip'
 | 
			
		||||
import { useSettingsAuthContext } from 'hooks/useSettingsAuthContext'
 | 
			
		||||
import { CustomIcon } from './CustomIcon'
 | 
			
		||||
import { useLocation, useNavigate } from 'react-router-dom'
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
import { PATHS } from 'lib/paths'
 | 
			
		||||
import { createAndOpenNewProject } from 'lib/desktopFS'
 | 
			
		||||
||||||| parent of 1f27643b (Merge main)
 | 
			
		||||
import { createAndOpenNewProject } from 'lib/tauriFS'
 | 
			
		||||
import { paths } from 'lib/paths'
 | 
			
		||||
=======
 | 
			
		||||
import { createAndOpenNewProject } from 'lib/tauriFS'
 | 
			
		||||
import { PATHS } from 'lib/paths'
 | 
			
		||||
>>>>>>> 1f27643b (Merge main)
 | 
			
		||||
import { useAbsoluteFilePath } from 'hooks/useAbsoluteFilePath'
 | 
			
		||||
import { useLspContext } from './LspProvider'
 | 
			
		||||
import { openExternalBrowserIfDesktop } from 'lib/openWindow'
 | 
			
		||||
 | 
			
		||||
@ -93,7 +93,15 @@ export function LowerRightControls({
 | 
			
		||||
        <Link
 | 
			
		||||
          to={
 | 
			
		||||
            location.pathname.includes(PATHS.FILE)
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
              ? filePath + PATHS.SETTINGS + '?tab=project'
 | 
			
		||||
||||||| parent of 1f27643b (Merge main)
 | 
			
		||||
            location.pathname.includes(paths.FILE)
 | 
			
		||||
              ? filePath + paths.SETTINGS + '?tab=project'
 | 
			
		||||
              : paths.HOME + paths.SETTINGS
 | 
			
		||||
=======
 | 
			
		||||
              ? filePath + PATHS.SETTINGS_PROJECT
 | 
			
		||||
>>>>>>> 1f27643b (Merge main)
 | 
			
		||||
              : PATHS.HOME + PATHS.SETTINGS
 | 
			
		||||
          }
 | 
			
		||||
          data-testid="settings-link"
 | 
			
		||||
 | 
			
		||||
@ -15,7 +15,14 @@ import { Extension } from '@codemirror/state'
 | 
			
		||||
import { LanguageSupport } from '@codemirror/language'
 | 
			
		||||
import { useNavigate } from 'react-router-dom'
 | 
			
		||||
import { PATHS } from 'lib/paths'
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
import { FileEntry } from 'lib/project'
 | 
			
		||||
||||||| parent of 1f27643b (Merge main)
 | 
			
		||||
import { paths } from 'lib/paths'
 | 
			
		||||
import { FileEntry } from 'lib/types'
 | 
			
		||||
=======
 | 
			
		||||
import { FileEntry } from 'lib/types'
 | 
			
		||||
>>>>>>> 1f27643b (Merge main)
 | 
			
		||||
import Worker from 'editor/plugins/lsp/worker.ts?worker'
 | 
			
		||||
import {
 | 
			
		||||
  KclWorkerOptions,
 | 
			
		||||
 | 
			
		||||
@ -2,7 +2,14 @@ import { Popover, Transition } from '@headlessui/react'
 | 
			
		||||
import { ActionButton, ActionButtonProps } from './ActionButton'
 | 
			
		||||
import { type IndexLoaderData } from 'lib/types'
 | 
			
		||||
import { PATHS } from 'lib/paths'
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
import { isDesktop } from '../lib/isDesktop'
 | 
			
		||||
||||||| parent of 1f27643b (Merge main)
 | 
			
		||||
import { paths } from 'lib/paths'
 | 
			
		||||
import { isTauri } from '../lib/isTauri'
 | 
			
		||||
=======
 | 
			
		||||
import { isTauri } from '../lib/isTauri'
 | 
			
		||||
>>>>>>> 1f27643b (Merge main)
 | 
			
		||||
import { Link, useLocation, useNavigate } from 'react-router-dom'
 | 
			
		||||
import { Fragment, useMemo } from 'react'
 | 
			
		||||
import { Logo } from './Logo'
 | 
			
		||||
 | 
			
		||||
@ -15,8 +15,16 @@ import { SettingsFieldInput } from './SettingsFieldInput'
 | 
			
		||||
import { getInitialDefaultDir } from 'lib/desktop'
 | 
			
		||||
import toast from 'react-hot-toast'
 | 
			
		||||
import { APP_VERSION } from 'routes/Settings'
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
import { PATHS } from 'lib/paths'
 | 
			
		||||
import { createAndOpenNewProject, getSettingsFolderPaths } from 'lib/desktopFS'
 | 
			
		||||
||||||| parent of 1f27643b (Merge main)
 | 
			
		||||
import { createAndOpenNewProject, getSettingsFolderPaths } from 'lib/tauriFS'
 | 
			
		||||
import { paths } from 'lib/paths'
 | 
			
		||||
=======
 | 
			
		||||
import { createAndOpenNewProject, getSettingsFolderPaths } from 'lib/tauriFS'
 | 
			
		||||
import { PATHS } from 'lib/paths'
 | 
			
		||||
>>>>>>> 1f27643b (Merge main)
 | 
			
		||||
import { useDotDotSlash } from 'hooks/useDotDotSlash'
 | 
			
		||||
import { ForwardedRef, forwardRef, useEffect } from 'react'
 | 
			
		||||
import { useLspContext } from 'components/LspProvider'
 | 
			
		||||
@ -45,12 +53,20 @@ export const AllSettingsFields = forwardRef(
 | 
			
		||||
            location.pathname
 | 
			
		||||
              .replace(PATHS.FILE + '/', '')
 | 
			
		||||
              .replace(PATHS.SETTINGS, '')
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
              .slice(
 | 
			
		||||
                0,
 | 
			
		||||
                decodeURI(location.pathname).lastIndexOf(
 | 
			
		||||
                  window.electron.path.sep
 | 
			
		||||
                )
 | 
			
		||||
              )
 | 
			
		||||
||||||| parent of 1f27643b (Merge main)
 | 
			
		||||
              .replace(paths.FILE + '/', '')
 | 
			
		||||
              .replace(paths.SETTINGS, '')
 | 
			
		||||
              .slice(0, decodeURI(location.pathname).lastIndexOf(sep()))
 | 
			
		||||
=======
 | 
			
		||||
              .slice(0, decodeURI(location.pathname).lastIndexOf(sep()))
 | 
			
		||||
>>>>>>> 1f27643b (Merge main)
 | 
			
		||||
          )
 | 
			
		||||
        : undefined
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,12 @@
 | 
			
		||||
import { useMachine } from '@xstate/react'
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
import { useNavigate, useRouteLoaderData, useLocation } from 'react-router-dom'
 | 
			
		||||
||||||| parent of 1f27643b (Merge main)
 | 
			
		||||
import { useNavigate, useRouteLoaderData } from 'react-router-dom'
 | 
			
		||||
import { paths } from 'lib/paths'
 | 
			
		||||
=======
 | 
			
		||||
import { useNavigate, useRouteLoaderData } from 'react-router-dom'
 | 
			
		||||
>>>>>>> 1f27643b (Merge main)
 | 
			
		||||
import { PATHS } from 'lib/paths'
 | 
			
		||||
import { authMachine, TOKEN_PERSIST_KEY } from '../machines/authMachine'
 | 
			
		||||
import withBaseUrl from '../lib/withBaseURL'
 | 
			
		||||
@ -302,7 +309,14 @@ export const SettingsAuthProviderBase = ({
 | 
			
		||||
        logout()
 | 
			
		||||
      },
 | 
			
		||||
      goToIndexPage: () => {
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
        if (location.pathname.includes(PATHS.SIGN_IN)) {
 | 
			
		||||
||||||| parent of 1f27643b (Merge main)
 | 
			
		||||
        if (window.location.pathname.includes(paths.SIGN_IN)) {
 | 
			
		||||
          navigate(paths.INDEX)
 | 
			
		||||
=======
 | 
			
		||||
        if (window.location.pathname.includes(PATHS.SIGN_IN)) {
 | 
			
		||||
>>>>>>> 1f27643b (Merge main)
 | 
			
		||||
          navigate(PATHS.INDEX)
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
 | 
			
		||||
@ -256,6 +256,14 @@ const runFilletTest = async (
 | 
			
		||||
    return new Error('Path to extrude node not found')
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
||||||| parent of 1f27643b (Merge main)
 | 
			
		||||
  // const radius = createLiteral(5) as Value
 | 
			
		||||
 | 
			
		||||
=======
 | 
			
		||||
  // const radius = createLiteral(5) as Expr
 | 
			
		||||
 | 
			
		||||
>>>>>>> 1f27643b (Merge main)
 | 
			
		||||
  const result = addFillet(ast, pathToSegmentNode, pathToExtrudeNode, radius)
 | 
			
		||||
  if (err(result)) {
 | 
			
		||||
    return result
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,12 @@ import {
 | 
			
		||||
  ObjectExpression,
 | 
			
		||||
  PathToNode,
 | 
			
		||||
  Program,
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
  ProgramMemory,
 | 
			
		||||
||||||| parent of 1f27643b (Merge main)
 | 
			
		||||
  Value,
 | 
			
		||||
=======
 | 
			
		||||
>>>>>>> 1f27643b (Merge main)
 | 
			
		||||
  Expr,
 | 
			
		||||
  VariableDeclaration,
 | 
			
		||||
  VariableDeclarator,
 | 
			
		||||
@ -159,7 +164,15 @@ export function addFillet(
 | 
			
		||||
  ast: Program,
 | 
			
		||||
  pathToSegmentNode: PathToNode,
 | 
			
		||||
  pathToExtrudeNode: PathToNode,
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
  radius: Expr = createLiteral(5)
 | 
			
		||||
||||||| parent of 1f27643b (Merge main)
 | 
			
		||||
  radius = createLiteral(5) as Value
 | 
			
		||||
  // shouldPipe = false, // TODO: Implement this feature
 | 
			
		||||
=======
 | 
			
		||||
  radius = createLiteral(5) as Expr
 | 
			
		||||
  // shouldPipe = false, // TODO: Implement this feature
 | 
			
		||||
>>>>>>> 1f27643b (Merge main)
 | 
			
		||||
): { modifiedAst: Program; pathToFilletNode: PathToNode } | Error {
 | 
			
		||||
  // Clone AST to ensure safe mutations
 | 
			
		||||
  const astClone = structuredClone(ast)
 | 
			
		||||
 | 
			
		||||
@ -25,6 +25,7 @@ type OnboardingPaths = {
 | 
			
		||||
 | 
			
		||||
const SETTINGS = '/settings' as const
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
export type ProjectRoute = {
 | 
			
		||||
  projectName: string | null
 | 
			
		||||
  projectPath: string
 | 
			
		||||
@ -32,6 +33,10 @@ export type ProjectRoute = {
 | 
			
		||||
  currentFilePath: string | null
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
||||||| parent of 1f27643b (Merge main)
 | 
			
		||||
export const paths = {
 | 
			
		||||
=======
 | 
			
		||||
>>>>>>> 1f27643b (Merge main)
 | 
			
		||||
export const PATHS = {
 | 
			
		||||
  INDEX: '/',
 | 
			
		||||
  HOME: '/home',
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,15 @@
 | 
			
		||||
import { ActionFunction, LoaderFunction, redirect } from 'react-router-dom'
 | 
			
		||||
import { FileLoaderData, HomeLoaderData, IndexLoaderData } from './types'
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
import { getProjectMetaByRouteId, PATHS } from './paths'
 | 
			
		||||
import { isDesktop } from './isDesktop'
 | 
			
		||||
||||||| parent of 1f27643b (Merge main)
 | 
			
		||||
import { isTauri } from './isTauri'
 | 
			
		||||
import { getProjectMetaByRouteId, paths } from './paths'
 | 
			
		||||
=======
 | 
			
		||||
import { isTauri } from './isTauri'
 | 
			
		||||
import { getProjectMetaByRouteId, PATHS } from './paths'
 | 
			
		||||
>>>>>>> 1f27643b (Merge main)
 | 
			
		||||
import { BROWSER_PATH } from 'lib/paths'
 | 
			
		||||
import {
 | 
			
		||||
  BROWSER_FILE_NAME,
 | 
			
		||||
@ -10,6 +18,15 @@ import {
 | 
			
		||||
} from 'lib/constants'
 | 
			
		||||
import { loadAndValidateSettings } from './settings/settingsUtils'
 | 
			
		||||
import makeUrlPathRelative from './makeUrlPathRelative'
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
||||||| parent of 1f27643b (Merge main)
 | 
			
		||||
import { sep } from '@tauri-apps/api/path'
 | 
			
		||||
import { readTextFile } from '@tauri-apps/plugin-fs'
 | 
			
		||||
import { codeManager, kclManager } from 'lib/singletons'
 | 
			
		||||
=======
 | 
			
		||||
import { sep } from '@tauri-apps/api/path'
 | 
			
		||||
import { readTextFile } from '@tauri-apps/plugin-fs'
 | 
			
		||||
>>>>>>> 1f27643b (Merge main)
 | 
			
		||||
import { codeManager } from 'lib/singletons'
 | 
			
		||||
import { fileSystemManager } from 'lang/std/fileSystemManager'
 | 
			
		||||
import {
 | 
			
		||||
@ -86,6 +103,7 @@ export const fileLoader: LoaderFunction = async (
 | 
			
		||||
    const { projectName, projectPath, currentFileName, currentFilePath } =
 | 
			
		||||
      projectPathData
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    const urlObj = new URL(routerData.request.url)
 | 
			
		||||
    let code = ''
 | 
			
		||||
 | 
			
		||||
@ -120,8 +138,50 @@ export const fileLoader: LoaderFunction = async (
 | 
			
		||||
      // the file system and not the editor.
 | 
			
		||||
      codeManager.updateCurrentFilePath(currentFilePath)
 | 
			
		||||
      codeManager.updateCodeStateEditor(code)
 | 
			
		||||
||||||| parent of 1f27643b (Merge main)
 | 
			
		||||
    if (!current_file_name || !current_file_path || !project_name) {
 | 
			
		||||
      return redirect(
 | 
			
		||||
        `${paths.FILE}/${encodeURIComponent(
 | 
			
		||||
          `${params.id}${isTauri() ? sep() : '/'}${PROJECT_ENTRYPOINT}`
 | 
			
		||||
        )}`
 | 
			
		||||
      )
 | 
			
		||||
=======
 | 
			
		||||
    if (!current_file_name || !current_file_path || !project_name) {
 | 
			
		||||
      return redirect(
 | 
			
		||||
        `${PATHS.FILE}/${encodeURIComponent(
 | 
			
		||||
          `${params.id}${isTauri() ? sep() : '/'}${PROJECT_ENTRYPOINT}`
 | 
			
		||||
        )}`
 | 
			
		||||
      )
 | 
			
		||||
>>>>>>> 1f27643b (Merge main)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
||||||| parent of 1f27643b (Merge main)
 | 
			
		||||
    // TODO: PROJECT_ENTRYPOINT is hardcoded
 | 
			
		||||
    // until we support setting a project's entrypoint file
 | 
			
		||||
    const code = await readTextFile(current_file_path)
 | 
			
		||||
 | 
			
		||||
    // Update both the state and the editor's code.
 | 
			
		||||
    // We explicitly do not write to the file here since we are loading from
 | 
			
		||||
    // the file system and not the editor.
 | 
			
		||||
    codeManager.updateCurrentFilePath(current_file_path)
 | 
			
		||||
    codeManager.updateCodeStateEditor(code)
 | 
			
		||||
 | 
			
		||||
    // We don't want to call await on execute code since we don't want to block the UI
 | 
			
		||||
    kclManager.executeCode(true)
 | 
			
		||||
 | 
			
		||||
=======
 | 
			
		||||
    // TODO: PROJECT_ENTRYPOINT is hardcoded
 | 
			
		||||
    // until we support setting a project's entrypoint file
 | 
			
		||||
    const code = await readTextFile(current_file_path)
 | 
			
		||||
 | 
			
		||||
    // Update both the state and the editor's code.
 | 
			
		||||
    // We explicitly do not write to the file here since we are loading from
 | 
			
		||||
    // the file system and not the editor.
 | 
			
		||||
    codeManager.updateCurrentFilePath(current_file_path)
 | 
			
		||||
    codeManager.updateCodeStateEditor(code)
 | 
			
		||||
 | 
			
		||||
>>>>>>> 1f27643b (Merge main)
 | 
			
		||||
    // Set the file system manager to the project path
 | 
			
		||||
    // So that WASM gets an updated path for operations
 | 
			
		||||
    fileSystemManager.dir = projectPath
 | 
			
		||||
@ -181,7 +241,14 @@ export const fileLoader: LoaderFunction = async (
 | 
			
		||||
export const homeLoader: LoaderFunction = async (): Promise<
 | 
			
		||||
  HomeLoaderData | Response
 | 
			
		||||
> => {
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
  if (!isDesktop()) {
 | 
			
		||||
||||||| parent of 1f27643b (Merge main)
 | 
			
		||||
  if (!isTauri()) {
 | 
			
		||||
    return redirect(paths.FILE + '/%2F' + BROWSER_PROJECT_NAME)
 | 
			
		||||
=======
 | 
			
		||||
  if (!isTauri()) {
 | 
			
		||||
>>>>>>> 1f27643b (Merge main)
 | 
			
		||||
    return redirect(PATHS.FILE + '/%2F' + BROWSER_PROJECT_NAME)
 | 
			
		||||
  }
 | 
			
		||||
  const { configuration } = await loadAndValidateSettings()
 | 
			
		||||
 | 
			
		||||
@ -42,7 +42,12 @@ import { Project } from 'lib/project'
 | 
			
		||||
// This route only opens in the desktop context for now,
 | 
			
		||||
// as defined in Router.tsx, so we can use the desktop APIs and types.
 | 
			
		||||
const Home = () => {
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
  const { projects: loadedProjects } = useLoaderData() as HomeLoaderData
 | 
			
		||||
||||||| parent of 1f27643b (Merge main)
 | 
			
		||||
  useRefreshSettings(paths.HOME + 'SETTINGS')
 | 
			
		||||
=======
 | 
			
		||||
>>>>>>> 1f27643b (Merge main)
 | 
			
		||||
  useRefreshSettings(PATHS.HOME + 'SETTINGS')
 | 
			
		||||
  const { commandBarSend } = useCommandsContext()
 | 
			
		||||
  const navigate = useNavigate()
 | 
			
		||||
@ -60,7 +65,14 @@ const Home = () => {
 | 
			
		||||
    e.preventDefault()
 | 
			
		||||
  })
 | 
			
		||||
  useHotkeys(
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
    isDesktop() ? 'mod+,' : 'shift+mod+,',
 | 
			
		||||
||||||| parent of 1f27643b (Merge main)
 | 
			
		||||
    isTauri() ? 'mod+,' : 'shift+mod+,',
 | 
			
		||||
    () => navigate(paths.HOME + paths.SETTINGS),
 | 
			
		||||
=======
 | 
			
		||||
    isTauri() ? 'mod+,' : 'shift+mod+,',
 | 
			
		||||
>>>>>>> 1f27643b (Merge main)
 | 
			
		||||
    () => navigate(PATHS.HOME + PATHS.SETTINGS),
 | 
			
		||||
    {
 | 
			
		||||
      splitKey: '|',
 | 
			
		||||
@ -280,8 +292,14 @@ const Home = () => {
 | 
			
		||||
          <p className="my-4 text-sm text-chalkboard-80 dark:text-chalkboard-30">
 | 
			
		||||
            Loaded from{' '}
 | 
			
		||||
            <Link
 | 
			
		||||
<<<<<<< HEAD
 | 
			
		||||
              data-testid="project-directory-settings-link"
 | 
			
		||||
              to={`${PATHS.HOME + PATHS.SETTINGS_USER}#projectDirectory`}
 | 
			
		||||
||||||| parent of 1f27643b (Merge main)
 | 
			
		||||
              to="settings?tab=user#projectDirectory"
 | 
			
		||||
=======
 | 
			
		||||
              to={`${PATHS.SETTINGS_USER}#projectDirectory`}
 | 
			
		||||
>>>>>>> 1f27643b (Merge main)
 | 
			
		||||
              className="text-chalkboard-90 dark:text-chalkboard-20 underline underline-offset-2"
 | 
			
		||||
            >
 | 
			
		||||
              {settings.app.projectDirectory.current}
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user