Skip to content

Commit e033668

Browse files
committed
Initial UI
1 parent 41c9c9d commit e033668

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+11467
-0
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
/bin
22
/.idea
3+
/static/ui

.vscode/launch.json

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
// Use IntelliSense to learn about possible attributes.
3+
// Hover to view descriptions of existing attributes.
4+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5+
"version": "0.2.0",
6+
"configurations": [
7+
{
8+
"name": "Launch file",
9+
"type": "go",
10+
"request": "launch",
11+
"mode": "debug",
12+
"program": "main.go",
13+
"args": ["--server"]
14+
}
15+
]
16+
}

Makefile

+5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
all: build-ui build
2+
3+
build-ui:
4+
$(MAKE) -C ui
5+
16
build:
27
CGO_ENABLED=0 go build -o bin/gptscript -tags "${GO_TAGS}" -ldflags "-s -w" .
38

ui/.ackrc

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
--ignore-dir=.git
2+
--ignore-dir=.nuxt
3+
--ignore-dir=.nuxt-prod
4+
--ignore-dir=.nyc_output
5+
--ignore-dir=.output
6+
--ignore-dir=.vscode
7+
--ignore-dir=coverage
8+
--ignore-dir=dist
9+
--ignore-dir=node_modules
10+
--ignore-dir=tmp
11+
--ignore-dir=vendor
12+
--ignore-file=ext:svg
13+
--ignore-file=is:selection.json
14+
--ignore-file=is:yarn.lock

ui/.dockerignore

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
node_modules
2+
.nuxt
3+
.nuxt-prod
4+
.env
5+
.nuxt
6+
.nyc_output
7+
coverage
8+
node_modules

ui/.gitignore

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Nuxt dev/build outputs
2+
.output
3+
.data
4+
.nuxt
5+
.nitro
6+
.cache
7+
dist
8+
9+
# Node dependencies
10+
node_modules
11+
12+
# Logs
13+
logs
14+
*.log
15+
16+
# Misc
17+
.DS_Store
18+
.fleet
19+
.idea
20+
21+
# Local env files
22+
.env
23+
.env.*
24+
!.env.example

ui/.vscode/settings.json

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
{
2+
"editor.codeActionsOnSave": {
3+
"source.fixAll.eslint": "explicit"
4+
},
5+
"editor.detectIndentation": false,
6+
"editor.insertSpaces": true,
7+
"editor.quickSuggestions": {
8+
"strings": true
9+
},
10+
"editor.tabSize": 2,
11+
"eslint.format.enable": true,
12+
"eslint.run": "onSave",
13+
"eslint.validate": [
14+
"vue",
15+
"html",
16+
"javascript",
17+
"typescript"
18+
],
19+
"files.associations": {
20+
"*.css": "tailwindcss"
21+
},
22+
"files.exclude": {
23+
".ackrc": true,
24+
".dockerignore": true,
25+
".drone.yml": true,
26+
".editorconfig": true,
27+
".eslintcache": true,
28+
".eslintignore": true,
29+
".eslintrc.js": true,
30+
".gitignore": true,
31+
".nuxt*": true,
32+
".nyc_output": true,
33+
"babel.config.js": true,
34+
"coverage": true,
35+
"jsconfig.json": true,
36+
"LICENSE": true,
37+
"yarn-error.log": true
38+
},
39+
"javascript.preferences.importModuleSpecifier": "non-relative",
40+
"prettier.enable": false,
41+
"tailwindCSS.classAttributes": [
42+
"class",
43+
"className",
44+
"ui"
45+
],
46+
"tailwindCSS.experimental.classRegex": [
47+
[
48+
"ui:\\s*{([^)]*)\\s*}",
49+
"[\"'`]([^\"'`]*).*?[\"'`]"
50+
],
51+
[
52+
"/\\*ui\\*/\\s*{([^;]*)}",
53+
":\\s*[\"'`]([^\"'`]*).*?[\"'`]"
54+
]
55+
],
56+
"tailwindCSS.experimental.configFile": "tailwind.config.ts",
57+
"typescript.preferences.importModuleSpecifier": "non-relative"
58+
}

ui/Acornfile

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
args: {
2+
// Number of replicas
3+
replicas: 1
4+
5+
// API Endpoint
6+
api: "https://localhost:9090/v1"
7+
}
8+
9+
services: default: {
10+
default: true
11+
ports: ["80/http"]
12+
container: "ui"
13+
}
14+
15+
containers: ui: {
16+
scale: args.replicas
17+
build: context: "."
18+
19+
env: {
20+
NUXT_PUBLIC_API: args.api
21+
}
22+
23+
ports: publish: "80/http"
24+
probes: "http://localhost/healthz"
25+
}

ui/Dockerfile

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
FROM node:18-alpine as builder
2+
ENV NODE_OPTIONS --max_old_space_size=8192
3+
WORKDIR /src
4+
COPY package.json .
5+
COPY yarn.lock .
6+
RUN yarn --pure-lockfile install
7+
COPY . .
8+
ENV NUXT_PUBLIC_APP_VERSION=${NUXT_PUBLIC_APP_VERSION:-dev}
9+
RUN yarn build
10+
11+
FROM node:18-alpine
12+
ENV HOST 0.0.0.0
13+
ENV PORT 80
14+
EXPOSE 80
15+
WORKDIR /src
16+
COPY package.json .
17+
COPY --from=builder /src/.output /src/.output
18+
ENV NUXT_PUBLIC_APP_VERSION=${NUXT_PUBLIC_APP_VERSION:-dev}
19+
CMD ["yarn","start"]

ui/Makefile

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
build: clean
2+
yarn
3+
yarn generate
4+
rm -rf ../static/ui/_nuxt
5+
cp -rp .output/public/* ../static/ui/
6+
7+
clean:
8+
yarn clean

ui/README.md

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# GPTScript UI
2+
3+
Look at the [Nuxt 3 documentation](https://nuxt.com/docs/getting-started/introduction) to learn more.
4+
5+
## Setup
6+
7+
```bash
8+
yarn install
9+
```
10+
11+
## Development Server
12+
13+
Start the development server on `http://localhost:9091`:
14+
15+
```bash
16+
yarn dev
17+
```
18+
19+
## Production
20+
21+
Build the application for embedding into GPTScript:
22+
23+
```bash
24+
yarn run generate
25+
```

ui/app.config.ts

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export default defineAppConfig({
2+
ui: {
3+
primary: 'slate',
4+
gray: 'cool',
5+
},
6+
})

ui/app.vue

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<script lang="ts" setup>
2+
import '@/styles/app.scss'
3+
4+
const sock = useSocket()
5+
</script>
6+
<template>
7+
<div class="root bg-slate-100 dark:bg-slate-950">
8+
<nav class="bg-slate-200 dark:bg-slate-900">
9+
<LeftNav />
10+
</nav>
11+
<aside class="bg-slate-200 dark:bg-slate-900">
12+
<ThemeToggle />
13+
{{sock.status}}
14+
</aside>
15+
<main>
16+
<NuxtPage />
17+
</main>
18+
</div>
19+
</template>
20+
21+
<style lang="scss" scoped>
22+
.root {
23+
--nav-width: 300px;
24+
--aside-height: 50px;
25+
26+
display: grid;
27+
grid-template-areas: "nav main"
28+
"aside main";
29+
grid-template-columns: var(--nav-width) 1fr;
30+
grid-template-rows: 1fr var(--aside-height);
31+
position: absolute;
32+
top: 0;
33+
left: 0;
34+
right: 0;
35+
bottom: 0;
36+
37+
NAV {
38+
grid-area: nav;
39+
overflow: auto;
40+
}
41+
42+
ASIDE {
43+
grid-area: aside;
44+
line-height: var(--aside-height);
45+
}
46+
47+
MAIN {
48+
grid-area: main;
49+
overflow: auto;
50+
position: relative;
51+
padding: 1rem;
52+
}
53+
}
54+
</style>

ui/components/arguments.vue

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
<script lang="ts" setup>
2+
interface Props {
3+
modelValue?: Args
4+
schema: ArgSchema
5+
}
6+
7+
const { schema, modelValue: initialState } = defineProps<Props>()
8+
const form = ref()
9+
const state = reactive(clone(initialState || {}))
10+
11+
if ( schema ) {
12+
for ( const k in schema.properties ) {
13+
if ( typeof state[k] !== 'string' ) {
14+
state[k] = ''
15+
}
16+
}
17+
}
18+
19+
// function validate(state: Args): FormError[] {
20+
// const errors: FormError[] = []
21+
function validate(state: Args) {
22+
const errors: {path: string, message: string}[] = []
23+
24+
if ( schema && schema.required?.length ) {
25+
for ( const k of schema.required ) {
26+
if ( ! (state[k] || '').trim() ) {
27+
errors.push({ path: k, message: 'Required' })
28+
}
29+
}
30+
}
31+
32+
return errors
33+
}
34+
35+
const valid = computed(() => {
36+
return form.value?.errors?.length === 0 || false
37+
})
38+
39+
defineExpose({form, valid})
40+
41+
// async function onError (event: FormErrorEvent) {
42+
async function onError (event: any) {
43+
const element = document.getElementById(event.errors[0].id)
44+
element?.focus()
45+
element?.scrollIntoView({ behavior: 'smooth', block: 'center' })
46+
}
47+
48+
// eslint-disable-next-line func-call-spacing
49+
const emit = defineEmits<{
50+
(e: 'update:modelValue', value: Args): void
51+
}>()
52+
53+
watchEffect(() => {
54+
emit('update:modelValue', state)
55+
})
56+
</script>
57+
58+
<template>
59+
<div>
60+
<UForm
61+
ref="form"
62+
:validate="validate"
63+
:state="state"
64+
class="space-y-4"
65+
@error="onError"
66+
>
67+
<template v-if="schema">
68+
<UFormGroup v-for="(p, k) in schema?.properties" :key="k" :label="k" :name="k" :required="schema.required?.includes(k)">
69+
<UTextarea autoresize :rows="1" :value="state[k]" @update:modelValue="(v) => state[k] = v" />
70+
</UFormGroup>
71+
</template>
72+
<template v-else>
73+
<UTextarea autoresize :rows="1" :value="state[k]" @update:modelValue="(v) => state[k] = v" />
74+
</template>
75+
</UForm>
76+
</div>
77+
</template>

0 commit comments

Comments
 (0)