diff --git a/src/components/link.tsx b/src/components/link.tsx index d4a2323..a3efe0d 100644 --- a/src/components/link.tsx +++ b/src/components/link.tsx @@ -8,7 +8,7 @@ export interface LinkProps extends HTMLProps { href: string } -export default function Link(props: LinkProps) { +export function Link(props: LinkProps) { const {children, to, href, className: classNameProp, ...rest} = props let linkHref = '' diff --git a/src/components/nav-link.tsx b/src/components/nav-link.tsx deleted file mode 100644 index ed88c6c..0000000 --- a/src/components/nav-link.tsx +++ /dev/null @@ -1,55 +0,0 @@ -import type {HTMLProps} from 'react' -import {useLocation} from './AppCookieContext' -import log from '@log' - -export interface NavLinkProps extends Omit, 'className'> { - to: string - end?: boolean - className?: string | ((props: {isActive: boolean; isPending: boolean}) => string | undefined) -} - -export default function NavLink(props: NavLinkProps) { - const {children, to, end, href, className: classNameProp = '', ...rest} = props - - const location = useLocation() - let locationPathname = (location && location.pathname) || '/' - let toPathname = to || href || '/' - - const isPending = false - - let isActive = - locationPathname === toPathname || - (!end && locationPathname.startsWith(toPathname) && locationPathname.charAt(toPathname.length) === '/') - - // log('loc: ', location, toPathname, isActive) - - let className: string | undefined - if (typeof classNameProp === 'function') { - className = classNameProp({isActive, isPending}) - } else { - // If the className prop is not a function, we use a default `active` - // class for s that are active. In v5 `active` was the default - // value for `activeClassName`, but we are removing that API and can still - // use the old default behavior for a cleaner upgrade path and keep the - // simple styling rules working as they currently do. - className = [classNameProp, isActive ? 'active' : null, isPending ? 'pending' : null].filter(Boolean).join(' ') - } - let disableOnClick = (event: any) => { - event?.preventDefault() - return false - } - if (props.disabled) { - className += ' opacity-60 cursor-not-allowed' - } - - return ( - - {children} - - ) -} diff --git a/src/db/migrations/0001_needy_mimic.sql b/src/db/migrations/0001_needy_mimic.sql new file mode 100644 index 0000000..7c556ff --- /dev/null +++ b/src/db/migrations/0001_needy_mimic.sql @@ -0,0 +1 @@ +ALTER TABLE `builds` ADD `public` integer DEFAULT false NOT NULL; \ No newline at end of file diff --git a/src/db/migrations/meta/0001_snapshot.json b/src/db/migrations/meta/0001_snapshot.json new file mode 100644 index 0000000..999e9a7 --- /dev/null +++ b/src/db/migrations/meta/0001_snapshot.json @@ -0,0 +1,514 @@ +{ + "version": "6", + "dialect": "sqlite", + "id": "0befce22-0169-4598-9cab-9b82ea159fad", + "prevId": "206a3c30-67f7-4624-868f-1ca6467d0f86", + "tables": { + "api_keys": { + "name": "api_keys", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "pid": { + "name": "pid", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": { + "api_key_pid_idx": { + "name": "api_key_pid_idx", + "columns": [ + "pid" + ], + "isUnique": true + } + }, + "foreignKeys": { + "api_keys_user_id_users_id_fk": { + "name": "api_keys_user_id_users_id_fk", + "tableFrom": "api_keys", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "builds": { + "name": "builds", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "pid": { + "name": "pid", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_pid": { + "name": "user_pid", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "project_id": { + "name": "project_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "project_pid": { + "name": "project_pid", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "commit_sha": { + "name": "commit_sha", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "image_sha": { + "name": "image_sha", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "tag": { + "name": "tag", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "public": { + "name": "public", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "release_url": { + "name": "release_url", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "registry_url": { + "name": "registry_url", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "built_with": { + "name": "built_with", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "built_by": { + "name": "built_by", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "object_path": { + "name": "object_path", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": { + "builds_pid_idx": { + "name": "builds_pid_idx", + "columns": [ + "pid" + ], + "isUnique": true + } + }, + "foreignKeys": { + "builds_user_id_users_id_fk": { + "name": "builds_user_id_users_id_fk", + "tableFrom": "builds", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "builds_project_id_projects_id_fk": { + "name": "builds_project_id_projects_id_fk", + "tableFrom": "builds", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "projects": { + "name": "projects", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "pid": { + "name": "pid", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "user_pid": { + "name": "user_pid", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "org": { + "name": "org", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "repo_url": { + "name": "repo_url", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "registry_url": { + "name": "registry_url", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "public": { + "name": "public", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": { + "projects_pid_idx": { + "name": "projects_pid_idx", + "columns": [ + "pid" + ], + "isUnique": true + } + }, + "foreignKeys": { + "projects_user_id_users_id_fk": { + "name": "projects_user_id_users_id_fk", + "tableFrom": "projects", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "user_sessions": { + "name": "user_sessions", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "session_token": { + "name": "session_token", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + } + }, + "indexes": { + "user_sessions_session_token_unique": { + "name": "user_sessions_session_token_unique", + "columns": [ + "session_token" + ], + "isUnique": true + }, + "session_token_idx": { + "name": "session_token_idx", + "columns": [ + "session_token" + ], + "isUnique": true + } + }, + "foreignKeys": { + "user_sessions_user_id_users_id_fk": { + "name": "user_sessions_user_id_users_id_fk", + "tableFrom": "user_sessions", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "users": { + "name": "users", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": true + }, + "pid": { + "name": "pid", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": "(CURRENT_TIMESTAMP)" + }, + "full_name": { + "name": "full_name", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "github_id": { + "name": "github_id", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "github_login": { + "name": "github_login", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "github_avatar_url": { + "name": "github_avatar_url", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "user_pid_idx": { + "name": "user_pid_idx", + "columns": [ + "pid" + ], + "isUnique": true + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + } + }, + "enums": {}, + "_meta": { + "schemas": {}, + "tables": {}, + "columns": {} + } +} \ No newline at end of file diff --git a/src/db/migrations/meta/_journal.json b/src/db/migrations/meta/_journal.json index cc8b230..a327916 100644 --- a/src/db/migrations/meta/_journal.json +++ b/src/db/migrations/meta/_journal.json @@ -8,6 +8,13 @@ "when": 1716588993128, "tag": "0000_complex_marvex", "breakpoints": true + }, + { + "idx": 1, + "version": "6", + "when": 1717025603459, + "tag": "0001_needy_mimic", + "breakpoints": true } ] } \ No newline at end of file diff --git a/src/db/schema.ts b/src/db/schema.ts index a9acb5d..b7d45ab 100644 --- a/src/db/schema.ts +++ b/src/db/schema.ts @@ -113,6 +113,7 @@ export const builds = sqliteTable( commitSha: text('commit_sha'), imageSha: text('image_sha'), tag: text('tag'), + public: integer('public', {mode: 'boolean'}).notNull().default(false), releaseUrl: text('release_url'), registryUrl: text('registry_url'), builtWith: text('built_with'), // podman, docker diff --git a/src/log.ts b/src/log.ts index 39e3a81..5dae9e1 100644 --- a/src/log.ts +++ b/src/log.ts @@ -1,4 +1,4 @@ -export default function log(...args: any[]) { +export function log(...args: any[]) { const PUBLIC_DEBUG = import.meta.env.PUBLIC_DEBUG if (PUBLIC_DEBUG === 'true') { console.log.apply(null, args) diff --git a/src/pages/app/[...path].astro b/src/pages/app/[...path].astro index 0488907..40df34e 100644 --- a/src/pages/app/[...path].astro +++ b/src/pages/app/[...path].astro @@ -2,7 +2,7 @@ // main dashboard single page app import MainLayout from '@/layouts/main-layout.astro' -import App from '@/partials/app/app' +import {App} from '@/partials/app/app' import {verifyValidSession} from '@/lib/github-client' export const prerender = false diff --git a/src/pages/share/[pid].astro b/src/pages/share/[pid].astro new file mode 100644 index 0000000..8c7f273 --- /dev/null +++ b/src/pages/share/[pid].astro @@ -0,0 +1,19 @@ +--- +import MainLayout from '@/layouts/main-layout.astro' +import SiteHeader from '@/partials/header/site-header.astro' +export const prerender = false +import {SharedLinkViewerPage} from '@/partials/viewer/shared-link-viewer-page' + +const {pid} = Astro.params +if (!pid) { + return Astro.redirect('/404') +} +--- + + + + + diff --git a/src/pages/viewer.astro b/src/pages/viewer.astro index b506113..f8ab1f9 100644 --- a/src/pages/viewer.astro +++ b/src/pages/viewer.astro @@ -2,7 +2,7 @@ import MainLayout from '@/layouts/main-layout.astro' import SiteHeader from '@/partials/header/site-header.astro' export const prerender = true -import LocalViewerPage from '@/partials/viewer/local-viewer-page' +import {LocalViewerPage} from '@/partials/viewer/local-viewer-page' --- diff --git a/src/partials/app/app-layout.tsx b/src/partials/app/app-layout.tsx index 3950eb3..ed9b692 100644 --- a/src/partials/app/app-layout.tsx +++ b/src/partials/app/app-layout.tsx @@ -1,10 +1,10 @@ -import {Children, PropsWithChildren} from 'react' +import {PropsWithChildren} from 'react' import {AppHeader} from '../header/app-header' import {AppFooter} from '../footer/app-footer' import {useLocation} from 'react-router-dom' export interface AppLayoutProps {} -export default function AppLayout({children}: PropsWithChildren) { +export function AppLayout({children}: PropsWithChildren) { const location = useLocation() const hideFooter = location.pathname.startsWith('/app/deployment') diff --git a/src/partials/app/app.tsx b/src/partials/app/app.tsx index 71d9574..11b2e3d 100644 --- a/src/partials/app/app.tsx +++ b/src/partials/app/app.tsx @@ -2,14 +2,14 @@ import {StrictMode} from 'react' import {SWRConfig} from 'swr' import {BrowserRouter as Router, Routes, Route} from 'react-router-dom' -import DashboardPage from '../dashboard/dashboard-page' -import ProjectsPage from '../projects/projects-page' -import NewProjectPage from '../projects/new-project-page' -import AppLayout from './app-layout' -import SettingsPage from '../settings/settings-page' -import AppViewerPage from '../viewer/app-viewer-page' +import {DashboardPage} from '../dashboard/dashboard-page' +import {ProjectsPage} from '../projects/projects-page' +import {NewProjectPage} from '../projects/new-project-page' +import {AppLayout} from './app-layout' +import {SettingsPage} from '../settings/settings-page' +import {AppViewerPage} from '../viewer/app-viewer-page' -export default function App() { +export function App() { return ( } /> + } + /> } diff --git a/src/partials/app/sidebar-nav.tsx b/src/partials/app/sidebar-nav.tsx index 02748a5..142d954 100644 --- a/src/partials/app/sidebar-nav.tsx +++ b/src/partials/app/sidebar-nav.tsx @@ -1,7 +1,7 @@ import {cn} from '@/lib/utils' import {Icons} from '../header/icons' import {useLocation} from 'react-router-dom' -import Link from '@/components/link' +import {Link} from '@/components/link' export interface NavItem { title: string diff --git a/src/partials/builds/build-row.tsx b/src/partials/builds/build-row.tsx index 6fa151f..cc791e6 100644 --- a/src/partials/builds/build-row.tsx +++ b/src/partials/builds/build-row.tsx @@ -1,7 +1,7 @@ import {ChevronRightIcon, ExternalLinkIcon} from '@radix-ui/react-icons' import {Badge} from '@/components/ui/badge' import {formatRelativeTimeFromUTC} from '@/lib/format-dates' -import Link from '@/components/link' +import {Link} from '@/components/link' import {cn} from '@/lib/utils' @@ -54,7 +54,7 @@ export function BuildRow(props: BuildRowProps) { -
+
{/* gap-x-2.5 */}

{props.builtBy && props.builtWith && ( @@ -85,7 +85,7 @@ export function BuildRow(props: BuildRowProps) { {deployment.environment}

*/}