29
src/routes/new/application/import.json.ts
Normal file
29
src/routes/new/application/import.json.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { getUserDetails } from '$lib/common';
|
||||
import * as db from '$lib/database';
|
||||
import { PrismaErrorHandler } from '$lib/database';
|
||||
import type { RequestHandler } from '@sveltejs/kit';
|
||||
|
||||
export const post: RequestHandler = async (event) => {
|
||||
const { teamId, status, body } = await getUserDetails(event);
|
||||
if (status === 401) return { status, body };
|
||||
|
||||
let { name, fqdn, port, buildCommand, startCommand, installCommand } = await event.request.json();
|
||||
|
||||
if (fqdn) fqdn = fqdn.toLowerCase();
|
||||
if (port) port = Number(port);
|
||||
|
||||
try {
|
||||
const { id } = await db.importApplication({
|
||||
name,
|
||||
teamId,
|
||||
fqdn,
|
||||
port,
|
||||
buildCommand,
|
||||
startCommand,
|
||||
installCommand
|
||||
});
|
||||
return { status: 201, body: { id } };
|
||||
} catch (error) {
|
||||
return PrismaErrorHandler(error);
|
||||
}
|
||||
};
|
||||
19
src/routes/new/application/index.json.ts
Normal file
19
src/routes/new/application/index.json.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { getUserDetails, uniqueName } from '$lib/common';
|
||||
import * as db from '$lib/database';
|
||||
import { PrismaErrorHandler } from '$lib/database';
|
||||
import type { RequestHandler } from '@sveltejs/kit';
|
||||
|
||||
export const post: RequestHandler = async (event) => {
|
||||
const { teamId, status, body } = await getUserDetails(event);
|
||||
if (status === 401) return { status, body };
|
||||
|
||||
const { name } = await event.request.json();
|
||||
if (!name) return { status: 400, body: { error: 'Missing name.' } };
|
||||
|
||||
try {
|
||||
const { id } = await db.newApplication({ name, teamId });
|
||||
return { status: 201, body: { id } };
|
||||
} catch (error) {
|
||||
return PrismaErrorHandler(error);
|
||||
}
|
||||
};
|
||||
53
src/routes/new/application/index.svelte
Normal file
53
src/routes/new/application/index.svelte
Normal file
@@ -0,0 +1,53 @@
|
||||
<script context="module" lang="ts">
|
||||
import type { Load } from '@sveltejs/kit';
|
||||
export const load: Load = async ({ fetch }) => {
|
||||
const url = `/common/getUniqueName.json`;
|
||||
const res = await fetch(url);
|
||||
|
||||
if (res.ok) {
|
||||
return {
|
||||
props: {
|
||||
...(await res.json())
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
status: res.status,
|
||||
error: new Error(`Could not load ${url}`)
|
||||
};
|
||||
};
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
export let name;
|
||||
import { onMount } from 'svelte';
|
||||
import { goto } from '$app/navigation';
|
||||
import { post } from '$lib/api';
|
||||
import { errorNotification } from '$lib/form';
|
||||
|
||||
let nameEl: HTMLInputElement;
|
||||
onMount(() => {
|
||||
nameEl.focus();
|
||||
});
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
const { id } = await post('/new/application.json', { name });
|
||||
return await goto(`/applications/${id}`);
|
||||
} catch ({ error }) {
|
||||
return errorNotification(error);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="flex space-x-1 p-6 font-bold">
|
||||
<div class="mr-4 text-2xl tracking-tight">Add New Application</div>
|
||||
</div>
|
||||
<div class="pt-10">
|
||||
<form on:submit|preventDefault={handleSubmit}>
|
||||
<div class="flex flex-col items-center space-y-4">
|
||||
<input name="name" placeholder="Application name" bind:this={nameEl} bind:value={name} />
|
||||
<button type="submit" class="bg-green-600 hover:bg-green-500">Save</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
18
src/routes/new/database/index.json.ts
Normal file
18
src/routes/new/database/index.json.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { getUserDetails } from '$lib/common';
|
||||
import * as db from '$lib/database';
|
||||
import { PrismaErrorHandler } from '$lib/database';
|
||||
import type { RequestHandler } from '@sveltejs/kit';
|
||||
|
||||
export const post: RequestHandler = async (event) => {
|
||||
const { teamId, status, body } = await getUserDetails(event);
|
||||
if (status === 401) return { status, body };
|
||||
|
||||
const { name } = await event.request.json();
|
||||
|
||||
try {
|
||||
const { id } = await db.newDatabase({ name, teamId });
|
||||
return { status: 201, body: { id } };
|
||||
} catch (error) {
|
||||
return PrismaErrorHandler(error);
|
||||
}
|
||||
};
|
||||
59
src/routes/new/database/index.svelte
Normal file
59
src/routes/new/database/index.svelte
Normal file
@@ -0,0 +1,59 @@
|
||||
<script context="module" lang="ts">
|
||||
import type { Load } from '@sveltejs/kit';
|
||||
export const load: Load = async ({ fetch, session }) => {
|
||||
const url = `/common/getUniqueName.json`;
|
||||
const res = await fetch(url);
|
||||
|
||||
if (res.ok) {
|
||||
return {
|
||||
props: {
|
||||
...(await res.json())
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
status: res.status,
|
||||
error: new Error(`Could not load ${url}`)
|
||||
};
|
||||
};
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
export let name;
|
||||
import { errorNotification } from '$lib/form';
|
||||
import { onMount } from 'svelte';
|
||||
import { goto } from '$app/navigation';
|
||||
import { post } from '$lib/api';
|
||||
let autofocus;
|
||||
|
||||
onMount(() => {
|
||||
autofocus.focus();
|
||||
});
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
const { id } = await post('/new/database.json', { name });
|
||||
return await goto(`/databases/${id}`);
|
||||
} catch ({ error }) {
|
||||
return errorNotification(error);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="flex space-x-1 p-6 font-bold">
|
||||
<div class="mr-4 text-2xl tracking-tight">Add New Database</div>
|
||||
</div>
|
||||
<div class="pt-10">
|
||||
<form on:submit|preventDefault={handleSubmit}>
|
||||
<div class="flex flex-col items-center space-y-4">
|
||||
<input
|
||||
name="name"
|
||||
placeholder="Database name"
|
||||
required
|
||||
bind:this={autofocus}
|
||||
bind:value={name}
|
||||
/>
|
||||
<button type="submit" class="bg-purple-600 hover:bg-purple-500">Save</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
101
src/routes/new/destination/_Docker.svelte
Normal file
101
src/routes/new/destination/_Docker.svelte
Normal file
@@ -0,0 +1,101 @@
|
||||
<script lang="ts">
|
||||
import { goto } from '$app/navigation';
|
||||
|
||||
export let payload;
|
||||
|
||||
import { post } from '$lib/api';
|
||||
import Setting from '$lib/components/Setting.svelte';
|
||||
import { enhance, errorNotification } from '$lib/form';
|
||||
|
||||
let loading = false;
|
||||
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
await post('/new/destination/check.json', { network: payload.network });
|
||||
const { id } = await post('/new/destination/docker.json', {
|
||||
...payload
|
||||
});
|
||||
return await goto(`/destinations/${id}`);
|
||||
} catch ({ error }) {
|
||||
return errorNotification(error);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="flex justify-center px-6 pb-8">
|
||||
<form on:submit|preventDefault={handleSubmit} class="grid grid-flow-row gap-2 py-4">
|
||||
<div class="flex h-8 items-center space-x-2">
|
||||
<div class="text-xl font-bold text-white">Configuration</div>
|
||||
<button
|
||||
type="submit"
|
||||
class:bg-sky-600={!loading}
|
||||
class:hover:bg-sky-500={!loading}
|
||||
disabled={loading}
|
||||
>{loading
|
||||
? payload.isCoolifyProxyUsed
|
||||
? 'Saving and configuring proxy...'
|
||||
: 'Saving...'
|
||||
: 'Save'}</button
|
||||
>
|
||||
</div>
|
||||
<div class="grid grid-cols-3 items-center">
|
||||
<label for="name">Name</label>
|
||||
<div class="col-span-2">
|
||||
<input required name="name" placeholder="name" bind:value={payload.name} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-3 items-center">
|
||||
<label for="engine">Engine</label>
|
||||
<div class="col-span-2">
|
||||
<input
|
||||
required
|
||||
name="engine"
|
||||
placeholder="eg: /var/run/docker.sock"
|
||||
bind:value={payload.engine}
|
||||
/>
|
||||
<!-- <Explainer text="You can use remote Docker Engine with over SSH." /> -->
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="flex items-center">
|
||||
<label for="remoteEngine">Remote Docker Engine?</label>
|
||||
<input name="remoteEngine" type="checkbox" bind:checked={payload.remoteEngine} />
|
||||
</div>
|
||||
{#if payload.remoteEngine}
|
||||
<div class="grid grid-cols-3 items-center">
|
||||
<label for="user">User</label>
|
||||
<div class="col-span-2">
|
||||
<input required name="user" placeholder="eg: root" bind:value={payload.user} />
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid grid-cols-3 items-center">
|
||||
<label for="port">Port</label>
|
||||
<div class="col-span-2">
|
||||
<input required name="port" placeholder="eg: 22" bind:value={payload.port} />
|
||||
</div>
|
||||
</div>
|
||||
{/if} -->
|
||||
<div class="grid grid-cols-3 items-center">
|
||||
<label for="network">Network</label>
|
||||
<div class="col-span-2">
|
||||
<input
|
||||
required
|
||||
name="network"
|
||||
placeholder="default: coolify"
|
||||
bind:value={payload.network}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-start">
|
||||
<ul class="mt-2 divide-y divide-stone-800">
|
||||
<Setting
|
||||
bind:setting={payload.isCoolifyProxyUsed}
|
||||
on:click={() => (payload.isCoolifyProxyUsed = !payload.isCoolifyProxyUsed)}
|
||||
isPadding={false}
|
||||
title="Use Coolify Proxy?"
|
||||
description="This will install a proxy on the destination to allow you to access your applications and services without any manual configuration (recommended for Docker). Databases will have their own proxy."
|
||||
/>
|
||||
</ul>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
23
src/routes/new/destination/check.json.ts
Normal file
23
src/routes/new/destination/check.json.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { getUserDetails } from '$lib/common';
|
||||
import { isDockerNetworkExists, PrismaErrorHandler } from '$lib/database';
|
||||
import type { RequestHandler } from '@sveltejs/kit';
|
||||
|
||||
export const post: RequestHandler = async (event) => {
|
||||
const { teamId, status, body } = await getUserDetails(event);
|
||||
if (status === 401) return { status, body };
|
||||
|
||||
const { network } = await event.request.json();
|
||||
try {
|
||||
const found = await isDockerNetworkExists({ network });
|
||||
if (found) {
|
||||
throw {
|
||||
error: `Network ${network} already configured for another team!`
|
||||
};
|
||||
}
|
||||
return {
|
||||
status: 200
|
||||
};
|
||||
} catch (error) {
|
||||
return PrismaErrorHandler(error);
|
||||
}
|
||||
};
|
||||
19
src/routes/new/destination/docker.json.ts
Normal file
19
src/routes/new/destination/docker.json.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { asyncExecShell, getUserDetails } from '$lib/common';
|
||||
import * as db from '$lib/database';
|
||||
import { PrismaErrorHandler } from '$lib/database';
|
||||
import { dockerInstance } from '$lib/docker';
|
||||
import type { RequestHandler } from '@sveltejs/kit';
|
||||
|
||||
export const post: RequestHandler = async (event) => {
|
||||
const { teamId, status, body } = await getUserDetails(event);
|
||||
if (status === 401) return { status, body };
|
||||
|
||||
const { name, engine, network, isCoolifyProxyUsed } = await event.request.json();
|
||||
|
||||
try {
|
||||
const id = await db.newDestination({ name, teamId, engine, network, isCoolifyProxyUsed });
|
||||
return { status: 200, body: { id } };
|
||||
} catch (error) {
|
||||
return PrismaErrorHandler(error);
|
||||
}
|
||||
};
|
||||
43
src/routes/new/destination/index.svelte
Normal file
43
src/routes/new/destination/index.svelte
Normal file
@@ -0,0 +1,43 @@
|
||||
<script>
|
||||
import Docker from './_Docker.svelte';
|
||||
|
||||
let payload = {};
|
||||
let selected = 'docker';
|
||||
|
||||
function setPredefined(type) {
|
||||
selected = type;
|
||||
switch (type) {
|
||||
case 'docker':
|
||||
payload = {
|
||||
name: 'Local Docker',
|
||||
engine: '/var/run/docker.sock',
|
||||
remoteEngine: false,
|
||||
user: 'root',
|
||||
port: 22,
|
||||
privateKey: null,
|
||||
network: 'coolify',
|
||||
isCoolifyProxyUsed: true
|
||||
};
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="flex space-x-1 p-6 font-bold">
|
||||
<div class="mr-4 text-2xl tracking-tight">Add New Destination</div>
|
||||
</div>
|
||||
<div class="flex-col space-y-2 pb-10 text-center">
|
||||
<div class="text-xl font-bold text-white">Predefined destinations</div>
|
||||
<div class="flex justify-center space-x-2">
|
||||
<button class="w-32" on:click={() => setPredefined('docker')}>Docker</button>
|
||||
<button class="w-32" on:click={() => setPredefined('kubernetes')}>Kubernetes</button>
|
||||
</div>
|
||||
</div>
|
||||
{#if selected === 'docker'}
|
||||
<Docker {payload} />
|
||||
{:else}
|
||||
<div class="text-center font-bold text-4xl py-10">Not implemented yet</div>
|
||||
{/if}
|
||||
18
src/routes/new/service/index.json.ts
Normal file
18
src/routes/new/service/index.json.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { getUserDetails, uniqueName } from '$lib/common';
|
||||
import * as db from '$lib/database';
|
||||
import { PrismaErrorHandler } from '$lib/database';
|
||||
import type { RequestHandler } from '@sveltejs/kit';
|
||||
|
||||
export const post: RequestHandler = async (event) => {
|
||||
const { teamId, status, body } = await getUserDetails(event);
|
||||
if (status === 401) return { status, body };
|
||||
|
||||
const { name } = await event.request.json();
|
||||
|
||||
try {
|
||||
const { id } = await db.newService({ name, teamId });
|
||||
return { status: 201, body: { id } };
|
||||
} catch (error) {
|
||||
return PrismaErrorHandler(error);
|
||||
}
|
||||
};
|
||||
59
src/routes/new/service/index.svelte
Normal file
59
src/routes/new/service/index.svelte
Normal file
@@ -0,0 +1,59 @@
|
||||
<script context="module" lang="ts">
|
||||
import type { Load } from '@sveltejs/kit';
|
||||
export const load: Load = async ({ fetch, session }) => {
|
||||
const url = `/common/getUniqueName.json`;
|
||||
const res = await fetch(url);
|
||||
|
||||
if (res.ok) {
|
||||
return {
|
||||
props: {
|
||||
...(await res.json())
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
status: res.status,
|
||||
error: new Error(`Could not load ${url}`)
|
||||
};
|
||||
};
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
export let name;
|
||||
import { enhance, errorNotification } from '$lib/form';
|
||||
import { onMount } from 'svelte';
|
||||
import { goto } from '$app/navigation';
|
||||
import { post } from '$lib/api';
|
||||
let autofocus;
|
||||
|
||||
onMount(() => {
|
||||
autofocus.focus();
|
||||
});
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
const { id } = await post(`/new/service.json`, { name });
|
||||
return await goto(`/services/${id}`);
|
||||
} catch ({ error }) {
|
||||
return errorNotification(error);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="flex space-x-1 p-6 font-bold">
|
||||
<div class="mr-4 text-2xl tracking-tight">Add New Service</div>
|
||||
</div>
|
||||
<div class="pt-10">
|
||||
<form on:submit|preventDefault={handleSubmit}>
|
||||
<div class="flex flex-col items-center space-y-4">
|
||||
<input
|
||||
name="name"
|
||||
placeholder="Service name"
|
||||
required
|
||||
bind:this={autofocus}
|
||||
bind:value={name}
|
||||
/>
|
||||
<button type="submit" class="bg-pink-600 hover:bg-pink-500">Save</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
101
src/routes/new/source/_Github.svelte
Normal file
101
src/routes/new/source/_Github.svelte
Normal file
@@ -0,0 +1,101 @@
|
||||
<script lang="ts">
|
||||
export let gitSource;
|
||||
import { goto } from '$app/navigation';
|
||||
import { post } from '$lib/api';
|
||||
|
||||
import Explainer from '$lib/components/Explainer.svelte';
|
||||
|
||||
import { errorNotification } from '$lib/form';
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
let nameEl;
|
||||
let organizationEl;
|
||||
|
||||
onMount(() => {
|
||||
nameEl.focus();
|
||||
});
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
const { id } = await post(`/new/source.json`, { ...gitSource });
|
||||
return await goto(`/sources/${id}/`);
|
||||
} catch ({ error }) {
|
||||
return errorNotification(error);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="flex justify-center pb-8">
|
||||
<form on:submit|preventDefault={handleSubmit} class="grid grid-flow-row gap-2 py-4">
|
||||
<div class="flex h-8 items-center space-x-2">
|
||||
<div class="text-xl font-bold text-white">Configuration</div>
|
||||
<button type="submit" class="bg-orange-600 hover:bg-orange-500">Save</button>
|
||||
</div>
|
||||
<div class="grid grid-cols-3 items-center">
|
||||
<label for="type">Type</label>
|
||||
|
||||
<div class="col-span-2">
|
||||
<select name="type" id="type" class="w-96" bind:value={gitSource.type}>
|
||||
<option value="github">GitHub</option>
|
||||
<option value="gitlab">GitLab</option>
|
||||
<option value="bitbucket">BitBucket</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid grid-cols-3 items-center">
|
||||
<label for="name">Name</label>
|
||||
<div class="col-span-2">
|
||||
<input
|
||||
name="name"
|
||||
id="name"
|
||||
placeholder="GitHub.com"
|
||||
required
|
||||
bind:this={nameEl}
|
||||
bind:value={gitSource.name}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-3 items-center">
|
||||
<label for="htmlUrl">HTML URL</label>
|
||||
<div class="col-span-2">
|
||||
<input
|
||||
type="url"
|
||||
name="htmlUrl"
|
||||
id="htmlUrl"
|
||||
placeholder="eg: https://github.com"
|
||||
required
|
||||
bind:value={gitSource.htmlUrl}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid grid-cols-3 items-center">
|
||||
<label for="apiUrl">API URL</label>
|
||||
<div class="col-span-2">
|
||||
<input
|
||||
name="apiUrl"
|
||||
type="url"
|
||||
id="apiUrl"
|
||||
placeholder="eg: https://api.github.com"
|
||||
required
|
||||
bind:value={gitSource.apiUrl}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid grid-cols-3">
|
||||
<label for="organization" class="pt-2">Organization</label>
|
||||
<div class="col-span-2">
|
||||
<input
|
||||
name="organization"
|
||||
id="organization"
|
||||
placeholder="eg: coollabsio"
|
||||
bind:value={gitSource.organization}
|
||||
bind:this={organizationEl}
|
||||
/>
|
||||
<Explainer
|
||||
text="Fill it if you would like to use an organization's as your Git Source. Otherwise your
|
||||
user will be used."
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
82
src/routes/new/source/_Gitlab.svelte
Normal file
82
src/routes/new/source/_Gitlab.svelte
Normal file
@@ -0,0 +1,82 @@
|
||||
<script lang="ts">
|
||||
export let gitSource;
|
||||
import { goto } from '$app/navigation';
|
||||
import { post } from '$lib/api';
|
||||
|
||||
import { errorNotification } from '$lib/form';
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
let nameEl;
|
||||
|
||||
onMount(() => {
|
||||
nameEl.focus();
|
||||
});
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
const { id } = await post(`/new/source.json`, { ...gitSource });
|
||||
return await goto(`/sources/${id}/`);
|
||||
} catch ({ error }) {
|
||||
return errorNotification(error);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="flex justify-center pb-8">
|
||||
<form on:submit|preventDefault={handleSubmit} class="grid grid-flow-row gap-2 py-4">
|
||||
<div class="flex h-8 items-center space-x-2">
|
||||
<div class="text-xl font-bold text-white">Configuration</div>
|
||||
<button type="submit" class="bg-orange-600 hover:bg-orange-500">Save</button>
|
||||
</div>
|
||||
<div class="grid grid-cols-3 items-center">
|
||||
<label for="type">Type</label>
|
||||
|
||||
<div class="col-span-2">
|
||||
<select name="type" id="type" class="w-96" bind:value={gitSource.type}>
|
||||
<option value="github">GitHub</option>
|
||||
<option value="gitlab">GitLab</option>
|
||||
<option value="bitbucket">BitBucket</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid grid-cols-3 items-center">
|
||||
<label for="name">Name</label>
|
||||
<div class="col-span-2">
|
||||
<input
|
||||
name="name"
|
||||
id="name"
|
||||
placeholder="GitHub.com"
|
||||
required
|
||||
bind:this={nameEl}
|
||||
bind:value={gitSource.name}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-3 items-center">
|
||||
<label for="htmlUrl">HTML URL</label>
|
||||
<div class="col-span-2">
|
||||
<input
|
||||
type="url"
|
||||
name="htmlUrl"
|
||||
id="htmlUrl"
|
||||
placeholder="eg: https://github.com"
|
||||
required
|
||||
bind:value={gitSource.htmlUrl}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid grid-cols-3 items-center">
|
||||
<label for="apiUrl">API URL</label>
|
||||
<div class="col-span-2">
|
||||
<input
|
||||
name="apiUrl"
|
||||
type="url"
|
||||
id="apiUrl"
|
||||
placeholder="eg: https://api.github.com"
|
||||
required
|
||||
bind:value={gitSource.apiUrl}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
17
src/routes/new/source/index.json.ts
Normal file
17
src/routes/new/source/index.json.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { getUserDetails } from '$lib/common';
|
||||
import * as db from '$lib/database';
|
||||
import { PrismaErrorHandler } from '$lib/database';
|
||||
import type { RequestHandler } from '@sveltejs/kit';
|
||||
|
||||
export const post: RequestHandler = async (event) => {
|
||||
const { teamId, status, body } = await getUserDetails(event);
|
||||
if (status === 401) return { status, body };
|
||||
|
||||
const { name, type, htmlUrl, apiUrl, organization } = await event.request.json();
|
||||
try {
|
||||
const { id } = await db.newSource({ name, teamId, type, htmlUrl, apiUrl, organization });
|
||||
return { status: 201, body: { id } };
|
||||
} catch (e) {
|
||||
return PrismaErrorHandler(e);
|
||||
}
|
||||
};
|
||||
66
src/routes/new/source/index.svelte
Normal file
66
src/routes/new/source/index.svelte
Normal file
@@ -0,0 +1,66 @@
|
||||
<script lang="ts">
|
||||
import Github from './_Github.svelte';
|
||||
import Gitlab from './_Gitlab.svelte';
|
||||
let gitSource = {
|
||||
name: undefined,
|
||||
type: 'github',
|
||||
htmlUrl: undefined,
|
||||
apiUrl: undefined,
|
||||
organization: undefined
|
||||
};
|
||||
function setPredefined(type) {
|
||||
switch (type) {
|
||||
case 'github':
|
||||
gitSource = {
|
||||
name: 'GitHub.com',
|
||||
type,
|
||||
htmlUrl: 'https://github.com',
|
||||
apiUrl: 'https://api.github.com',
|
||||
organization: undefined
|
||||
};
|
||||
break;
|
||||
case 'gitlab':
|
||||
gitSource = {
|
||||
name: 'GitLab.com',
|
||||
type,
|
||||
htmlUrl: 'https://gitlab.com',
|
||||
apiUrl: 'https://gitlab.com/api',
|
||||
organization: undefined
|
||||
};
|
||||
break;
|
||||
case 'bitbucket':
|
||||
gitSource = {
|
||||
name: 'BitBucket.com',
|
||||
type,
|
||||
htmlUrl: 'https://bitbucket.com',
|
||||
apiUrl: 'https://bitbucket.com',
|
||||
organization: undefined
|
||||
};
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="flex space-x-1 p-6 font-bold">
|
||||
<div class="mr-4 text-2xl tracking-tight">Add New Git Source</div>
|
||||
</div>
|
||||
|
||||
<div class="flex-col space-y-2 pb-10 text-center">
|
||||
<div class="text-xl font-bold text-white">Offical providers</div>
|
||||
<div class="flex justify-center space-x-2">
|
||||
<button class="w-32" on:click={() => setPredefined('github')}>GitHub.com</button>
|
||||
<button class="w-32" on:click={() => setPredefined('gitlab')}>GitLab.com</button>
|
||||
<button class="w-32" on:click={() => setPredefined('bitbucket')}>Bitbucket.com</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="px-6">
|
||||
{#if gitSource.type === 'github'}
|
||||
<Github {gitSource} />
|
||||
{:else if gitSource.type === 'gitlab'}
|
||||
<Gitlab {gitSource} />
|
||||
{:else if gitSource.type === 'bitbucket'}
|
||||
<div class="text-center font-bold text-4xl py-10">Not implemented yet</div>
|
||||
{/if}
|
||||
</div>
|
||||
18
src/routes/new/team/index.json.ts
Normal file
18
src/routes/new/team/index.json.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { getUserDetails, uniqueName } from '$lib/common';
|
||||
import * as db from '$lib/database';
|
||||
import { PrismaErrorHandler } from '$lib/database';
|
||||
import type { RequestHandler } from '@sveltejs/kit';
|
||||
|
||||
export const post: RequestHandler = async (event) => {
|
||||
const { userId, status, body } = await getUserDetails(event);
|
||||
if (status === 401) return { status, body };
|
||||
|
||||
const { name } = await event.request.json();
|
||||
|
||||
try {
|
||||
const { id } = await db.newTeam({ name, userId });
|
||||
return { status: 201, body: { id } };
|
||||
} catch (error) {
|
||||
return PrismaErrorHandler(error);
|
||||
}
|
||||
};
|
||||
56
src/routes/new/team/index.svelte
Normal file
56
src/routes/new/team/index.svelte
Normal file
@@ -0,0 +1,56 @@
|
||||
<script context="module" lang="ts">
|
||||
import type { Load } from '@sveltejs/kit';
|
||||
export const load: Load = async ({ fetch, session }) => {
|
||||
const url = `/common/getUniqueName.json`;
|
||||
const res = await fetch(url);
|
||||
|
||||
if (res.ok) {
|
||||
return {
|
||||
props: {
|
||||
...(await res.json())
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
status: res.status,
|
||||
error: new Error(`Could not load ${url}`)
|
||||
};
|
||||
};
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
export let name;
|
||||
import { errorNotification } from '$lib/form';
|
||||
import { onMount } from 'svelte';
|
||||
import { goto } from '$app/navigation';
|
||||
import { post } from '$lib/api';
|
||||
|
||||
let autofocus;
|
||||
onMount(() => {
|
||||
autofocus.focus();
|
||||
});
|
||||
async function handleSubmit() {
|
||||
if (name) {
|
||||
try {
|
||||
const { id } = await post('/new/team.json', { name });
|
||||
return await goto(`/teams/${id}`);
|
||||
} catch ({ error }) {
|
||||
return errorNotification(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="flex space-x-1 p-6 font-bold">
|
||||
<div class="mr-4 text-2xl tracking-tight">Add New Team</div>
|
||||
</div>
|
||||
|
||||
<div class="pt-10">
|
||||
<form on:submit|preventDefault={handleSubmit}>
|
||||
<div class="flex flex-col items-center space-y-4">
|
||||
<input name="name" placeholder="Team name" required bind:this={autofocus} bind:value={name} />
|
||||
<button type="submit" class="bg-green-600 hover:bg-green-500">Save</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
Reference in New Issue
Block a user