commit
5e02c386ec
@ -0,0 +1,26 @@
|
||||
-- RedefineTables
|
||||
PRAGMA foreign_keys=OFF;
|
||||
CREATE TABLE "new_GitSource" (
|
||||
"id" TEXT NOT NULL PRIMARY KEY,
|
||||
"name" TEXT NOT NULL,
|
||||
"forPublic" BOOLEAN NOT NULL DEFAULT false,
|
||||
"type" TEXT,
|
||||
"apiUrl" TEXT,
|
||||
"htmlUrl" TEXT,
|
||||
"customPort" INTEGER NOT NULL DEFAULT 22,
|
||||
"organization" TEXT,
|
||||
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" DATETIME NOT NULL,
|
||||
"githubAppId" TEXT,
|
||||
"gitlabAppId" TEXT,
|
||||
"isSystemWide" BOOLEAN NOT NULL DEFAULT false,
|
||||
CONSTRAINT "GitSource_gitlabAppId_fkey" FOREIGN KEY ("gitlabAppId") REFERENCES "GitlabApp" ("id") ON DELETE SET NULL ON UPDATE CASCADE,
|
||||
CONSTRAINT "GitSource_githubAppId_fkey" FOREIGN KEY ("githubAppId") REFERENCES "GithubApp" ("id") ON DELETE SET NULL ON UPDATE CASCADE
|
||||
);
|
||||
INSERT INTO "new_GitSource" ("apiUrl", "createdAt", "customPort", "forPublic", "githubAppId", "gitlabAppId", "htmlUrl", "id", "name", "organization", "type", "updatedAt") SELECT "apiUrl", "createdAt", "customPort", "forPublic", "githubAppId", "gitlabAppId", "htmlUrl", "id", "name", "organization", "type", "updatedAt" FROM "GitSource";
|
||||
DROP TABLE "GitSource";
|
||||
ALTER TABLE "new_GitSource" RENAME TO "GitSource";
|
||||
CREATE UNIQUE INDEX "GitSource_githubAppId_key" ON "GitSource"("githubAppId");
|
||||
CREATE UNIQUE INDEX "GitSource_gitlabAppId_key" ON "GitSource"("gitlabAppId");
|
||||
PRAGMA foreign_key_check;
|
||||
PRAGMA foreign_keys=ON;
|
@ -299,6 +299,7 @@ model GitSource {
|
||||
updatedAt DateTime @updatedAt
|
||||
githubAppId String? @unique
|
||||
gitlabAppId String? @unique
|
||||
isSystemWide Boolean @default(false)
|
||||
gitlabApp GitlabApp? @relation(fields: [gitlabAppId], references: [id])
|
||||
githubApp GithubApp? @relation(fields: [githubAppId], references: [id])
|
||||
application Application[]
|
||||
|
@ -21,7 +21,7 @@ import { scheduler } from './scheduler';
|
||||
import { supportedServiceTypesAndVersions } from './services/supportedVersions';
|
||||
import { includeServices } from './services/common';
|
||||
|
||||
export const version = '3.10.9';
|
||||
export const version = '3.10.10';
|
||||
export const isDev = process.env.NODE_ENV === 'development';
|
||||
|
||||
const algorithm = 'aes-256-ctr';
|
||||
|
@ -135,7 +135,7 @@ export async function showDashboard(request: FastifyRequest) {
|
||||
include: { destinationDocker: true, teams: true },
|
||||
});
|
||||
const gitSources = await prisma.gitSource.findMany({
|
||||
where: { teams: { some: { id: teamId === "0" ? undefined : teamId } } },
|
||||
where: { OR: [{ teams: { some: { id: teamId === "0" ? undefined : teamId } } }, { isSystemWide: true }] },
|
||||
include: { teams: true },
|
||||
});
|
||||
const destinations = await prisma.destinationDocker.findMany({
|
||||
|
@ -9,7 +9,7 @@ export async function listSources(request: FastifyRequest) {
|
||||
try {
|
||||
const teamId = request.user?.teamId;
|
||||
const sources = await prisma.gitSource.findMany({
|
||||
where: { teams: { some: { id: teamId === '0' ? undefined : teamId } } },
|
||||
where: { OR: [{ teams: { some: { id: teamId === "0" ? undefined : teamId } } }, { isSystemWide: true }] },
|
||||
include: { teams: true, githubApp: true, gitlabApp: true }
|
||||
});
|
||||
return {
|
||||
@ -22,11 +22,11 @@ export async function listSources(request: FastifyRequest) {
|
||||
export async function saveSource(request, reply) {
|
||||
try {
|
||||
const { id } = request.params
|
||||
let { name, htmlUrl, apiUrl, customPort } = request.body
|
||||
let { name, htmlUrl, apiUrl, customPort, isSystemWide } = request.body
|
||||
if (customPort) customPort = Number(customPort)
|
||||
await prisma.gitSource.update({
|
||||
where: { id },
|
||||
data: { name, htmlUrl, apiUrl, customPort }
|
||||
data: { name, htmlUrl, apiUrl, customPort, isSystemWide }
|
||||
});
|
||||
return reply.code(201).send()
|
||||
} catch ({ status, message }) {
|
||||
@ -56,7 +56,7 @@ export async function getSource(request: FastifyRequest<OnlyId>) {
|
||||
}
|
||||
|
||||
const source = await prisma.gitSource.findFirst({
|
||||
where: { id, teams: { some: { id: teamId === '0' ? undefined : teamId } } },
|
||||
where: { id, OR: [{ teams: { some: { id: teamId === "0" ? undefined : teamId } } }, { isSystemWide: true }] },
|
||||
include: { githubApp: true, gitlabApp: true }
|
||||
});
|
||||
if (!source) {
|
||||
@ -104,7 +104,7 @@ export async function saveGitHubSource(request: FastifyRequest<SaveGitHubSource>
|
||||
const { teamId } = request.user
|
||||
|
||||
const { id } = request.params
|
||||
let { name, htmlUrl, apiUrl, organization, customPort } = request.body
|
||||
let { name, htmlUrl, apiUrl, organization, customPort, isSystemWide } = request.body
|
||||
|
||||
if (customPort) customPort = Number(customPort)
|
||||
if (id === 'new') {
|
||||
@ -117,6 +117,7 @@ export async function saveGitHubSource(request: FastifyRequest<SaveGitHubSource>
|
||||
apiUrl,
|
||||
organization,
|
||||
customPort,
|
||||
isSystemWide,
|
||||
type: 'github',
|
||||
teams: { connect: { id: teamId } }
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ export interface SaveGitHubSource extends OnlyId {
|
||||
apiUrl: string,
|
||||
organization: string,
|
||||
customPort: number,
|
||||
isSystemWide: boolean
|
||||
}
|
||||
}
|
||||
export interface SaveGitLabSource extends OnlyId {
|
||||
|
1
apps/ui/src/lib/components/Beta.svelte
Normal file
1
apps/ui/src/lib/components/Beta.svelte
Normal file
@ -0,0 +1 @@
|
||||
<span class="badge bg-coollabs-gradient rounded text-white font-normal"> BETA </span>
|
@ -1,10 +1,13 @@
|
||||
<script lang="ts">
|
||||
import Beta from './Beta.svelte';
|
||||
import Explaner from './Explainer.svelte';
|
||||
import Tooltip from './Tooltip.svelte';
|
||||
|
||||
export let id: any;
|
||||
export let customClass: any = null;
|
||||
export let setting: any;
|
||||
export let title: any;
|
||||
export let isBeta: any = false;
|
||||
export let description: any;
|
||||
export let isCenter = true;
|
||||
export let disabled = false;
|
||||
@ -18,13 +21,16 @@
|
||||
<!-- svelte-ignore a11y-label-has-associated-control -->
|
||||
<label>
|
||||
{title}
|
||||
{#if isBeta}
|
||||
<Beta />
|
||||
{/if}
|
||||
{#if description && description !== ''}
|
||||
<Explaner explanation={description} />
|
||||
{/if}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class:text-center={isCenter} class="flex justify-center">
|
||||
<div class:text-center={isCenter} class={`flex justify-center ${customClass}`}>
|
||||
<div
|
||||
on:click
|
||||
aria-pressed="false"
|
||||
|
@ -27,6 +27,7 @@
|
||||
import { onDestroy, onMount } from 'svelte';
|
||||
import { get, post } from '$lib/api';
|
||||
import { errorNotification } from '$lib/common';
|
||||
import Beta from './Beta.svelte';
|
||||
async function getStatus() {
|
||||
if (loading.usage) return;
|
||||
loading.usage = true;
|
||||
@ -78,7 +79,7 @@
|
||||
<h1 class="font-bold text-lg lg:text-xl truncate">
|
||||
{server.name}
|
||||
{#if server.remoteEngine}
|
||||
<span class="badge bg-coollabs-gradient rounded text-white"> BETA </span>
|
||||
<Beta />
|
||||
{/if}
|
||||
</h1>
|
||||
<div class="text-xs">
|
||||
|
@ -362,7 +362,7 @@
|
||||
</svg>
|
||||
</button>
|
||||
<Tooltip triggeredBy="#forceredeploy">Force Redeploy (without cache)</Tooltip>
|
||||
{:else if $isDeploymentEnabled}
|
||||
{:else if $isDeploymentEnabled && !$page.url.pathname.startsWith(`/applications/${id}/configuration/`)}
|
||||
<button
|
||||
class="icons flex items-center font-bold"
|
||||
disabled={!$isDeploymentEnabled}
|
||||
|
@ -152,8 +152,8 @@
|
||||
</div>
|
||||
{:else}
|
||||
<form on:submit|preventDefault={handleSubmit} class="px-10">
|
||||
<div class="flex lg:flex-row flex-col lg:space-y-0 space-y-2 space-x-0 lg:space-x-2 items-center">
|
||||
<div class="custom-select-wrapper w-1/2"><label for="repository" class="pb-1">Repository</label>
|
||||
<div class="flex lg:flex-row flex-col lg:space-y-0 space-y-2 space-x-0 lg:space-x-2 items-center lg:justify-center">
|
||||
<div class="custom-select-wrapper"><label for="repository" class="pb-1">Repository</label>
|
||||
<Select
|
||||
placeholder={loading.repositories
|
||||
? $t('application.configuration.loading_repositories')
|
||||
@ -168,7 +168,7 @@
|
||||
/>
|
||||
</div>
|
||||
<input class="hidden" bind:value={selected.projectId} name="projectId" />
|
||||
<div class="custom-select-wrapper w-1/2"><label for="repository" class="pb-1">Branch</label>
|
||||
<div class="custom-select-wrapper"><label for="repository" class="pb-1">Branch</label>
|
||||
<Select
|
||||
placeholder={loading.branches
|
||||
? $t('application.configuration.loading_branches')
|
||||
|
@ -328,8 +328,9 @@
|
||||
</script>
|
||||
|
||||
<form on:submit={handleSubmit}>
|
||||
<div class="flex flex-col space-y-2 px-4 xl:flex-row xl:space-y-0 xl:space-x-2 ">
|
||||
<div class="flex lg:flex-row flex-col lg:space-y-0 space-y-2 space-x-0 lg:space-x-2 items-center lg:justify-center">
|
||||
<div class="custom-select-wrapper">
|
||||
<label for="groups" class="pb-1">Groups</label>
|
||||
<Select
|
||||
placeholder={loading.base
|
||||
? $t('application.configuration.loading_groups')
|
||||
@ -355,6 +356,7 @@
|
||||
/>
|
||||
</div>
|
||||
<div class="custom-select-wrapper">
|
||||
<label for="projects" class="pb-1">Projects</label>
|
||||
<Select
|
||||
placeholder={loading.projects
|
||||
? $t('application.configuration.loading_projects')
|
||||
@ -380,6 +382,7 @@
|
||||
/>
|
||||
</div>
|
||||
<div class="custom-select-wrapper">
|
||||
<label for="branches" class="pb-1">Branches</label>
|
||||
<Select
|
||||
placeholder={loading.branches
|
||||
? $t('application.configuration.loading_branches')
|
||||
|
@ -53,7 +53,6 @@
|
||||
return source;
|
||||
}
|
||||
});
|
||||
|
||||
async function handleSubmit(gitSourceId: string) {
|
||||
try {
|
||||
await post(`/applications/${id}/configuration/source`, { gitSourceId });
|
||||
@ -71,7 +70,7 @@
|
||||
<div class="max-w-screen-2xl mx-auto px-9">
|
||||
<div class="title pb-8">Git App</div>
|
||||
<div class="flex flex-wrap justify-center">
|
||||
{#if !filteredSources || ownSources.length === 0}
|
||||
{#if !filteredSources}
|
||||
<div class="flex-col">
|
||||
<div class="pb-2 text-center font-bold">
|
||||
{$t('application.configuration.no_configurable_git')}
|
||||
@ -169,11 +168,68 @@
|
||||
<button
|
||||
disabled={source.gitlabApp && !source.gitlabAppId}
|
||||
type="submit"
|
||||
class="disabled:opacity-95 bg-coolgray-200 disabled:text-white box-selection hover:bg-orange-700 group"
|
||||
class="relative disabled:opacity-95 bg-coolgray-200 disabled:text-white box-selection hover:bg-orange-700 group"
|
||||
class:border-red-500={source.gitlabApp && !source.gitlabAppId}
|
||||
class:border-0={source.gitlabApp && !source.gitlabAppId}
|
||||
class:border-l-4={source.gitlabApp && !source.gitlabAppId}
|
||||
>
|
||||
<div class="absolute top-0 left-0 -m-5 flex">
|
||||
{#if source?.type === 'gitlab'}
|
||||
<svg viewBox="0 0 128 128" class="h-10 w-10">
|
||||
<path
|
||||
fill="#FC6D26"
|
||||
d="M126.615 72.31l-7.034-21.647L105.64 7.76c-.716-2.206-3.84-2.206-4.556 0l-13.94 42.903H40.856L26.916 7.76c-.717-2.206-3.84-2.206-4.557 0L8.42 50.664 1.385 72.31a4.792 4.792 0 001.74 5.358L64 121.894l60.874-44.227a4.793 4.793 0 001.74-5.357"
|
||||
/><path fill="#E24329" d="M64 121.894l23.144-71.23H40.856L64 121.893z" /><path
|
||||
fill="#FC6D26"
|
||||
d="M64 121.894l-23.144-71.23H8.42L64 121.893z"
|
||||
/><path
|
||||
fill="#FCA326"
|
||||
d="M8.42 50.663L1.384 72.31a4.79 4.79 0 001.74 5.357L64 121.894 8.42 50.664z"
|
||||
/><path
|
||||
fill="#E24329"
|
||||
d="M8.42 50.663h32.436L26.916 7.76c-.717-2.206-3.84-2.206-4.557 0L8.42 50.664z"
|
||||
/><path fill="#FC6D26" d="M64 121.894l23.144-71.23h32.437L64 121.893z" /><path
|
||||
fill="#FCA326"
|
||||
d="M119.58 50.663l7.035 21.647a4.79 4.79 0 01-1.74 5.357L64 121.894l55.58-71.23z"
|
||||
/><path
|
||||
fill="#E24329"
|
||||
d="M119.58 50.663H87.145l13.94-42.902c.717-2.206 3.84-2.206 4.557 0l13.94 42.903z"
|
||||
/>
|
||||
</svg>
|
||||
{:else if source?.type === 'github'}
|
||||
<svg viewBox="0 0 128 128" class="h-10 w-10">
|
||||
<g fill="#ffffff"
|
||||
><path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M64 5.103c-33.347 0-60.388 27.035-60.388 60.388 0 26.682 17.303 49.317 41.297 57.303 3.017.56 4.125-1.31 4.125-2.905 0-1.44-.056-6.197-.082-11.243-16.8 3.653-20.345-7.125-20.345-7.125-2.747-6.98-6.705-8.836-6.705-8.836-5.48-3.748.413-3.67.413-3.67 6.063.425 9.257 6.223 9.257 6.223 5.386 9.23 14.127 6.562 17.573 5.02.542-3.903 2.107-6.568 3.834-8.076-13.413-1.525-27.514-6.704-27.514-29.843 0-6.593 2.36-11.98 6.223-16.21-.628-1.52-2.695-7.662.584-15.98 0 0 5.07-1.623 16.61 6.19C53.7 35 58.867 34.327 64 34.304c5.13.023 10.3.694 15.127 2.033 11.526-7.813 16.59-6.19 16.59-6.19 3.287 8.317 1.22 14.46.593 15.98 3.872 4.23 6.215 9.617 6.215 16.21 0 23.194-14.127 28.3-27.574 29.796 2.167 1.874 4.097 5.55 4.097 11.183 0 8.08-.07 14.583-.07 16.572 0 1.607 1.088 3.49 4.148 2.897 23.98-7.994 41.263-30.622 41.263-57.294C124.388 32.14 97.35 5.104 64 5.104z"
|
||||
/><path
|
||||
d="M26.484 91.806c-.133.3-.605.39-1.035.185-.44-.196-.685-.605-.543-.906.13-.31.603-.395 1.04-.188.44.197.69.61.537.91zm2.446 2.729c-.287.267-.85.143-1.232-.28-.396-.42-.47-.983-.177-1.254.298-.266.844-.14 1.24.28.394.426.472.984.17 1.255zM31.312 98.012c-.37.258-.976.017-1.35-.52-.37-.538-.37-1.183.01-1.44.373-.258.97-.025 1.35.507.368.545.368 1.19-.01 1.452zm3.261 3.361c-.33.365-1.036.267-1.552-.23-.527-.487-.674-1.18-.343-1.544.336-.366 1.045-.264 1.564.23.527.486.686 1.18.333 1.543zm4.5 1.951c-.147.473-.825.688-1.51.486-.683-.207-1.13-.76-.99-1.238.14-.477.823-.7 1.512-.485.683.206 1.13.756.988 1.237zm4.943.361c.017.498-.563.91-1.28.92-.723.017-1.308-.387-1.315-.877 0-.503.568-.91 1.29-.924.717-.013 1.306.387 1.306.88zm4.598-.782c.086.485-.413.984-1.126 1.117-.7.13-1.35-.172-1.44-.653-.086-.498.422-.997 1.122-1.126.714-.123 1.354.17 1.444.663zm0 0"
|
||||
/></g
|
||||
>
|
||||
</svg>
|
||||
{/if}
|
||||
{#if source.isSystemWide}
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-10 w-10"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor"
|
||||
fill="none"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<circle cx="12" cy="12" r="9" />
|
||||
<line x1="3.6" y1="9" x2="20.4" y2="9" />
|
||||
<line x1="3.6" y1="15" x2="20.4" y2="15" />
|
||||
<path d="M11.5 3a17 17 0 0 0 0 18" />
|
||||
<path d="M12.5 3a17 17 0 0 1 0 18" />
|
||||
</svg>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div class="font-bold text-xl text-center truncate">{source.name}</div>
|
||||
{#if source.gitlabApp && !source.gitlabAppId}
|
||||
<div class="font-bold text-center truncate text-red-500 group-hover:text-white">
|
||||
|
@ -148,7 +148,7 @@
|
||||
class="flex cursor-pointer items-center justify-center py-4 no-underline transition-all duration-150 hover:bg-coolgray-300 hover:shadow-xl"
|
||||
class:bg-coolgray-200={$selectedBuildId === build.id}
|
||||
>
|
||||
<div class="flex-col px-2 text-center min-w-[10rem]">
|
||||
<div class="flex-col px-2 text-center">
|
||||
<div class="text-sm font-bold truncate">
|
||||
{build.branch || application.branch}
|
||||
</div>
|
||||
|
@ -41,25 +41,44 @@
|
||||
|
||||
let numberOfGetStatus = 0;
|
||||
let status: any = {};
|
||||
let noInitialStatus: any = {
|
||||
applications: false,
|
||||
services: false,
|
||||
databases: false
|
||||
};
|
||||
let loading = {
|
||||
applications: false,
|
||||
services: false,
|
||||
databases: false
|
||||
};
|
||||
doSearch();
|
||||
|
||||
async function refreshStatusApplications() {
|
||||
loading.applications = true;
|
||||
noInitialStatus.applications = false;
|
||||
numberOfGetStatus = 0;
|
||||
for (const application of applications) {
|
||||
getStatus(application, true);
|
||||
await getStatus(application, true);
|
||||
}
|
||||
loading.applications = false;
|
||||
}
|
||||
async function refreshStatusServices() {
|
||||
loading.services = true;
|
||||
noInitialStatus.services = false;
|
||||
numberOfGetStatus = 0;
|
||||
for (const service of services) {
|
||||
getStatus(service, true);
|
||||
await getStatus(service, true);
|
||||
}
|
||||
loading.services = false;
|
||||
}
|
||||
async function refreshStatusDatabases() {
|
||||
loading.databases = true;
|
||||
noInitialStatus.databases = false;
|
||||
numberOfGetStatus = 0;
|
||||
for (const database of databases) {
|
||||
getStatus(database, true);
|
||||
await getStatus(database, true);
|
||||
}
|
||||
loading.databases = false;
|
||||
}
|
||||
function setInitials(onlyOthers: boolean = false) {
|
||||
return {
|
||||
@ -109,9 +128,15 @@
|
||||
async function getStatus(resources: any, force: boolean = false) {
|
||||
const { id, buildPack, dualCerts, type } = resources;
|
||||
if (buildPack && applications.length > 10 && !force) {
|
||||
noInitialStatus.applications = true;
|
||||
return;
|
||||
}
|
||||
if (type && services.length > 10 && !force) {
|
||||
noInitialStatus.services = true;
|
||||
return;
|
||||
}
|
||||
if (databases.length > 10 && !force) {
|
||||
noInitialStatus.databases = true;
|
||||
return;
|
||||
}
|
||||
if (status[id] && !force) return status[id];
|
||||
@ -498,8 +523,12 @@
|
||||
{#if (filtered.applications.length > 0 && applications.length > 0) || filtered.otherApplications.length > 0}
|
||||
<div class="flex items-center mt-10">
|
||||
<h1 class="title lg:text-3xl pr-4">Applications</h1>
|
||||
<button class="btn btn-sm btn-primary" on:click={refreshStatusApplications}
|
||||
>Refresh Status</button
|
||||
<button
|
||||
class="btn btn-sm btn-primary"
|
||||
class:loading={loading.applications}
|
||||
disabled={loading.applications}
|
||||
on:click={refreshStatusApplications}
|
||||
>{noInitialStatus.applications ? 'Load Status' : 'Refresh Status'}</button
|
||||
>
|
||||
</div>
|
||||
{/if}
|
||||
@ -515,13 +544,17 @@
|
||||
class="w-full rounded p-5 bg-coolgray-200 hover:bg-green-600 indicator duration-150"
|
||||
>
|
||||
{#await getStatus(application)}
|
||||
<span class="indicator-item badge bg-yellow-500 badge-sm" />
|
||||
<span class="indicator-item badge bg-yellow-300 badge-sm" />
|
||||
{:then}
|
||||
{#if status[application.id] === 'running'}
|
||||
{#if !noInitialStatus.applications}
|
||||
{#if loading.applications}
|
||||
<span class="indicator-item badge bg-yellow-300 badge-sm" />
|
||||
{:else if status[application.id] === 'running'}
|
||||
<span class="indicator-item badge bg-success badge-sm" />
|
||||
{:else}
|
||||
<span class="indicator-item badge bg-error badge-sm" />
|
||||
{/if}
|
||||
{/if}
|
||||
{/await}
|
||||
<div class="w-full flex flex-row">
|
||||
<ApplicationsIcons {application} isAbsolute={true} />
|
||||
@ -609,9 +642,6 @@
|
||||
{#if filtered.applications.length > 0}
|
||||
<div class="divider w-32 mx-auto" />
|
||||
{/if}
|
||||
<div class="flex items-center mt-10">
|
||||
<h1 class="text-lg font-bold">Other Teams</h1>
|
||||
</div>
|
||||
{/if}
|
||||
{#if filtered.otherApplications.length > 0}
|
||||
<div
|
||||
@ -621,13 +651,17 @@
|
||||
<a class="no-underline mb-5" href={`/applications/${application.id}`}>
|
||||
<div class="w-full rounded p-5 bg-coolgray-200 hover:bg-green-600 indicator duration-150">
|
||||
{#await getStatus(application)}
|
||||
<span class="indicator-item badge bg-yellow-500 badge-sm" />
|
||||
<span class="indicator-item badge bg-yellow-300 badge-sm" />
|
||||
{:then}
|
||||
{#if status[application.id] === 'running'}
|
||||
{#if !noInitialStatus.applications}
|
||||
{#if loading.applications}
|
||||
<span class="indicator-item badge bg-yellow-300 badge-sm" />
|
||||
{:else if status[application.id] === 'running'}
|
||||
<span class="indicator-item badge bg-success badge-sm" />
|
||||
{:else}
|
||||
<span class="indicator-item badge bg-error badge-sm" />
|
||||
{/if}
|
||||
{/if}
|
||||
{/await}
|
||||
<div class="w-full flex flex-row">
|
||||
<ApplicationsIcons {application} isAbsolute={true} />
|
||||
@ -708,7 +742,12 @@
|
||||
{#if (filtered.services.length > 0 && services.length > 0) || filtered.otherServices.length > 0}
|
||||
<div class="flex items-center mt-10">
|
||||
<h1 class="title lg:text-3xl pr-4">Services</h1>
|
||||
<button class="btn btn-sm btn-primary" on:click={refreshStatusServices}>Refresh Status</button
|
||||
<button
|
||||
class="btn btn-sm btn-primary"
|
||||
class:loading={loading.services}
|
||||
disabled={loading.services}
|
||||
on:click={refreshStatusServices}
|
||||
>{noInitialStatus.services ? 'Load Status' : 'Refresh Status'}</button
|
||||
>
|
||||
</div>
|
||||
{/if}
|
||||
@ -724,13 +763,17 @@
|
||||
class="w-full rounded p-5 bg-coolgray-200 hover:bg-pink-600 indicator duration-150"
|
||||
>
|
||||
{#await getStatus(service)}
|
||||
<span class="indicator-item badge bg-yellow-500 badge-sm" />
|
||||
<span class="indicator-item badge bg-yellow-300 badge-sm" />
|
||||
{:then}
|
||||
{#if status[service.id] === 'running'}
|
||||
{#if !noInitialStatus.services}
|
||||
{#if loading.services}
|
||||
<span class="indicator-item badge bg-yellow-300 badge-sm" />
|
||||
{:else if status[service.id] === 'running'}
|
||||
<span class="indicator-item badge bg-success badge-sm" />
|
||||
{:else}
|
||||
<span class="indicator-item badge bg-error badge-sm" />
|
||||
{/if}
|
||||
{/if}
|
||||
{/await}
|
||||
<div class="w-full flex flex-row">
|
||||
<ServiceIcons type={service.type} isAbsolute={true} />
|
||||
@ -784,9 +827,6 @@
|
||||
{#if filtered.services.length > 0}
|
||||
<div class="divider w-32 mx-auto" />
|
||||
{/if}
|
||||
<div class="flex items-center mt-10">
|
||||
<h1 class="text-lg font-bold">Other Teams</h1>
|
||||
</div>
|
||||
{/if}
|
||||
{#if filtered.otherServices.length > 0}
|
||||
<div
|
||||
@ -796,13 +836,17 @@
|
||||
<a class="no-underline mb-5" href={`/services/${service.id}`}>
|
||||
<div class="w-full rounded p-5 bg-coolgray-200 hover:bg-pink-600 indicator duration-150">
|
||||
{#await getStatus(service)}
|
||||
<span class="indicator-item badge bg-yellow-500 badge-sm" />
|
||||
<span class="indicator-item badge bg-yellow-300 badge-sm" />
|
||||
{:then}
|
||||
{#if status[service.id] === 'running'}
|
||||
{#if !noInitialStatus.services}
|
||||
{#if loading.services}
|
||||
<span class="indicator-item badge bg-yellow-300 badge-sm" />
|
||||
{:else if status[service.id] === 'running'}
|
||||
<span class="indicator-item badge bg-success badge-sm" />
|
||||
{:else}
|
||||
<span class="indicator-item badge bg-error badge-sm" />
|
||||
{/if}
|
||||
{/if}
|
||||
{/await}
|
||||
<div class="w-full flex flex-row">
|
||||
<ServiceIcons type={service.type} isAbsolute={true} />
|
||||
@ -852,8 +896,12 @@
|
||||
{#if (filtered.databases.length > 0 && databases.length > 0) || filtered.otherDatabases.length > 0}
|
||||
<div class="flex items-center mt-10">
|
||||
<h1 class="title lg:text-3xl pr-4">Databases</h1>
|
||||
<button class="btn btn-sm btn-primary" on:click={refreshStatusDatabases}
|
||||
>Refresh Status</button
|
||||
<button
|
||||
class="btn btn-sm btn-primary"
|
||||
on:click={refreshStatusDatabases}
|
||||
class:loading={loading.databases}
|
||||
disabled={loading.databases}
|
||||
>{noInitialStatus.databases ? 'Load Status' : 'Refresh Status'}</button
|
||||
>
|
||||
</div>
|
||||
{/if}
|
||||
@ -869,13 +917,17 @@
|
||||
class="w-full rounded p-5 bg-coolgray-200 hover:bg-databases indicator duration-150"
|
||||
>
|
||||
{#await getStatus(database)}
|
||||
<span class="indicator-item badge bg-yellow-500 badge-sm" />
|
||||
<span class="indicator-item badge bg-yellow-300 badge-sm" />
|
||||
{:then}
|
||||
{#if status[database.id] === 'running'}
|
||||
{#if !noInitialStatus.databases}
|
||||
{#if loading.databases}
|
||||
<span class="indicator-item badge bg-yellow-300 badge-sm" />
|
||||
{:else if status[databases.id] === 'running'}
|
||||
<span class="indicator-item badge bg-success badge-sm" />
|
||||
{:else}
|
||||
<span class="indicator-item badge bg-error badge-sm" />
|
||||
{/if}
|
||||
{/if}
|
||||
{/await}
|
||||
<div class="w-full flex flex-row">
|
||||
<DatabaseIcons type={database.type} isAbsolute={true} />
|
||||
@ -933,9 +985,6 @@
|
||||
{#if filtered.databases.length > 0}
|
||||
<div class="divider w-32 mx-auto" />
|
||||
{/if}
|
||||
<div class="flex items-center mt-10">
|
||||
<h1 class="text-lg font-bold">Other Teams</h1>
|
||||
</div>
|
||||
{/if}
|
||||
{#if filtered.otherDatabases.length > 0}
|
||||
<div
|
||||
@ -945,13 +994,17 @@
|
||||
<a class="no-underline mb-5" href={`/databases/${database.id}`}>
|
||||
<div class="w-full rounded p-5 bg-coolgray-200 hover:bg-databases indicator duration-150">
|
||||
{#await getStatus(database)}
|
||||
<span class="indicator-item badge bg-yellow-500 badge-sm" />
|
||||
<span class="indicator-item badge bg-yellow-300 badge-sm" />
|
||||
{:then}
|
||||
{#if status[database.id] === 'running'}
|
||||
{#if !noInitialStatus.databases}
|
||||
{#if loading.databases}
|
||||
<span class="indicator-item badge bg-yellow-300 badge-sm" />
|
||||
{:else if status[databases.id] === 'running'}
|
||||
<span class="indicator-item badge bg-success badge-sm" />
|
||||
{:else}
|
||||
<span class="indicator-item badge bg-error badge-sm" />
|
||||
{/if}
|
||||
{/if}
|
||||
{/await}
|
||||
<div class="w-full flex flex-row">
|
||||
<DatabaseIcons type={database.type} isAbsolute={true} />
|
||||
@ -1017,9 +1070,9 @@
|
||||
<a class="no-underline mb-5" href={`/sources/${source.id}`}>
|
||||
<div class="w-full rounded p-5 bg-coolgray-200 hover:bg-sources indicator duration-150">
|
||||
<div class="w-full flex flex-row">
|
||||
<div class="absolute top-0 left-0 -m-5 h-10 w-10">
|
||||
<div class="absolute top-0 left-0 -m-5 flex">
|
||||
{#if source?.type === 'gitlab'}
|
||||
<svg viewBox="0 0 128 128">
|
||||
<svg viewBox="0 0 128 128" class="h-10 w-10">
|
||||
<path
|
||||
fill="#FC6D26"
|
||||
d="M126.615 72.31l-7.034-21.647L105.64 7.76c-.716-2.206-3.84-2.206-4.556 0l-13.94 42.903H40.856L26.916 7.76c-.717-2.206-3.84-2.206-4.557 0L8.42 50.664 1.385 72.31a4.792 4.792 0 001.74 5.358L64 121.894l60.874-44.227a4.793 4.793 0 001.74-5.357"
|
||||
@ -1041,7 +1094,7 @@
|
||||
/>
|
||||
</svg>
|
||||
{:else if source?.type === 'github'}
|
||||
<svg viewBox="0 0 128 128">
|
||||
<svg viewBox="0 0 128 128" class="h-10 w-10">
|
||||
<g fill="#ffffff"
|
||||
><path
|
||||
fill-rule="evenodd"
|
||||
@ -1053,6 +1106,26 @@
|
||||
>
|
||||
</svg>
|
||||
{/if}
|
||||
|
||||
{#if source.isSystemWide}
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-10 w-10"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor"
|
||||
fill="none"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<circle cx="12" cy="12" r="9" />
|
||||
<line x1="3.6" y1="9" x2="20.4" y2="9" />
|
||||
<line x1="3.6" y1="15" x2="20.4" y2="15" />
|
||||
<path d="M11.5 3a17 17 0 0 0 0 18" />
|
||||
<path d="M12.5 3a17 17 0 0 1 0 18" />
|
||||
</svg>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="w-full flex flex-col">
|
||||
<div class="h-10">
|
||||
@ -1077,9 +1150,6 @@
|
||||
{#if filtered.gitSources.length > 0}
|
||||
<div class="divider w-32 mx-auto" />
|
||||
{/if}
|
||||
<div class="flex items-center mt-10">
|
||||
<h1 class="text-lg font-bold">Other Teams</h1>
|
||||
</div>
|
||||
{/if}
|
||||
{#if filtered.otherGitSources.length > 0}
|
||||
<div
|
||||
@ -1089,9 +1159,9 @@
|
||||
<a class="no-underline mb-5" href={`/sources/${source.id}`}>
|
||||
<div class="w-full rounded p-5 bg-coolgray-200 hover:bg-sources indicator duration-150">
|
||||
<div class="w-full flex flex-row">
|
||||
<div class="absolute top-0 left-0 -m-5 h-10 w-10">
|
||||
<div class="absolute top-0 left-0 -m-5 flex">
|
||||
{#if source?.type === 'gitlab'}
|
||||
<svg viewBox="0 0 128 128">
|
||||
<svg viewBox="0 0 128 128" class="h-10 w-10">
|
||||
<path
|
||||
fill="#FC6D26"
|
||||
d="M126.615 72.31l-7.034-21.647L105.64 7.76c-.716-2.206-3.84-2.206-4.556 0l-13.94 42.903H40.856L26.916 7.76c-.717-2.206-3.84-2.206-4.557 0L8.42 50.664 1.385 72.31a4.792 4.792 0 001.74 5.358L64 121.894l60.874-44.227a4.793 4.793 0 001.74-5.357"
|
||||
@ -1113,7 +1183,7 @@
|
||||
/>
|
||||
</svg>
|
||||
{:else if source?.type === 'github'}
|
||||
<svg viewBox="0 0 128 128">
|
||||
<svg viewBox="0 0 128 128" class="h-10 w-10">
|
||||
<g fill="#ffffff"
|
||||
><path
|
||||
fill-rule="evenodd"
|
||||
@ -1125,6 +1195,26 @@
|
||||
>
|
||||
</svg>
|
||||
{/if}
|
||||
|
||||
{#if source.isSystemWide}
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-10 w-10"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor"
|
||||
fill="none"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<circle cx="12" cy="12" r="9" />
|
||||
<line x1="3.6" y1="9" x2="20.4" y2="9" />
|
||||
<line x1="3.6" y1="15" x2="20.4" y2="15" />
|
||||
<path d="M11.5 3a17 17 0 0 0 0 18" />
|
||||
<path d="M12.5 3a17 17 0 0 1 0 18" />
|
||||
</svg>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="w-full flex flex-col">
|
||||
<div class="h-10">
|
||||
@ -1228,9 +1318,6 @@
|
||||
{#if filtered.destinations.length > 0}
|
||||
<div class="divider w-32 mx-auto" />
|
||||
{/if}
|
||||
<div class="flex items-center mt-10">
|
||||
<h1 class="text-lg font-bold">Other Teams</h1>
|
||||
</div>
|
||||
{/if}
|
||||
{#if filtered.otherDestinations.length > 0}
|
||||
<div
|
||||
|
@ -20,6 +20,7 @@
|
||||
export let certificates: any;
|
||||
import { del, post } from '$lib/api';
|
||||
import { errorNotification } from '$lib/common';
|
||||
import Beta from '$lib/components/Beta.svelte';
|
||||
|
||||
let loading = {
|
||||
save: false
|
||||
@ -57,7 +58,7 @@
|
||||
|
||||
<div class="mx-auto w-full">
|
||||
<div class="flex border-b border-coolgray-500 mb-6">
|
||||
<div class="title font-bold pb-3 pr-4">SSL Certificates <span class="badge rounded bg-coollabs-gradient text-white">BETA</span></div>
|
||||
<div class="title font-bold pb-3 pr-4">SSL Certificates <Beta /></div>
|
||||
<label for="my-modal" class="btn btn-sm btn-primary" on:click={() => (isModalActive = true)}
|
||||
>Add SSL Certificate</label
|
||||
>
|
||||
|
@ -8,6 +8,7 @@
|
||||
import { addToast, appSession } from '$lib/store';
|
||||
import { dev } from '$app/env';
|
||||
import Explainer from '$lib/components/Explainer.svelte';
|
||||
import Setting from '$lib/components/Setting.svelte';
|
||||
|
||||
const { id } = $page.params;
|
||||
|
||||
@ -21,7 +22,8 @@
|
||||
await post(`/sources/${id}`, {
|
||||
name: source.name,
|
||||
htmlUrl: source.htmlUrl.replace(/\/$/, ''),
|
||||
apiUrl: source.apiUrl.replace(/\/$/, '')
|
||||
apiUrl: source.apiUrl.replace(/\/$/, ''),
|
||||
isSystemWide: source.isSystemWide
|
||||
});
|
||||
return addToast({
|
||||
message: 'Configuration saved.',
|
||||
@ -43,7 +45,8 @@
|
||||
htmlUrl: source.htmlUrl.replace(/\/$/, ''),
|
||||
apiUrl: source.apiUrl.replace(/\/$/, ''),
|
||||
organization: source.organization,
|
||||
customPort: source.customPort
|
||||
customPort: source.customPort,
|
||||
isSystemWide: source.isSystemWide
|
||||
});
|
||||
const { organization, htmlUrl } = source;
|
||||
const { fqdn, ipv4, ipv6 } = settings;
|
||||
@ -88,6 +91,16 @@
|
||||
return errorNotification(error);
|
||||
}
|
||||
}
|
||||
async function changeSettings(name: any, save: boolean) {
|
||||
if ($appSession.teamId === '0') {
|
||||
if (name === 'isSystemWide') {
|
||||
source.isSystemWide = !source.isSystemWide;
|
||||
}
|
||||
if (save) {
|
||||
await handleSubmit();
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="mx-auto max-w-6xl lg:px-6 px-3">
|
||||
@ -104,13 +117,13 @@
|
||||
{/if}
|
||||
</div>
|
||||
<div class="grid gap-2 grid-cols-2 auto-rows-max">
|
||||
<label for="name" class="text-base font-bold text-stone-100">Name</label>
|
||||
<label for="name">Name</label>
|
||||
<input class="w-full" name="name" id="name" required bind:value={source.name} />
|
||||
<label for="htmlUrl" class="text-base font-bold text-stone-100">HTML URL</label>
|
||||
<label for="htmlUrl">HTML URL</label>
|
||||
<input class="w-full" name="htmlUrl" id="htmlUrl" required bind:value={source.htmlUrl} />
|
||||
<label for="apiUrl" class="text-base font-bold text-stone-100">API URL</label>
|
||||
<label for="apiUrl">API URL</label>
|
||||
<input class="w-full" name="apiUrl" id="apiUrl" required bind:value={source.apiUrl} />
|
||||
<label for="customPort" class="text-base font-bold text-stone-100"
|
||||
<label for="customPort"
|
||||
>Custom SSH Port <Explainer
|
||||
explanation={'If you use a self-hosted version of Git, you can provide custom port for all the Git related actions.'}
|
||||
/></label
|
||||
@ -124,7 +137,7 @@
|
||||
required
|
||||
value={source.customPort}
|
||||
/>
|
||||
<label for="organization" class="pt-2 text-base font-bold text-stone-100"
|
||||
<label for="organization" class="pt-2"
|
||||
>Organization
|
||||
<Explainer
|
||||
explanation={"Fill it if you would like to use an organization's as your Git Source. Otherwise your user will be used."}
|
||||
@ -137,14 +150,26 @@
|
||||
placeholder="eg: coollabsio"
|
||||
bind:value={source.organization}
|
||||
/>
|
||||
<Setting
|
||||
customClass="pt-4"
|
||||
isBeta={true}
|
||||
id="autodeploy"
|
||||
isCenter={false}
|
||||
bind:setting={source.isSystemWide}
|
||||
on:click={() => changeSettings('isSystemWide', false)}
|
||||
title="System Wide Git Source"
|
||||
description="System Wide Git Sources are available to all the users in your Coolify instance. <br><br> <span class='font-bold text-warning'>Use with caution, as it can be a security risk.</span>"
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
{:else if source.githubApp?.installationId}
|
||||
<form on:submit|preventDefault={handleSubmit} class="py-4">
|
||||
<div class="flex lg:flex-row lg:justify-between flex-col space-y-3 w-full lg:items-center">
|
||||
<h1 class="title">{$t('general')}</h1>
|
||||
{#if $appSession.isAdmin}
|
||||
<div class="flex flex-col lg:flex-row lg:space-x-4 lg:w-fit space-y-2 lg:space-y-0 w-full">
|
||||
{#if $appSession.isAdmin && $appSession.teamId === '0'}
|
||||
<div
|
||||
class="flex flex-col lg:flex-row lg:space-x-4 lg:w-fit space-y-2 lg:space-y-0 w-full"
|
||||
>
|
||||
<button class="btn btn-sm bg-sources" type="submit" disabled={loading}
|
||||
>{loading ? 'Saving...' : 'Save'}</button
|
||||
>
|
||||
@ -159,9 +184,16 @@
|
||||
{/if}
|
||||
</div>
|
||||
<div class="grid gap-2 grid-cols-2 auto-rows-max mt-4">
|
||||
<label for="name" class="text-base font-bold text-stone-100">{$t('forms.name')}</label>
|
||||
<input class="w-full" name="name" id="name" required bind:value={source.name} />
|
||||
<label for="htmlUrl" class="text-base font-bold text-stone-100">HTML URL</label>
|
||||
<label for="name">{$t('forms.name')}</label>
|
||||
<input
|
||||
class="w-full"
|
||||
name="name"
|
||||
id="name"
|
||||
required
|
||||
bind:value={source.name}
|
||||
disabled={$appSession.teamId !== '0'}
|
||||
/>
|
||||
<label for="htmlUrl">HTML URL</label>
|
||||
<input
|
||||
class="w-full"
|
||||
name="htmlUrl"
|
||||
@ -171,7 +203,7 @@
|
||||
required
|
||||
bind:value={source.htmlUrl}
|
||||
/>
|
||||
<label for="apiUrl" class="text-base font-bold text-stone-100">API URL</label>
|
||||
<label for="apiUrl">API URL</label>
|
||||
<input
|
||||
class="w-full"
|
||||
name="apiUrl"
|
||||
@ -181,7 +213,7 @@
|
||||
readonly={source.githubAppId}
|
||||
bind:value={source.apiUrl}
|
||||
/>
|
||||
<label for="customPort" class="text-base font-bold text-stone-100"
|
||||
<label for="customPort"
|
||||
>Custom SSH Port <Explainer
|
||||
explanation="If you use a self-hosted version of Git, you can provide custom port for all the Git related actions."
|
||||
/></label
|
||||
@ -195,9 +227,7 @@
|
||||
required
|
||||
value={source.customPort}
|
||||
/>
|
||||
<label for="organization" class="pt-2 text-base font-bold text-stone-100"
|
||||
>Organization</label
|
||||
>
|
||||
<label for="organization" class="pt-2">Organization</label>
|
||||
<input
|
||||
class="w-full"
|
||||
readonly
|
||||
@ -207,6 +237,17 @@
|
||||
placeholder="eg: coollabsio"
|
||||
bind:value={source.organization}
|
||||
/>
|
||||
<Setting
|
||||
customClass="pt-4"
|
||||
isBeta={true}
|
||||
id="autodeploy"
|
||||
isCenter={false}
|
||||
disabled={$appSession.teamId !== '0'}
|
||||
bind:setting={source.isSystemWide}
|
||||
on:click={() => changeSettings('isSystemWide', true)}
|
||||
title="System Wide Git Source"
|
||||
description="System Wide Git Sources are available to all the users in your Coolify instance. <br><br> <span class='font-bold text-warning'>Use with caution, as it can be a security risk.</span>"
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
{:else}
|
||||
|
@ -53,7 +53,7 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if id !== 'new'}
|
||||
{#if id !== 'new' && $appSession.teamId === '0'}
|
||||
<nav class="nav-side">
|
||||
<button
|
||||
id="delete"
|
||||
|
@ -43,7 +43,7 @@ #svelte .custom-select-wrapper .selectContainer input {
|
||||
}
|
||||
|
||||
#svelte .custom-select-wrapper .selectContainer {
|
||||
@apply h-12 w-96 rounded bg-coolgray-200 p-2 px-0 text-xs tracking-tight outline-none transition duration-150 hover:bg-coolgray-500 focus:bg-coolgray-500 md:text-sm w-full ;
|
||||
@apply h-12 w-96 rounded bg-coolgray-200 p-2 px-0 text-xs tracking-tight outline-none transition duration-150 hover:bg-coolgray-500 focus:bg-coolgray-500 md:text-sm ;
|
||||
}
|
||||
|
||||
#svelte .listContainer {
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "coolify",
|
||||
"description": "An open-source & self-hostable Heroku / Netlify alternative.",
|
||||
"version": "3.10.9",
|
||||
"version": "3.10.10",
|
||||
"license": "Apache-2.0",
|
||||
"repository": "github:coollabsio/coolify",
|
||||
"scripts": {
|
||||
|
Loading…
Reference in New Issue
Block a user