Skip to content

Commit

Permalink
feat(insights): basic UI for seeing symbols
Browse files Browse the repository at this point in the history
  • Loading branch information
mhevery committed Jun 22, 2023
1 parent 9b7da10 commit 7f1e135
Show file tree
Hide file tree
Showing 17 changed files with 462 additions and 53 deletions.
5 changes: 1 addition & 4 deletions packages/docs/src/root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,7 @@ export default component$(() => {
<RouterHead />
<ServiceWorkerRegister />
{/* <script dangerouslySetInnerHTML={`(${collectSymbols})()`} /> */}
<Insights
publicApiKey={import.meta.env.PUBLIC_QWIK_INSIGHTS_KEY}
postUrl={'/api/v1/${publicApiKey}/post/'}
/>
<Insights publicApiKey={import.meta.env.PUBLIC_QWIK_INSIGHTS_KEY} />
</head>
<body
class={{
Expand Down
24 changes: 14 additions & 10 deletions packages/docs/vite.config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { defineConfig } from 'vite';
import { defineConfig, loadEnv } from 'vite';
import { qwikVite } from '@builder.io/qwik/optimizer';
import { resolve } from 'node:path';
import { qwikCity } from '@builder.io/qwik-city/vite';
Expand All @@ -7,6 +7,7 @@ import { examplesData, playgroundData, tutorialData } from './vite.repl-apps';
import { sourceResolver } from './vite.source-resolver';
import { qwikReact } from '@builder.io/qwik-react/vite';
import Inspect from 'vite-plugin-inspect';
import { insightsEntryStrategy } from '../qwik-labs/src';

export default defineConfig(async () => {
const { default: rehypePrettyCode } = await import('rehype-pretty-code');
Expand Down Expand Up @@ -86,15 +87,18 @@ export default defineConfig(async () => {
},
}),
qwikVite({
entryStrategy: {
type: 'smart',
manual: {
...page,
...menus,
...algoliaSearch,
...repl,
},
},
entryStrategy: await insightsEntryStrategy({
publicApiKey: loadEnv('', '.').PUBLIC_QWIK_INSIGHT_KEY,
}),
// entryStrategy: {
// type: 'smart',
// manual: {
// ...page,
// ...menus,
// ...algoliaSearch,
// ...repl,
// },
// },
}),
partytownVite({
dest: resolve('dist', '~partytown'),
Expand Down
1 change: 1 addition & 0 deletions packages/insights/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
},
"dependencies": {
"@libsql/client": "^0.2.1",
"@modular-forms/qwik": "^0.12.0",
"dotenv": "^16.3.1",
"drizzle-kit": "^0.19.1",
"drizzle-orm": "^0.27.0"
Expand Down
22 changes: 22 additions & 0 deletions packages/insights/src/components/icons/edit.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { type QwikIntrinsicElements } from '@builder.io/qwik';

export const EditIcon = function MaterialSymbolsEditSquareOutlineRounded(
props: QwikIntrinsicElements['svg'],
key: string
) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width="1em"
height="1em"
viewBox="0 0 24 24"
{...props}
key={key}
>
<path
fill="black"
d="M5 23.7q-.825 0-1.413-.587T3 21.7v-14q0-.825.588-1.413T5 5.7h8.925l-2 2H5v14h14v-6.95l2-2v8.95q0 .825-.588 1.413T19 23.7H5Zm7-9Zm4.175-8.425l1.425 1.4l-6.6 6.6V15.7h1.4l6.625-6.625l1.425 1.4l-6.625 6.625q-.275.275-.638.438t-.762.162H10q-.425 0-.713-.288T9 16.7v-2.425q0-.4.15-.763t.425-.637l6.6-6.6Zm4.275 4.2l-4.275-4.2l2.5-2.5q.6-.6 1.438-.6t1.412.6l1.4 1.425q.575.575.575 1.4T22.925 8l-2.475 2.475Z"
></path>
</svg>
);
};
22 changes: 22 additions & 0 deletions packages/insights/src/components/icons/error.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { type QwikIntrinsicElements } from '@builder.io/qwik';

export const ErrorIcon = function MaterialSymbolsChatErrorSharp(
props: QwikIntrinsicElements['svg'],
key: string
) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width="1em"
height="1em"
viewBox="0 0 24 24"
{...props}
key={key}
>
<path
fill="darkred"
d="M2 22V2h20v16H6l-4 4Zm7.4-8l2.6-2.6l2.6 2.6l1.4-1.4l-2.6-2.6L16 7.4L14.6 6L12 8.6L9.4 6L8 7.4l2.6 2.6L8 12.6L9.4 14Z"
></path>
</svg>
);
};
22 changes: 22 additions & 0 deletions packages/insights/src/components/icons/slow.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { type QwikIntrinsicElements } from '@builder.io/qwik';

export const SlowIcon = function FluentAnimalTurtle24Regular(
props: QwikIntrinsicElements['svg'],
key: string
) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width="1em"
height="1em"
viewBox="0 0 24 24"
{...props}
key={key}
>
<path
fill="currentColor"
d="M10.997 5.998a6.14 6.14 0 0 1 5.8 4.126l.075.233l.044.144h2.33a2.749 2.749 0 0 1 2.744 2.582l.005.167v1a1.75 1.75 0 0 1-1.606 1.743l-.143.005H18.62l.241.584a1.75 1.75 0 0 1-.813 2.22l-.137.064a1.749 1.749 0 0 1-.496.124l-.171.008h-1.787a1.75 1.75 0 0 1-1.51-.867l-.072-.137l-.539-1.143l.054-.007c-1.4.186-2.817.208-4.221.066l-.497-.057l-.535 1.136a1.75 1.75 0 0 1-1.583 1.005H4.75a1.749 1.749 0 0 1-1.618-2.415l.433-1.05a3.242 3.242 0 0 1-1.57-2.78a.75.75 0 0 1 .648-.742L2.745 12h1.88l.497-1.643a6.137 6.137 0 0 1 5.875-4.359Zm6.777 9.693c-.771.31-1.559.565-2.356.765l-.549.129l.362.77a.25.25 0 0 0 .117.119l.053.018l.056.007h1.787a.25.25 0 0 0 .248-.28l-.017-.065l-.478-1.156h-.043l.411-.148l.409-.159Zm-13.552 0l.39.152l.388.141l-.482 1.166a.25.25 0 0 0 .232.345h1.804l.057-.007a.25.25 0 0 0 .17-.137l.359-.763l.044.01a18.168 18.168 0 0 1-2.962-.906Zm6.775-8.194a4.638 4.638 0 0 0-4.371 3.087l-.068.207l-1.136 3.75l.163.059a16.67 16.67 0 0 0 10.42.133l.406-.133l.162-.059l-1.136-3.75a4.64 4.64 0 0 0-4.006-3.273l-.216-.016l-.218-.005Zm-6.977 6.5l.151-.5l-.507.002l.025.052c.086.166.198.316.33.446ZM17.37 12l.756 2.498l2.12.001a.25.25 0 0 0 .243-.192l.007-.058v-.999a1.25 1.25 0 0 0-1.122-1.243l-.128-.006H17.37Z"
></path>
</svg>
);
};
22 changes: 22 additions & 0 deletions packages/insights/src/components/icons/symbol.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { type QwikIntrinsicElements } from '@builder.io/qwik';

export const SymbolIcon = function MaterialSymbolsFunction(
props: QwikIntrinsicElements['svg'],
key: string
) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width="1em"
height="1em"
viewBox="0 0 24 24"
{...props}
key={key}
>
<path
fill="currentColor"
d="M10 18v-2h1.55l2.625-3l-2.625-3H9.9l-1.6 8.6q-.2 1.125-.925 1.763T5.525 21Q4.4 21 3.7 20.4T3 18.8q0-.8.425-1.288t1.075-.487q.625 0 1.063.425T6 18.475q0 .125-.013.225t-.037.225q.125-.025.213-.138t.137-.312L7.85 10H5V8h3.225l.525-2.85q.175-.95.938-1.55T11.5 3q1.1 0 1.8.65t.7 1.625q0 .75-.425 1.238T12.5 7q-.625 0-1.063-.425T11 5.525q0-.125.013-.225t.037-.225q-.15.05-.225.15t-.125.3L10.275 8H15v2h-.8l1.3 1.475L16.8 10H16V8h5v2h-1.55l-2.625 3l2.625 3H21v2h-5v-2h.8l-1.3-1.5l-1.3 1.5h.8v2h-5Z"
></path>
</svg>
);
};
8 changes: 8 additions & 0 deletions packages/insights/src/routes/app/[publicApiKey]/app.form.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { z } from 'zod';

export const ApplicationForm = z.object({
name: z.string().min(1, 'Application name is required.'),
description: z.string().min(1, 'Application description is required.'),
});

export type ApplicationForm = z.infer<typeof ApplicationForm>;
92 changes: 92 additions & 0 deletions packages/insights/src/routes/app/[publicApiKey]/edit/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { component$ } from '@builder.io/qwik';
import { routeLoader$, useLocation } from '@builder.io/qwik-city';
import { formAction$, useForm, zodForm$, type InitialValues } from '@modular-forms/qwik';
import { applicationTable, getDB } from '~/db';
import { ApplicationForm } from '../../[publicApiKey]/app.form';
import { eq } from 'drizzle-orm';
import { a } from 'drizzle-orm/column.d-b7dc3bdb';
import { url } from '~/url';

export const useFormLoader = routeLoader$<InitialValues<ApplicationForm>>(async ({ params }) => {
if (isCreateMode(params)) {
return {
name: '',
description: '',
};
} else {
const db = getDB();
const app = await db
.select()
.from(applicationTable)
.where(eq(applicationTable.publicApiKey, params.publicApiKey))
.limit(1)
.get();
return app as ApplicationForm;
}
});

export const useFormAction = formAction$<ApplicationForm>(
async ({ name, description }, { redirect, params }) => {
const db = getDB();
if (isCreateMode(params)) {
const publicApiKey = Math.round(Math.random() * Number.MAX_SAFE_INTEGER).toString(36);
await db
.insert(applicationTable)
.values({
name,
description,
publicApiKey,
})
.run();
redirect(302, url(`/app/[publicApiKey]/`, { publicApiKey }));
} else {
db.update(applicationTable)
.set({
name,
description,
})
.where(eq(applicationTable.publicApiKey, params.publicApiKey))
.run();
throw redirect(302, url(`/app/[publicApiKey]/`, { publicApiKey: params.publicApiKey }));
}
},
zodForm$(ApplicationForm)
);

export default component$(() => {
const [loginForm, { Form, Field, FieldArray }] = useForm<ApplicationForm>({
loader: useFormLoader(),
action: useFormAction(),
validate: zodForm$(ApplicationForm),
});
const location = useLocation();
const isCreate = isCreateMode(location.params);

return (
<div>
<h1>Create new application</h1>
<Form>
<div>
<label>Name:</label>
<Field name="name">
{(field, props) => <input {...props} type="text" value={field.value} />}
</Field>
</div>
<div>
<label>Description:</label>
<Field name="description">
{(field, props) => <textarea {...props} value={field.value} />}
</Field>
</div>
<div>
<label></label>
<button type="submit">{isCreate ? 'Create' : 'Save'}</button>
</div>
</Form>
</div>
);
});

function isCreateMode(params: Readonly<Record<string, string>>) {
return params.publicApiKey == '__new__';
}
35 changes: 35 additions & 0 deletions packages/insights/src/routes/app/[publicApiKey]/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { component$ } from '@builder.io/qwik';
import { routeLoader$ } from '@builder.io/qwik-city';
import { eq } from 'drizzle-orm';
import { SymbolIcon } from '~/components/icons/symbol';
import { applicationTable, getDB } from '~/db';
import { AppLink } from '~/url';

export const useApplication = routeLoader$(async ({ params }) => {
const db = getDB();
const app = await db
.select()
.from(applicationTable)
.where(eq(applicationTable.publicApiKey, params.publicApiKey))
.get();
return app;
});

export default component$(() => {
const app = useApplication();
return (
<div>
<h1>
App: {app.value.name} (<code>{app.value.publicApiKey}</code>)
</h1>
<p>{app.value.description}</p>
<ul>
<li>
<AppLink route="/app/[publicApiKey]/symbols/" param:publicApiKey={app.value.publicApiKey}>
<SymbolIcon /> Symbols View
</AppLink>
</li>
</ul>
</div>
);
});
65 changes: 65 additions & 0 deletions packages/insights/src/routes/app/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { component$ } from '@builder.io/qwik';
import { routeLoader$ } from '@builder.io/qwik-city';
import { EditIcon } from '~/components/icons/edit';
import { ErrorIcon } from '~/components/icons/error';
import { SlowIcon } from '~/components/icons/slow';
import { SymbolIcon } from '~/components/icons/symbol';
import { applicationTable, getDB } from '~/db';
import { AppLink, url } from '~/url';

export const useApps = routeLoader$(async () => {
const db = getDB();
return await db.select().from(applicationTable).orderBy(applicationTable.name).all();
});

export default component$(() => {
const apps = useApps();
return (
<div>
<h1>Apps</h1>[ <a href={url('/app/__new__/edit/')}>new</a> ]
<table>
<tbody>
<tr>
<th>Name</th>
<th>Description</th>
<th>API Key</th>
<th></th>
</tr>
{apps.value.map((app) => (
<tr key={app.id}>
<td>
<a href={url('/app/[publicApiKey]/', { publicApiKey: app.publicApiKey })}>
{app.name}
</a>
</td>
<td>{app.description}</td>
<td>
<code>{app.publicApiKey}</code>
</td>
<td>
<AppLink route="/app/[publicApiKey]/symbols/" param:publicApiKey={app.publicApiKey}>
<SymbolIcon />
</AppLink>
<AppLink
route="/app/[publicApiKey]/symbols/slow/"
param:publicApiKey={app.publicApiKey}
>
<SlowIcon />
</AppLink>
<AppLink
route={`/app/[publicApiKey]/errors/`}
param:publicApiKey={app.publicApiKey}
>
<ErrorIcon />
</AppLink>
<AppLink route={`/app/[publicApiKey]/edit/`} param:publicApiKey={app.publicApiKey}>
<EditIcon />
</AppLink>
</td>
</tr>
))}
</tbody>
</table>
</div>
);
});

0 comments on commit 7f1e135

Please sign in to comment.