Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,14 @@ Using python3.10 (3.10.13)

Notice the environment prefix `(openadapt-py3.10)`.

### Tray
Run the following command to start the system tray icon and launch the web dashboard:

```
python -m openadapt.entrypoint
```
This command will print the config, update the database to the latest migration, start the system tray icon and launch the web dashboard.

### Record

Create a new recording by running the following command:
Expand Down
4 changes: 3 additions & 1 deletion openadapt/app/dashboard/api/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ def attach_routes(self) -> APIRouter:
self.app.add_api_route("", self.set_settings, methods=["POST"])
return self.app

Category = Literal["api_keys", "scrubbing", "record_and_replay", "general"]
Category = Literal[
"api_keys", "scrubbing", "record_and_replay", "general", "onboarding"
]

@staticmethod
def get_settings(category: Category) -> dict[str, Any]:
Expand Down
7 changes: 3 additions & 4 deletions openadapt/app/dashboard/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { ColorSchemeScript, MantineProvider } from '@mantine/core'
import { Notifications } from '@mantine/notifications';
import { Shell } from '@/components/Shell'
import { CSPostHogProvider } from './providers';
import { ModalsProvider } from '@mantine/modals';

export const metadata = {
title: 'OpenAdapt.AI',
Expand All @@ -24,9 +23,9 @@ export default function RootLayout({
<body>
<MantineProvider>
<Notifications />
<ModalsProvider>
<Shell>{children}</Shell>
</ModalsProvider>
<Shell>
{children}
</Shell>
</MantineProvider>
</body>
</CSPostHogProvider>
Expand Down
16 changes: 16 additions & 0 deletions openadapt/app/dashboard/app/onboarding/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { BookACall } from "@/components/Onboarding/steps/BookACall";
import { RegisterForUpdates } from "@/components/Onboarding/steps/RegisterForUpdates";
import { Tutorial } from "@/components/Onboarding/steps/Tutorial";
import { Box, Divider } from "@mantine/core";

export default function Onboarding() {
return (
<Box w="fit-content" mx="auto">
<RegisterForUpdates />
<Divider my={20} w="40vw" mx="auto" />
<BookACall />
<Divider my={20} w="40vw" mx="auto" />
<Tutorial />
</Box>
);
}
4 changes: 2 additions & 2 deletions openadapt/app/dashboard/app/recordings/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export default function Recordings() {
}, []);
return (
<Box>
{recordingStatus === RecordingStatus.RECORDING && (
{/* {recordingStatus === RecordingStatus.RECORDING && (
<Button onClick={stopRecording} variant="outline" color="red">
Stop recording
</Button>
Expand All @@ -64,7 +64,7 @@ export default function Recordings() {
<Button variant="outline" color="blue">
Loading recording status...
</Button>
)}
)} */}
<Tabs defaultValue="regular" mt={40}>
<Tabs.List>
<Tabs.Tab value="regular">
Expand Down
4 changes: 4 additions & 0 deletions openadapt/app/dashboard/app/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,9 @@ export const routes: Route[] = [
{
name: 'Scrubbing',
path: '/scrubbing',
},
{
name: 'Onboarding',
path: '/onboarding',
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Box, Text } from '@mantine/core'
import Link from 'next/link'
import React from 'react'

export const BookACall = () => {
return (
<Box w="fit-content">
<Text>
<Link href="https://www.getclockwise.com/c/richard-abrich/quick-meeting" className='no-underline'>
Book a call with us
</Link>
<Text component='span'> to discuss how OpenAdapt can help your team</Text>
</Text>
</Box>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
'use client';


import { Box, Button, Stack, Text, TextInput } from '@mantine/core'
import { isNotEmpty, useForm } from '@mantine/form'
import { notifications } from '@mantine/notifications'
import React, { useEffect } from 'react'

export const RegisterForUpdates = () => {
const onboardingForm = useForm({
initialValues: {
email: '',
},
validate: {
email: isNotEmpty('Email is required'),
}
})
useEffect(() => {
fetch('/api/settings', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
REDIRECT_TO_ONBOARDING: false
}),
})
}, [])
function onSubmit({ email }: { email: string }) {
fetch('https://openadapt.ai/form.html', {
method: 'POST',
mode: 'no-cors',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: new URLSearchParams({
email,
'form-name': 'email',
'bot-field': '',
}).toString(),
}).then(() => {
notifications.show({
title: 'Thank you!',
message: 'You have been registered for updates',
color: 'green',
})
})
}
return (
<Box maw={600}>
<Stack gap="xs">
<form onSubmit={onboardingForm.onSubmit(onSubmit)}>
<TextInput
placeholder="Email (optional)"
label="Register for updates"
description="We promise not to spam!"
type="email"
{...onboardingForm.getInputProps('email')}
/>
<Button type="submit" mt={10}>
Register
</Button>
</form>
</Stack>
</Box>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
'use client';

import { Box, Text } from '@mantine/core'
import { algora, type AlgoraOutput } from '@algora/sdk';
import React, { useEffect } from 'react'
import Link from 'next/link';

type Bounty = AlgoraOutput['bounty']['list']['items'][number];

function BountyCard(props: { bounty: Bounty }) {
return (
<Link
href={props.bounty.task.url}
target="_blank"
rel="noopener"
className="block group relative h-full rounded-lg border border-gray-400/50 dark:border-indigo-500/50 bg-gradient-to-br from-gray-300/30 via-gray-300/40 to-gray-300/50 dark:from-indigo-600/20 dark:via-indigo-600/30 dark:to-indigo-600/40 md:gap-8 transition-colors hover:border-gray-400 hover:dark:border-indigo-500 hover:bg-gray-300/10 hover:dark:bg-gray-600/5 !no-underline"
>
<div className="relative h-full p-4">
<div className="text-2xl font-bold text-green-500 group-hover:text-green-600 dark:text-green-400 dark:group-hover:text-green-300 transition-colors">
{props.bounty.reward_formatted}
</div>
<div className="mt-0.5 text-sm text-gray-700 dark:text-indigo-200 group-hover:text-gray-800 dark:group-hover:text-indigo-100 transition-colors">
{props.bounty.task.repo_name}#{props.bounty.task.number}
</div>
<div className="mt-3 line-clamp-1 break-words text-lg font-medium leading-tight text-gray-800 dark:text-indigo-50 group-hover:text-gray-900 dark:group-hover:text-white">
{props.bounty.task.title}
</div>
</div>
</Link>
);
}

const featuredBountyId = 'clxi7tk210002l20aqlz58ram';

async function getFeaturedBounty() {
const bounty: Bounty = await algora.bounty.get.query({ id: featuredBountyId });
return bounty;
}

export const Tutorial = () => {
const [featuredBounty, setFeaturedBounty] = React.useState<Bounty | null>(null);
useEffect(() => {
getFeaturedBounty().then(setFeaturedBounty);
}, []);
return (
<Box>
<Text my={20} maw={800}>
Welcome to OpenAdapt! Thank you for joining us on our mission to build open source desktop AI. Your feedback is extremely valuable!
</Text>
<Text my={20} maw={800}>
To start, please watch the demonstration below. Then try it yourself! If you have any issues, please submit a <Link href='https://github.com/OpenAdaptAI/OpenAdapt/issues/new/choose' className='no-underline'>Github Issue.</Link>
</Text>
<iframe width="800" height="400" src="https://www.youtube.com/embed/OVERugs50cQ?si=cmi1vY73ADom9EKG" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerPolicy="strict-origin-when-cross-origin" allowFullScreen className='block mx-auto'></iframe>
<Text my={20} maw={800}>
If you'd like to contribute directly to our development, please consider the following open Bounties (no development experience required):
{featuredBounty && <BountyCard bounty={featuredBounty} />}
</Text>
</Box>
)
}
8 changes: 6 additions & 2 deletions openadapt/app/dashboard/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const checkPort = (port) => {
}

// check if both ports are not being used
const { DASHBOARD_CLIENT_PORT, DASHBOARD_SERVER_PORT } = process.env
const { DASHBOARD_CLIENT_PORT, DASHBOARD_SERVER_PORT, REDIRECT_TO_ONBOARDING } = process.env
Promise.all([checkPort(DASHBOARD_CLIENT_PORT), checkPort(DASHBOARD_SERVER_PORT)])
.then(([clientPort, serverPort]) => {
if (clientPort !== DASHBOARD_CLIENT_PORT) {
Expand Down Expand Up @@ -45,7 +45,11 @@ function spawnChildProcess() {
// wait for 3 seconds before opening the browser
setTimeout(() => {
import('open').then(({ default: open }) => {
open(`http://localhost:${DASHBOARD_CLIENT_PORT}`)
let url = `http://localhost:${DASHBOARD_CLIENT_PORT}`
if (REDIRECT_TO_ONBOARDING === 'true') {
url += '/onboarding'
}
open(url)
})
}, 3000)
})
Expand Down
66 changes: 66 additions & 0 deletions openadapt/app/dashboard/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions openadapt/app/dashboard/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"format": "prettier --write ."
},
"dependencies": {
"@algora/sdk": "^0.2.0",
"@mantine/carousel": "7.7.1",
"@mantine/core": "7.7.1",
"@mantine/form": "7.7.1",
Expand Down
Loading