Skip to content

Commit

Permalink
added in app route
Browse files Browse the repository at this point in the history
  • Loading branch information
whkelvin committed Dec 30, 2024
1 parent e891e30 commit 9bc7d11
Show file tree
Hide file tree
Showing 23 changed files with 586 additions and 75 deletions.
4 changes: 4 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ RUN mkdir /app
COPY . /app

WORKDIR /app
# csrf check is disabled for local development
RUN rm svelte.config.js
# csrf check is enabled for prod
RUN mv svelte.config.prod.js svelte.config.js
RUN npm install
RUN npm run build

Expand Down
4 changes: 2 additions & 2 deletions spec/yizy-spec.json
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@
{
"name": "getSpecs",
"description": "gets a list of spec that belongs to the user",
"url": "/api/specs/getSpecs",
"url": "/api/spec/getSpecs",
"requestModel": {
"name": "GetSpecsRequest",
"fields": [
Expand Down Expand Up @@ -132,7 +132,7 @@
{
"name": "getLatestSpecById",
"description": "gets the latest snapshot of a spec by id",
"url": "/api/specs/getLatestSpecById",
"url": "/api/spec/getLatestSpecById",
"requestModel": {
"name": "GetLatestSpecByIdRequest",
"fields": [
Expand Down
3 changes: 3 additions & 0 deletions src/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@
}
body {
@apply bg-background text-foreground;
margin: 0;
height: 100%;
overflow: hidden;
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/lib/api-client/yizyClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ export async function getSpecs(
defaultHeaders = { ...defaultHeaders, ...headers };
}

const response = await fetch("http://localhost:5173/api/specs/getSpecs", {
const response = await fetch("http://localhost:5173/api/spec/getSpecs", {
method: "POST",
headers: defaultHeaders,
body: JSON.stringify(req),
Expand All @@ -151,7 +151,7 @@ export async function getLatestSpecById(
}

const response = await fetch(
"http://localhost:5173/api/specs/getLatestSpecById",
"http://localhost:5173/api/spec/getLatestSpecById",
{
method: "POST",
headers: defaultHeaders,
Expand Down
2 changes: 1 addition & 1 deletion src/lib/components/ui/editor/YizyEditor.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@
});
</script>

<div class="w-full p-6 pb-20">
<div class="w-full pb-20">
<div class="mx-auto grid w-full grid-cols-1 rounded-lg lg:grid-cols-5 lg:gap-2">
<div class="col-span-1 rounded-lg px-6 pr-10 pt-4 lg:col-span-3 lg:pb-4">
<div class="mt-4 border-muted lg:mb-2">
Expand Down
69 changes: 49 additions & 20 deletions src/lib/components/ui/editor/models/models.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,3 @@
//import {
// type ArrayType,
// arrayType,
// type DataType,
// type Field as YizyField,
// type FieldDataType,
// isPrimitiveType,
// type NullableArrayType,
// nullableArrayType,
// type NullableReferenceType,
// nullableReferenceType,
// type ObjectType,
// objectType,
// type PrimitiveTypes,
// type ReferenceType,
// type Service,
// TypeIdentifier,
//} from "@yizy/spec";
import { ProgrammingLanguage } from "$lib/models/constants";
import * as yizy from "@yizy/spec";

Expand All @@ -27,6 +9,53 @@ export interface Document {
additionalModels: Model[];
}

export const DEFAULT_DOCUMENT: Document = {
name: "",
description: "",
environment: [
{
name: "",
baseUrl: "",
},
],
endpoints: [
{
name: "",
url: "",
description: "",
req: {
name: "",
fields: [
{
name: "",
type: "",
},
],
},
res: {
name: "",
fields: [
{
name: "",
type: "",
},
],
},
},
],
additionalModels: [
{
name: "",
fields: [
{
name: "",
type: "",
},
],
},
],
};

export interface Environment {
name: string;
baseUrl: string;
Expand Down Expand Up @@ -128,7 +157,7 @@ export function docToYizySpec(doc: Document): yizy.Service {
return service;
}

function specTypeToNativeType(dataType: yizy.Datatype): string {
function specTypeToNativeType(dataType: yizy.DataType): string {
const typeMap = {
float: "float",
"float?": "float?",
Expand Down Expand Up @@ -165,7 +194,7 @@ function specTypeToNativeType(dataType: yizy.Datatype): string {
return typeof (dataType as yizy.NullableObjectType).name === "string"
? (((dataType as yizy.NullableObjectType).name + "?") as string)
: yizy.getLanguageSpecificName(
(dataType as yizy.NullableObjectType).name as NameMap,
(dataType as yizy.NullableObjectType).name as yizy.NameMap,
ProgrammingLanguage.Typescript,
) + "?";
case yizy.TypeIdentifier.ReferenceType:
Expand Down
File renamed without changes.
185 changes: 176 additions & 9 deletions src/routes/(app)/app/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,12 +1,121 @@
<script lang="ts">
import { Files, User, Plus } from 'lucide-svelte';
import * as Tabs from '$lib/components/ui/tabs';
import { Files, User, Plus, LoaderCircle } from 'lucide-svelte';
import YizyLogo from '$lib/components/ui/YIZYLogo.svelte';
import * as yizy from '$lib/api-client/yizyClient';
import { onMount } from 'svelte';
import { Button } from '$lib/components/ui/button/index.js';
import * as Dialog from '$lib/components/ui/dialog/index.js';
import { Input } from '$lib/components/ui/input/index.js';
import { Label } from '$lib/components/ui/label/index.js';
import { currentService } from '$lib/state';
import { yizySpecToDoc } from '$lib/components/ui/editor/models/models';
import * as yizySpec from '@yizy/spec';
import CodeTab from './components/CodeTab.svelte';
import SpecTab from './components/SpecTab.svelte';
import { DEFAULT_DOCUMENT } from '$lib/components/ui/editor/models/models';
let { data } = $props();
interface SpecDto {
id: string;
name: string;
}
interface SpecDetailDto {
id: string;
snapshotId: string;
}
let doc = $state(yizySpecToDoc($currentService));
let specs: SpecDto[] = $state([]);
let selectedSpec: SpecDto | null = $state(null);
let selectedSpecDetails: SpecDetailDto | null = $state(null);
let specContent: string = $state('');
let isContentLoading: boolean = $state(false);
let createSpecDialogSpecName: string = $state('');
let isCreateSpecDialogOpen: boolean = $state(false);
function closeCreateSpecDialog() {
isCreateSpecDialogOpen = false;
}
function isSelectedSpec(spec: SpecDto) {
if (!selectedSpec) return false;
return spec.id == selectedSpec.id;
}
async function selectSpecClicked(spec: SpecDto) {
selectedSpec = spec;
isContentLoading = true;
const res = await yizy.getLatestSpecById({ id: spec.id });
if (res.error === null && res.result !== null) {
selectedSpecDetails = {
id: spec.id,
snapshotId: res.result.snapshotId
};
specContent = res.result?.content;
try {
const service = JSON.parse(specContent) as yizySpec.Service;
doc = yizySpecToDoc(service);
} catch (e) {
console.log('cannot parse spec!');
doc = DEFAULT_DOCUMENT;
}
}
isContentLoading = false;
}
async function createSpecDialogSaveBtnClicked() {
if (data.authState) {
const res = await yizy.createSpec({
name: createSpecDialogSpecName,
creatorUserId: data.authState?.user.uuid
});
if (res.error === null && res.result != null) {
specs = specs.concat(res.result);
closeCreateSpecDialog();
}
} else {
console.log('please login!');
}
}
async function updateSpecBtnClicked(specContent: string) {
if (data.authState && selectedSpecDetails) {
const res = await yizy.updateSpec({
specId: selectedSpecDetails.id,
content: specContent,
updatorUserId: data.authState.user.uuid,
prevSpecSnapshotId: selectedSpecDetails.snapshotId
});
if (res.error == null && res.result != null) {
selectedSpecDetails = {
snapshotId: res.result?.prevSnapshotId,
id: selectedSpecDetails.id
};
}
return;
} else {
console.log('please login!');
}
}
onMount(async () => {
if (data.authState) {
const res = await yizy.getSpecs({
userId: data.authState?.user.uuid
});
if (res.error == null) {
specs = res.result.resultset;
}
}
});
</script>

<div class="flex h-full flex-row">
<div class="flex h-full w-1/5 flex-col border-r">
<div class="flex h-full flex-row">
<div class="flex h-screen flex-row">
<div class="flex h-screen w-1/5 flex-col border-r">
<div class="flex h-full w-full flex-row">
<div class="flex h-full w-12 flex-col gap-3 bg-secondary px-2 py-4">
<button class="w-full"><Files class="h-8 w-8" /></button>
<button class="w-full"><User class="h-8 w-8 text-muted" /></button>
Expand All @@ -16,13 +125,71 @@
<YizyLogo />
</div>
<div class="flex flex-row justify-between bg-border px-2 py-1">
<div class="my-auto text-sm">My Specs</div>
<button class="my-auto h-5"><Plus class="h-full" /></button>
<div class="my-auto text-sm font-bold">My Specs</div>
<Dialog.Root bind:open={isCreateSpecDialogOpen}>
<Dialog.Trigger class="my-auto flex">
<Plus class="h-5" />
</Dialog.Trigger>
<Dialog.Content class="sm:max-w-[425px]">
<Dialog.Header>
<Dialog.Title>Create New API Spec</Dialog.Title>
<Dialog.Description>Create a new API spec</Dialog.Description>
</Dialog.Header>
<div class="grid gap-4 py-4">
<div class="grid grid-cols-4 items-center gap-4">
<Label for="name" class="text-right">Name</Label>
<Input
id="name"
placeholder="My API Service"
class="col-span-3"
bind:value={createSpecDialogSpecName} />
</div>
</div>
<Dialog.Footer>
<Button
onclick={async () => {
await createSpecDialogSaveBtnClicked();
}}>Create</Button>
</Dialog.Footer>
</Dialog.Content>
</Dialog.Root>
</div>
{#each specs as s}
{#if isSelectedSpec(s)}
<button class="bg-primary px-2 py-1 text-left text-sm text-primary-foreground"
>{s.name}</button>
{:else}
<button
class="px-2 py-1 text-left text-sm hover:bg-primary hover:text-primary-foreground"
onclick={async () => {
selectSpecClicked(s);
}}>{s.name}</button>
{/if}
{/each}
</div>
</div>
</div>
<div class="flex w-4/5 p-2">
<div class="m-auto">Create a new spec</div>

<div class="flex h-full w-4/5 flex-col overflow-y-scroll">
{#if isContentLoading}
<div class="m-auto">
<LoaderCircle class="animate-spin text-primary" />
</div>
{:else if selectedSpec === null}
<div class="m-auto">Select a spec or Create a new spec</div>
{:else}
<Tabs.Root value="api-spec" class="w-full p-4">
<Tabs.List class="grid w-full grid-cols-2">
<Tabs.Trigger value="api-spec">Edit Spec</Tabs.Trigger>
<Tabs.Trigger value="code-gen">Generate Code</Tabs.Trigger>
</Tabs.List>
<Tabs.Content value="api-spec">
<SpecTab bind:doc onGenerateBtnClicked={updateSpecBtnClicked}></SpecTab>
</Tabs.Content>
<Tabs.Content value="code-gen">
<CodeTab bind:doc />
</Tabs.Content>
</Tabs.Root>
{/if}
</div>
</div>
Loading

0 comments on commit 9bc7d11

Please sign in to comment.