Settings move to rust (for read/write from files) (#2220)
* start of settings types Signed-off-by: Jess Frazelle <github@jessfraz.com> * updates Signed-off-by: Jess Frazelle <github@jessfraz.com> * add validator Signed-off-by: Jess Frazelle <github@jessfraz.com> * updates Signed-off-by: Jess Frazelle <github@jessfraz.com> * start of settings in rust Signed-off-by: Jess Frazelle <github@jessfraz.com> * fix wasm Signed-off-by: Jess Frazelle <github@jessfraz.com> * fix Signed-off-by: Jess Frazelle <github@jessfraz.com> * fix wasm Signed-off-by: Jess Frazelle <github@jessfraz.com> * updates Signed-off-by: Jess Frazelle <github@jessfraz.com> * updates Signed-off-by: Jess Frazelle <github@jessfraz.com> * more tests Signed-off-by: Jess Frazelle <github@jessfraz.com> * derive docs Signed-off-by: Jess Frazelle <github@jessfraz.com> * configuration Signed-off-by: Jess Frazelle <github@jessfraz.com> * updates Signed-off-by: Jess Frazelle <github@jessfraz.com> * read and write functions with migration Signed-off-by: Jess Frazelle <github@jessfraz.com> * make more dry Signed-off-by: Jess Frazelle <github@jessfraz.com> * more parsing of app settings Signed-off-by: Jess Frazelle <github@jessfraz.com> * more things Signed-off-by: Jess Frazelle <github@jessfraz.com> * cleanup Signed-off-by: Jess Frazelle <github@jessfraz.com> * trim end Signed-off-by: Jess Frazelle <github@jessfraz.com> * project settings Signed-off-by: Jess Frazelle <github@jessfraz.com> * updates Signed-off-by: Jess Frazelle <github@jessfraz.com> * fix Signed-off-by: Jess Frazelle <github@jessfraz.com> * fixes Signed-off-by: Jess Frazelle <github@jessfraz.com> * fixes Signed-off-by: Jess Frazelle <github@jessfraz.com> * cleanup tauri commands Signed-off-by: Jess Frazelle <github@jessfraz.com> * updates Signed-off-by: Jess Frazelle <github@jessfraz.com> * refactor Signed-off-by: Jess Frazelle <github@jessfraz.com> * refactor Signed-off-by: Jess Frazelle <github@jessfraz.com> * updates Signed-off-by: Jess Frazelle <github@jessfraz.com> * updates Signed-off-by: Jess Frazelle <github@jessfraz.com> * updates Signed-off-by: Jess Frazelle <github@jessfraz.com> * change to files Signed-off-by: Jess Frazelle <github@jessfraz.com> * better Signed-off-by: Jess Frazelle <github@jessfraz.com> * cleanup more Signed-off-by: Jess Frazelle <github@jessfraz.com> * get rid of dead code Signed-off-by: Jess Frazelle <github@jessfraz.com> * fixed Signed-off-by: Jess Frazelle <github@jessfraz.com> * updates Signed-off-by: Jess Frazelle <github@jessfraz.com> * cleanup some more shit Signed-off-by: Jess Frazelle <github@jessfraz.com> * updates Signed-off-by: Jess Frazelle <github@jessfraz.com> * updates Signed-off-by: Jess Frazelle <github@jessfraz.com> * updates Signed-off-by: Jess Frazelle <github@jessfraz.com> * updates Signed-off-by: Jess Frazelle <github@jessfraz.com> * add validation Signed-off-by: Jess Frazelle <github@jessfraz.com> * validation Signed-off-by: Jess Frazelle <github@jessfraz.com> * validate Signed-off-by: Jess Frazelle <github@jessfraz.com> * validate Signed-off-by: Jess Frazelle <github@jessfraz.com> * clippuy Signed-off-by: Jess Frazelle <github@jessfraz.com> * clippuy Signed-off-by: Jess Frazelle <github@jessfraz.com> * fix; Signed-off-by: Jess Frazelle <github@jessfraz.com> --------- Signed-off-by: Jess Frazelle <github@jessfraz.com>
This commit is contained in:
@ -15,10 +15,10 @@ import {
|
||||
import { useCommandsContext } from 'hooks/useCommandsContext'
|
||||
import { fileMachine } from 'machines/fileMachine'
|
||||
import { mkdir, remove, rename, create } from '@tauri-apps/plugin-fs'
|
||||
import { readProject } from 'lib/tauriFS'
|
||||
import { isTauri } from 'lib/isTauri'
|
||||
import { join, sep } from '@tauri-apps/api/path'
|
||||
import { DEFAULT_FILE_NAME, FILE_EXT } from 'lib/constants'
|
||||
import { getProjectInfo } from 'lib/tauri'
|
||||
|
||||
type MachineContext<T extends AnyStateMachine> = {
|
||||
state: StateFrom<T>
|
||||
@ -62,7 +62,7 @@ export const FileMachineProvider = ({
|
||||
services: {
|
||||
readFiles: async (context: ContextFrom<typeof fileMachine>) => {
|
||||
const newFiles = isTauri()
|
||||
? await readProject(context.project.path)
|
||||
? (await getProjectInfo(context.project.name)).children
|
||||
: []
|
||||
return {
|
||||
...context.project,
|
||||
|
@ -94,10 +94,7 @@ export function HelpMenu(props: React.PropsWithChildren) {
|
||||
if (isInProject) {
|
||||
navigate('onboarding')
|
||||
} else {
|
||||
createAndOpenNewProject(
|
||||
settings.context.app.projectDirectory.current,
|
||||
navigate
|
||||
)
|
||||
createAndOpenNewProject(navigate)
|
||||
}
|
||||
}}
|
||||
>
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { FormEvent, useEffect, useRef, useState } from 'react'
|
||||
import { type ProjectWithEntryPointMetadata } from 'lib/types'
|
||||
import { paths } from 'lib/paths'
|
||||
import { Link } from 'react-router-dom'
|
||||
import { ActionButton } from './ActionButton'
|
||||
@ -9,11 +8,11 @@ import {
|
||||
faTrashAlt,
|
||||
faX,
|
||||
} from '@fortawesome/free-solid-svg-icons'
|
||||
import { getPartsCount, readProject } from '../lib/tauriFS'
|
||||
import { FILE_EXT } from 'lib/constants'
|
||||
import { Dialog } from '@headlessui/react'
|
||||
import { useHotkeys } from 'react-hotkeys-hook'
|
||||
import Tooltip from './Tooltip'
|
||||
import { Project } from 'wasm-lib/kcl/bindings/Project'
|
||||
|
||||
function ProjectCard({
|
||||
project,
|
||||
@ -21,17 +20,17 @@ function ProjectCard({
|
||||
handleDeleteProject,
|
||||
...props
|
||||
}: {
|
||||
project: ProjectWithEntryPointMetadata
|
||||
project: Project
|
||||
handleRenameProject: (
|
||||
e: FormEvent<HTMLFormElement>,
|
||||
f: ProjectWithEntryPointMetadata
|
||||
f: Project
|
||||
) => Promise<void>
|
||||
handleDeleteProject: (f: ProjectWithEntryPointMetadata) => Promise<void>
|
||||
handleDeleteProject: (f: Project) => Promise<void>
|
||||
}) {
|
||||
useHotkeys('esc', () => setIsEditing(false))
|
||||
const [isEditing, setIsEditing] = useState(false)
|
||||
const [isConfirmingDelete, setIsConfirmingDelete] = useState(false)
|
||||
const [numberOfParts, setNumberOfParts] = useState(1)
|
||||
const [numberOfFiles, setNumberOfFiles] = useState(1)
|
||||
const [numberOfFolders, setNumberOfFolders] = useState(0)
|
||||
|
||||
let inputRef = useRef<HTMLInputElement>(null)
|
||||
@ -41,7 +40,8 @@ function ProjectCard({
|
||||
void handleRenameProject(e, project).then(() => setIsEditing(false))
|
||||
}
|
||||
|
||||
function getDisplayedTime(date: Date) {
|
||||
function getDisplayedTime(dateStr: string) {
|
||||
const date = new Date(dateStr)
|
||||
const startOfToday = new Date()
|
||||
startOfToday.setHours(0, 0, 0, 0)
|
||||
return date.getTime() < startOfToday.getTime()
|
||||
@ -50,15 +50,12 @@ function ProjectCard({
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
async function getNumberOfParts() {
|
||||
const { kclFileCount, kclDirCount } = getPartsCount(
|
||||
await readProject(project.path)
|
||||
)
|
||||
setNumberOfParts(kclFileCount)
|
||||
setNumberOfFolders(kclDirCount)
|
||||
async function getNumberOfFiles() {
|
||||
setNumberOfFiles(project.kcl_file_count)
|
||||
setNumberOfFolders(project.directory_count)
|
||||
}
|
||||
void getNumberOfParts()
|
||||
}, [project.path])
|
||||
void getNumberOfFiles()
|
||||
}, [project.kcl_file_count, project.directory_count])
|
||||
|
||||
useEffect(() => {
|
||||
if (inputRef.current) {
|
||||
@ -129,7 +126,7 @@ function ProjectCard({
|
||||
{project.name?.replace(FILE_EXT, '')}
|
||||
</Link>
|
||||
<span className="text-chalkboard-60 text-xs">
|
||||
{numberOfParts} part{numberOfParts === 1 ? '' : 's'}{' '}
|
||||
{numberOfFiles} file{numberOfFiles === 1 ? '' : 's'}{' '}
|
||||
{numberOfFolders > 0 &&
|
||||
`/ ${numberOfFolders} folder${
|
||||
numberOfFolders === 1 ? '' : 's'
|
||||
@ -137,8 +134,8 @@ function ProjectCard({
|
||||
</span>
|
||||
<span className="text-chalkboard-60 text-xs">
|
||||
Edited{' '}
|
||||
{project.entrypointMetadata.mtime
|
||||
? getDisplayedTime(project.entrypointMetadata.mtime)
|
||||
{project.metadata && project.metadata?.modified
|
||||
? getDisplayedTime(project.metadata.modified)
|
||||
: 'never'}
|
||||
</span>
|
||||
<div className="absolute z-10 bottom-2 right-2 flex gap-1 items-center opacity-0 group-hover:opacity-100 group-focus-within:opacity-100">
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { fireEvent, render, screen } from '@testing-library/react'
|
||||
import { BrowserRouter } from 'react-router-dom'
|
||||
import ProjectSidebarMenu from './ProjectSidebarMenu'
|
||||
import { type ProjectWithEntryPointMetadata } from 'lib/types'
|
||||
import { SettingsAuthProviderJest } from './SettingsAuthProvider'
|
||||
import { APP_NAME } from 'lib/constants'
|
||||
import { CommandBarProvider } from './CommandBar/CommandBarProvider'
|
||||
import { Project } from 'wasm-lib/kcl/bindings/Project'
|
||||
|
||||
const now = new Date()
|
||||
const projectWellFormed = {
|
||||
@ -14,29 +14,17 @@ const projectWellFormed = {
|
||||
{
|
||||
name: 'main.kcl',
|
||||
path: '/some/path/Simple Box/main.kcl',
|
||||
children: [],
|
||||
},
|
||||
],
|
||||
entrypointMetadata: {
|
||||
atime: now,
|
||||
blksize: 32,
|
||||
blocks: 32,
|
||||
birthtime: now,
|
||||
dev: 1,
|
||||
gid: 1,
|
||||
ino: 1,
|
||||
isDirectory: false,
|
||||
isFile: true,
|
||||
isSymlink: false,
|
||||
mode: 1,
|
||||
mtime: now,
|
||||
nlink: 1,
|
||||
readonly: false,
|
||||
rdev: 1,
|
||||
metadata: {
|
||||
created: now.toISOString(),
|
||||
modified: now.toISOString(),
|
||||
size: 32,
|
||||
uid: 1,
|
||||
fileAttributes: null,
|
||||
},
|
||||
} satisfies ProjectWithEntryPointMetadata
|
||||
kcl_file_count: 1,
|
||||
directory_count: 0,
|
||||
} satisfies Project
|
||||
|
||||
describe('ProjectSidebarMenu tests', () => {
|
||||
test('Renders the project name', () => {
|
||||
|
@ -133,13 +133,13 @@ function ProjectMenuPopover({
|
||||
<p className="m-0 text-mono" data-testid="projectName">
|
||||
{project?.name ? project.name : APP_NAME}
|
||||
</p>
|
||||
{project?.entrypointMetadata && (
|
||||
{project?.metadata && project.metadata.created && (
|
||||
<p
|
||||
className="m-0 text-xs text-chalkboard-80 dark:text-chalkboard-40"
|
||||
data-testid="createdAt"
|
||||
>
|
||||
Created{' '}
|
||||
{project.entrypointMetadata.birthtime?.toLocaleDateString()}
|
||||
{new Date(project.metadata.created).toLocaleDateString()}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
|
@ -168,7 +168,7 @@ export const SettingsAuthProviderBase = ({
|
||||
},
|
||||
'Execute AST': () => kclManager.executeCode(true),
|
||||
persistSettings: (context) =>
|
||||
saveSettings(context, loadedProject?.project?.path),
|
||||
saveSettings(context, loadedProject?.project?.name),
|
||||
},
|
||||
}
|
||||
)
|
||||
|
Reference in New Issue
Block a user