Compare commits

..

52 Commits

Author SHA1 Message Date
Mauricio Siu bb59a0cd3f Merge pull request #230 from Dokploy/canary
v0.3.3
2024-07-18 00:11:10 -06:00
Mauricio Siu 1e4217315b chore(version): bump version 2024-07-17 23:05:28 -06:00
Mauricio Siu b373aca0ff Merge pull request #228 from anh-ld/feat/add-input-copy-button
feat: add copy function to visibility input
2024-07-17 22:28:21 -06:00
Anh (Daniel) Le 87e90cb30b fix: use copy-to-clipboard for visibility input 2024-07-18 11:15:35 +07:00
Mauricio Siu 135fabb852 Merge pull request #229 from kdurek/feat/update-dockerfile-and-cicd
ci: split workflows to separate files
2024-07-17 13:01:12 -06:00
Krzysztof Durek b0b5b94bb7 Merge branch 'canary' of https://github.com/kdurek/dokploy into feat/update-dockerfile-and-cicd 2024-07-17 20:28:04 +02:00
Mauricio Siu 8f1c1e5202 Merge pull request #226 from kdurek/fix/husky-on-prod
fix: disable husky only on production
2024-07-17 11:52:04 -06:00
Anh (Daniel) Le e4c243d7a6 fix: format toggle visibility input 2024-07-18 00:15:43 +07:00
Anh (Daniel) Le c3bca21d14 fix: remove redundant selection api 2024-07-17 18:55:40 +07:00
Krzysztof Durek 1befdb76e7 ci: pnpm gets version from package.json packageManager field 2024-07-17 12:38:49 +02:00
Krzysztof Durek 35652c5c53 build: split build into multiple stages for caching 2024-07-17 12:33:21 +02:00
Krzysztof Durek 9524609092 ci: split workflows to separate files 2024-07-17 12:32:33 +02:00
Anh (Daniel) Le 38c16fe839 feat: add copy function to visibility input 2024-07-17 14:59:16 +07:00
Mauricio Siu c0587b9409 Update FUNDING.yml 2024-07-16 19:45:41 -06:00
Krzysztof Durek e249e878f6 fix: disable husky only on production 2024-07-16 14:11:44 +02:00
Krzysztof Durek 2d64815c12 fix: disable husky only on production 2024-07-16 12:05:27 +02:00
Mauricio Siu d0d4182fc1 Merge pull request #224 from Dokploy/fix/remove-husky
chore(husky): remove script
2024-07-15 21:21:11 -06:00
Mauricio Siu 736f7c2d77 chore(husky): remove script 2024-07-15 21:10:46 -06:00
Mauricio Siu 6e38508477 Merge pull request #219 from kdurek/feat/refactor-format-and-lint
feat: update configs
2024-07-15 20:45:00 -06:00
Mauricio Siu afe8160d46 Update biome.json 2024-07-15 20:26:39 -06:00
Mauricio Siu ceb4ae62e2 Update biome.json 2024-07-15 20:25:15 -06:00
Krzysztof Durek 67d0dd5bf7 fix: update test to not throw typescript errors 2024-07-15 14:36:48 +02:00
Krzysztof Durek 6e28545c3f feat: update continuous integration 2024-07-15 13:59:21 +02:00
Krzysztof Durek 382208ae13 Merge branch 'canary' of https://github.com/Dokploy/dokploy into feat/refactor-format-and-lint 2024-07-15 01:13:09 +02:00
Krzysztof Durek 906e8de13b chore: format whole repository with new configs 2024-07-15 01:08:18 +02:00
Krzysztof Durek 7a5c71cda3 feat: update configs 2024-07-15 01:02:18 +02:00
Mauricio Siu 7bc6d0777d Merge pull request #217 from kdurek/feat/umami-template
feat: add umami template
2024-07-14 13:05:27 -06:00
Krzysztof Durek f684ba7b1f fix: change umami version 2024-07-14 20:42:26 +02:00
Mauricio Siu 86ed884162 Merge pull request #215 from eremannisto/214-clarify-error-message-for-naming-validation
Clarify error message for naming validation in `AppName`
2024-07-14 12:32:23 -06:00
Krzysztof Durek 4ff178ea34 feat: add umami template 2024-07-14 20:28:37 +02:00
Ere Männistö 2eb5c331a1 Clarify error message for naming validation 2024-07-14 15:23:54 +03:00
Mauricio Siu 84c10eec66 chore: add open collective organizations 2024-07-13 00:48:49 -06:00
Mauricio Siu 61673a40e3 Merge pull request #212 from Dokploy/210-every-time-i-create-a-server-on-hetzner-it-does-not-work-after-restart
fix(#210): Make dokploy services automatically start when a crash or restart server
2024-07-13 00:40:49 -06:00
Mauricio Siu 363ba1d20e fix(#210): remove restartpolicy in order to automatically restart the services in any case 2024-07-12 23:35:51 -06:00
Mauricio Siu 44e6a117dd Merge pull request #208 from Dokploy/canary
v0.3.2
2024-07-11 23:21:32 -06:00
Mauricio Siu 86bb119052 chore(version): bump version 2024-07-11 21:24:36 -06:00
Mauricio Siu 54c70ff177 Merge pull request #206 from Dokploy/feat/add-constraints-dokploy-services
refactor(setup): add constraints to dokploy services
2024-07-10 22:47:22 -06:00
Mauricio Siu eabe14e4c3 refactor(setup): add constraints to dokploy services 2024-07-10 22:40:13 -06:00
Mauricio Siu 9d0edd810e Merge pull request #204 from henriklovhaug/canary
[Docs/style]: Fix minor spelling error
2024-07-08 10:30:09 -06:00
Henrik Tøn Løvhaug 35ff65a871 Fix spelling 2024-07-08 10:16:26 +02:00
Mauricio Siu 675fbb7692 Merge pull request #200 from ciocan/feat/listmonk
feat: listmonk template
2024-07-06 17:38:29 -06:00
Mauricio Siu 295bd06918 Update templates.ts 2024-07-06 17:17:14 -06:00
Mauricio Siu 89635fa27b Merge branch 'canary' into feat/listmonk 2024-07-06 17:16:01 -06:00
Mauricio Siu 60b19616c1 Update docker-compose.yml 2024-07-06 17:15:17 -06:00
Mauricio Siu 3884dc9259 Merge pull request #198 from ciocan/feat/doublezero
feat: doublezero template
2024-07-06 17:13:27 -06:00
Mauricio Siu e8648732be Update index.ts 2024-07-06 17:07:19 -06:00
Mauricio Siu 0f0f32a40d Update index.ts 2024-07-06 17:06:40 -06:00
Radu Ciocan 1b91376f5e feat: listmonk template 2024-07-06 23:01:01 +01:00
Radu Ciocan aa347abfcd fix: code review changes 2024-07-06 20:30:23 +01:00
Radu Ciocan e49b190c32 Update templates/doublezero/docker-compose.yml
Co-authored-by: Mauricio Siu <47042324+Siumauricio@users.noreply.github.com>
2024-07-06 20:13:12 +01:00
Radu Ciocan 66017c8623 fix: update template description 2024-07-06 14:34:30 +01:00
Radu Ciocan bab93f8145 feat: doublezero template 2024-07-06 14:29:32 +01:00
374 changed files with 4466 additions and 3879 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
# These are supported funding model platforms
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
github: [siumauricio]
patreon: #
open_collective: dokploy
ko_fi: # Replace with a single Ko-fi username
+22 -37
View File
@@ -1,59 +1,44 @@
name: Pull request
on:
pull_request:
branches:
- main
- canary
push:
branches:
- main
- canary
env:
HUSKY: 0
jobs:
build-app:
if: github.event_name == 'pull_request'
runs-on: ubuntu-20.04
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18.18.0]
steps:
- uses: actions/checkout@v3
- uses: pnpm/action-setup@v3
with:
version: 8
- name: Check out the code
uses: actions/checkout@v4
- name: Setup pnpm
uses: pnpm/action-setup@v4
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'pnpm'
- name: Install dependencies
run: pnpm install
- name: Run format and lint
run: pnpm biome ci
- name: Run type check
run: pnpm typecheck
- name: Run Build
run: pnpm build
- name: Run Tests
run: pnpm run test
build-and-push-docker-on-push:
if: github.event_name == 'push'
runs-on: ubuntu-latest
steps:
- name: Check out the code
uses: actions/checkout@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Prepare .env file
run: |
cp .env.production.example .env.production
- name: Build and push Docker image using custom script
run: |
chmod +x ./docker/push.sh
./docker/push.sh ${{ github.ref_name == 'canary' && 'canary' || '' }}
+35
View File
@@ -0,0 +1,35 @@
name: Push
on:
push:
branches:
- main
- canary
env:
HUSKY: 0
jobs:
build-and-push-docker-on-push:
runs-on: ubuntu-latest
steps:
- name: Check out the code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Prepare .env file
run: |
cp .env.production.example .env.production
- name: Build and push Docker image using custom script
run: |
chmod +x ./docker/push.sh
./docker/push.sh ${{ github.ref_name == 'canary' && 'canary' || '' }}
+6
View File
@@ -0,0 +1,6 @@
// Skip Husky install in production and CI
if (process.env.NODE_ENV === "production" || process.env.CI === "true") {
process.exit(0);
}
const husky = (await import("husky")).default;
console.log(husky());
+1
View File
@@ -0,0 +1 @@
pnpm lint-staged
+43 -27
View File
@@ -1,48 +1,65 @@
# Etapa 1: Prepare image for building
FROM node:18-slim AS base
# Install dependencies
# Disable husky
ENV HUSKY=0
# Set pnpm home
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"
RUN corepack enable && apt-get update && apt-get install -y python3 make g++ git && rm -rf /var/lib/apt/lists/*
# Enable corepack
RUN corepack enable
# Set workdir
WORKDIR /app
FROM base AS base-deps
# Install dependencies only for production
RUN apt-get update && apt-get install -y python3 make g++ git && rm -rf /var/lib/apt/lists/*
# Copy install script for husky
COPY .husky/install.mjs ./.husky/install.mjs
# Copy package.json and pnpm-lock.yaml
COPY package.json pnpm-lock.yaml ./
FROM base-deps AS prod-deps
# Set production
ENV NODE_ENV=production
# Install dependencies only for production
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --prod --frozen-lockfile
FROM base-deps AS build
# Install dependencies only for building
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile
# Copy the rest of the source code
COPY . .
# Build the application
RUN pnpm run build
# Build the application
RUN pnpm build
# Stage 2: Prepare image for production
FROM node:18-slim AS production
FROM base AS production
# Set production
ENV NODE_ENV=production
# Install dependencies only for production
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"
RUN corepack enable && apt-get update && apt-get install -y curl && apt-get install -y apache2-utils && rm -rf /var/lib/apt/lists/*
RUN apt-get update && apt-get install -y curl apache2-utils && rm -rf /var/lib/apt/lists/*
WORKDIR /app
# Copy the rest of the source code
COPY --from=base /app/.next ./.next
COPY --from=base /app/dist ./dist
COPY --from=base /app/next.config.mjs ./next.config.mjs
COPY --from=base /app/public ./public
COPY --from=base /app/package.json ./package.json
COPY --from=base /app/drizzle ./drizzle
COPY --from=base /app/.env.production ./.env
COPY --from=base /app/components.json ./components.json
# Install dependencies only for production
COPY package.json pnpm-lock.yaml ./
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --prod --frozen-lockfile
# Copy the rest of the source code
COPY --from=build /app/.next ./.next
COPY --from=build /app/dist ./dist
COPY --from=build /app/next.config.mjs ./next.config.mjs
COPY --from=build /app/public ./public
COPY --from=build /app/package.json ./package.json
COPY --from=build /app/drizzle ./drizzle
COPY --from=build /app/.env.production ./.env
COPY --from=build /app/components.json ./components.json
COPY --from=prod-deps /app/node_modules ./node_modules
# Install docker
RUN curl -fsSL https://get.docker.com -o get-docker.sh && sh get-docker.sh && rm get-docker.sh
@@ -54,11 +71,10 @@ RUN curl -sSL https://nixpacks.com/install.sh -o install.sh \
&& ./install.sh \
&& pnpm install -g tsx
# Install buildpacks
RUN curl -sSL "https://github.com/buildpacks/pack/releases/download/v0.32.1/pack-v0.32.1-linux.tgz" | tar -C /usr/local/bin/ --no-same-owner -xzv pack
# Expose port
EXPOSE 3000
CMD ["pnpm", "start"]
CMD ["pnpm", "start"]
+21 -32
View File
@@ -1,4 +1,3 @@
<div align="center">
<h1 align="center">Dokploy</h1>
<div>
@@ -11,74 +10,67 @@
<br />
Dokploy is a free self-hostable Platform as a Service (PaaS) that simplifies the deployment and management of applications and databases.
### Features
Dokploy include multiples features to make your life easier.
* **Applications**: Deploy any type of application (Node.js, PHP, Python, Go, Ruby, etc.).
* **Databases**: Create and manage databases with support for MySQL, PostgreSQL, MongoDB, MariaDB, Redis.
* **Backups**: Automate backups for databases to a external storage destination.
* **Docker Compose**: Native support for Docker Compose to manage complex applications.
* **Multi Node**: Scale applications to multiples nodes using docker swarm to manage the cluster.
* **Templates**: Deploy in a single click open source templates (Plausible, Pocketbase, Calcom, etc.).
* **Traefik Integration**: Automatically integrates with Traefik for routing and load balancing.
* **Real-time Monitoring**: Monitor CPU, memory, storage, and network usage, for every resource.
* **Docker Management**: Easily deploy and manage Docker containers.
* **CLI/API**: Manage your applications and databases using the command line or trought the API.
* **Self-Hosted**: Self-host Dokploy on your VPS.
- **Applications**: Deploy any type of application (Node.js, PHP, Python, Go, Ruby, etc.).
- **Databases**: Create and manage databases with support for MySQL, PostgreSQL, MongoDB, MariaDB, Redis.
- **Backups**: Automate backups for databases to a external storage destination.
- **Docker Compose**: Native support for Docker Compose to manage complex applications.
- **Multi Node**: Scale applications to multiples nodes using docker swarm to manage the cluster.
- **Templates**: Deploy in a single click open source templates (Plausible, Pocketbase, Calcom, etc.).
- **Traefik Integration**: Automatically integrates with Traefik for routing and load balancing.
- **Real-time Monitoring**: Monitor CPU, memory, storage, and network usage, for every resource.
- **Docker Management**: Easily deploy and manage Docker containers.
- **CLI/API**: Manage your applications and databases using the command line or trought the API.
- **Self-Hosted**: Self-host Dokploy on your VPS.
## 🚀 Getting Started
To get started run the following command in a VPS:
```bash
curl -sSL https://dokploy.com/install.sh | sh
```
## 📄 Documentation
For detailed documentation, visit [docs.dokploy.com](https://docs.dokploy.com).
## Video Tutorial
<a href="https://youtu.be/mznYKPvhcfw">
<img src="https://dokploy.com/banner.webp" alt="Watch the video" width="400" style="border-radius:20px;"/>
</a>
## Donations
If you like dokploy, and want to support the project to cover the costs of hosting, testing and development new features, you can donate to the project using the following link:
Thanks to all the supporters!
https://opencollective.com/dokploy
[Dokploy Open Collective](https://opencollective.com/dokploy)
Organizations:
<a href="https://opencollective.com/dokploy"><img src="https://opencollective.com/dokploy/organizations.svg?width=890"></a>
Individuals:
<a href="https://opencollective.com/dokploy"><img src="https://opencollective.com/dokploy/individuals.svg?width=890"></a>
## Contributors
<a href="https://github.com/dokploy/dokploy/graphs/contributors">
<img src="https://contrib.rocks/image?repo=dokploy/dokploy" />
</a>
## Support OS
- Ubuntu 24.04 LTS
- Ubuntu 24.04 LTS
- Ubuntu 23.10
- Ubuntu 22.04 LTS
- Ubuntu 20.04 LTS
- Ubuntu 22.04 LTS
- Ubuntu 20.04 LTS
- Ubuntu 18.04 LTS
- Debian 12
- Debian 11
@@ -86,9 +78,6 @@ https://opencollective.com/dokploy
- Centos 9
- Centos 8
## Explanation
[English](README.md) | [中文](README-zh.md) | [Deutsch](README-de.md) | [Русский Язык](README-ru.md)
+2 -2
View File
@@ -1,7 +1,7 @@
import { expect, test } from "vitest";
import { load } from "js-yaml";
import { addPrefixToAllProperties } from "@/server/utils/docker/compose";
import type { ComposeSpecification } from "@/server/utils/docker/types";
import { load } from "js-yaml";
import { expect, test } from "vitest";
const composeFile1 = `
version: "3.8"
@@ -79,10 +79,11 @@ test("Add prefix to networks in services with aliases", () => {
`frontend-${prefix}`,
);
const networkConfig =
actualComposeData?.services?.api?.networks[`frontend-${prefix}`];
expect(networkConfig).toBeDefined();
expect(networkConfig?.aliases).toContain("api");
const networkConfig = actualComposeData?.services?.api?.networks as {
[key: string]: { aliases?: string[] };
};
expect(networkConfig[`frontend-${prefix}`]).toBeDefined();
expect(networkConfig[`frontend-${prefix}`]?.aliases).toContain("api");
expect(actualComposeData.services?.api?.networks).not.toHaveProperty(
"frontend-ash",
@@ -169,7 +170,9 @@ test("Add prefix to networks in services (combined case)", () => {
);
// Caso 2: Objeto con aliases
const apiNetworks = actualComposeData.services?.api?.networks;
const apiNetworks = actualComposeData.services?.api?.networks as {
[key: string]: unknown;
};
expect(apiNetworks).toHaveProperty(`frontend-${prefix}`);
expect(apiNetworks[`frontend-${prefix}`]).toBeDefined();
expect(apiNetworks).not.toHaveProperty("frontend");
+4 -2
View File
@@ -76,9 +76,11 @@ test("Add prefix to networks in services and root (combined case)", () => {
);
// Caso 2: Objeto con aliases
const apiNetworks = actualComposeData.services?.api?.networks;
const apiNetworks = actualComposeData.services?.api?.networks as {
[key: string]: { aliases?: string[] };
};
expect(apiNetworks).toHaveProperty(`frontend-${prefix}`);
expect(apiNetworks[`frontend-${prefix}`]?.aliases).toContain("api");
expect(apiNetworks?.[`frontend-${prefix}`]?.aliases).toContain("api");
expect(apiNetworks).not.toHaveProperty("frontend");
// Caso 3: Objeto con redes simples
+3 -3
View File
@@ -1,8 +1,8 @@
import { expect, test } from "vitest";
import { load, dump } from "js-yaml";
import { generateRandomHash } from "@/server/utils/docker/compose";
import type { ComposeSpecification } from "@/server/utils/docker/types";
import { addPrefixToSecretsRoot } from "@/server/utils/docker/compose/secrets";
import type { ComposeSpecification } from "@/server/utils/docker/types";
import { dump, load } from "js-yaml";
import { expect, test } from "vitest";
test("Generate random hash with 8 characters", () => {
const hash = generateRandomHash();
@@ -42,7 +42,7 @@ test("Add prefix to service names with container_name in compose file", () => {
const actualComposeData = { ...composeData, services: updatedComposeData };
// Verificar que el nombre del contenedor ha cambiado correctamente
expect(actualComposeData.services[`web-${prefix}`].container_name).toBe(
expect(actualComposeData.services?.[`web-${prefix}`]?.container_name).toBe(
`web_container-${prefix}`,
);
// Verificar que la nueva clave del servicio tiene el prefijo y la vieja clave no existe
@@ -50,10 +50,10 @@ test("Add prefix to service names with container_name in compose file", () => {
expect(actualComposeData.services).not.toHaveProperty("web");
// Verificar que la configuración de la imagen sigue igual
expect(actualComposeData.services[`web-${prefix}`].image).toBe(
expect(actualComposeData.services?.[`web-${prefix}`]?.image).toBe(
"nginx:latest",
);
expect(actualComposeData.services[`api-${prefix}`].image).toBe(
expect(actualComposeData.services?.[`api-${prefix}`]?.image).toBe(
"myapi:latest",
);
});
@@ -51,30 +51,30 @@ test("Add prefix to service names with depends_on (array) in compose file", () =
expect(actualComposeData.services).not.toHaveProperty("web");
// Verificar que la configuración de la imagen sigue igual
expect(actualComposeData.services[`web-${prefix}`].image).toBe(
expect(actualComposeData.services?.[`web-${prefix}`]?.image).toBe(
"nginx:latest",
);
expect(actualComposeData.services[`api-${prefix}`].image).toBe(
expect(actualComposeData.services?.[`api-${prefix}`]?.image).toBe(
"myapi:latest",
);
// Verificar que los nombres en depends_on tienen el prefijo
expect(actualComposeData.services[`web-${prefix}`].depends_on).toContain(
expect(actualComposeData.services?.[`web-${prefix}`]?.depends_on).toContain(
`db-${prefix}`,
);
expect(actualComposeData.services[`web-${prefix}`].depends_on).toContain(
expect(actualComposeData.services?.[`web-${prefix}`]?.depends_on).toContain(
`api-${prefix}`,
);
// Verificar que los servicios `db` y `api` también tienen el prefijo
expect(actualComposeData.services).toHaveProperty(`db-${prefix}`);
expect(actualComposeData.services).not.toHaveProperty("db");
expect(actualComposeData.services[`db-${prefix}`].image).toBe(
expect(actualComposeData.services?.[`db-${prefix}`]?.image).toBe(
"postgres:latest",
);
expect(actualComposeData.services).toHaveProperty(`api-${prefix}`);
expect(actualComposeData.services).not.toHaveProperty("api");
expect(actualComposeData.services[`api-${prefix}`].image).toBe(
expect(actualComposeData.services?.[`api-${prefix}`]?.image).toBe(
"myapi:latest",
);
});
@@ -121,16 +121,16 @@ test("Add prefix to service names with depends_on (object) in compose file", ()
expect(actualComposeData.services).not.toHaveProperty("web");
// Verificar que la configuración de la imagen sigue igual
expect(actualComposeData.services[`web-${prefix}`].image).toBe(
expect(actualComposeData.services?.[`web-${prefix}`]?.image).toBe(
"nginx:latest",
);
expect(actualComposeData.services[`api-${prefix}`].image).toBe(
expect(actualComposeData.services?.[`api-${prefix}`]?.image).toBe(
"myapi:latest",
);
// Verificar que los nombres en depends_on tienen el prefijo
const webDependsOn = actualComposeData.services[`web-${prefix}`]
.depends_on as Record<string, any>;
const webDependsOn = actualComposeData.services?.[`web-${prefix}`]
?.depends_on as Record<string, any>;
expect(webDependsOn).toHaveProperty(`db-${prefix}`);
expect(webDependsOn).toHaveProperty(`api-${prefix}`);
expect(webDependsOn[`db-${prefix}`].condition).toBe("service_healthy");
@@ -139,12 +139,12 @@ test("Add prefix to service names with depends_on (object) in compose file", ()
// Verificar que los servicios `db` y `api` también tienen el prefijo
expect(actualComposeData.services).toHaveProperty(`db-${prefix}`);
expect(actualComposeData.services).not.toHaveProperty("db");
expect(actualComposeData.services[`db-${prefix}`].image).toBe(
expect(actualComposeData.services?.[`db-${prefix}`]?.image).toBe(
"postgres:latest",
);
expect(actualComposeData.services).toHaveProperty(`api-${prefix}`);
expect(actualComposeData.services).not.toHaveProperty("api");
expect(actualComposeData.services[`api-${prefix}`].image).toBe(
expect(actualComposeData.services?.[`api-${prefix}`]?.image).toBe(
"myapi:latest",
);
});
@@ -49,22 +49,22 @@ test("Add prefix to service names with extends (string) in compose file", () =>
expect(actualComposeData.services).not.toHaveProperty("web");
// Verificar que la configuración de la imagen sigue igual
expect(actualComposeData.services[`web-${prefix}`].image).toBe(
expect(actualComposeData.services?.[`web-${prefix}`]?.image).toBe(
"nginx:latest",
);
expect(actualComposeData.services[`api-${prefix}`].image).toBe(
expect(actualComposeData.services?.[`api-${prefix}`]?.image).toBe(
"myapi:latest",
);
// Verificar que el nombre en extends tiene el prefijo
expect(actualComposeData.services[`web-${prefix}`].extends).toBe(
expect(actualComposeData.services?.[`web-${prefix}`]?.extends).toBe(
`base_service-${prefix}`,
);
// Verificar que el servicio `base_service` también tiene el prefijo
expect(actualComposeData.services).toHaveProperty(`base_service-${prefix}`);
expect(actualComposeData.services).not.toHaveProperty("base_service");
expect(actualComposeData.services[`base_service-${prefix}`].image).toBe(
expect(actualComposeData.services?.[`base_service-${prefix}`]?.image).toBe(
"base:latest",
);
});
@@ -109,23 +109,23 @@ test("Add prefix to service names with extends (object) in compose file", () =>
expect(actualComposeData.services).not.toHaveProperty("web");
// Verificar que la configuración de la imagen sigue igual
expect(actualComposeData.services[`web-${prefix}`].image).toBe(
expect(actualComposeData.services?.[`web-${prefix}`]?.image).toBe(
"nginx:latest",
);
expect(actualComposeData.services[`api-${prefix}`].image).toBe(
expect(actualComposeData.services?.[`api-${prefix}`]?.image).toBe(
"myapi:latest",
);
// Verificar que el nombre en extends.service tiene el prefijo
const webExtends = actualComposeData.services[`web-${prefix}`].extends;
const webExtends = actualComposeData.services?.[`web-${prefix}`]?.extends;
if (typeof webExtends !== "string") {
expect(webExtends.service).toBe(`base_service-${prefix}`);
expect(webExtends?.service).toBe(`base_service-${prefix}`);
}
// Verificar que el servicio `base_service` también tiene el prefijo
expect(actualComposeData.services).toHaveProperty(`base_service-${prefix}`);
expect(actualComposeData.services).not.toHaveProperty("base_service");
expect(actualComposeData.services[`base_service-${prefix}`].image).toBe(
expect(actualComposeData.services?.[`base_service-${prefix}`]?.image).toBe(
"base:latest",
);
});
@@ -50,27 +50,27 @@ test("Add prefix to service names with links in compose file", () => {
expect(actualComposeData.services).not.toHaveProperty("web");
// Verificar que la configuración de la imagen sigue igual
expect(actualComposeData.services[`web-${prefix}`].image).toBe(
expect(actualComposeData.services?.[`web-${prefix}`]?.image).toBe(
"nginx:latest",
);
expect(actualComposeData.services[`api-${prefix}`].image).toBe(
expect(actualComposeData.services?.[`api-${prefix}`]?.image).toBe(
"myapi:latest",
);
// Verificar que los nombres en links tienen el prefijo
expect(actualComposeData.services[`web-${prefix}`].links).toContain(
expect(actualComposeData.services?.[`web-${prefix}`]?.links).toContain(
`db-${prefix}`,
);
// Verificar que los servicios `db` y `api` también tienen el prefijo
expect(actualComposeData.services).toHaveProperty(`db-${prefix}`);
expect(actualComposeData.services).not.toHaveProperty("db");
expect(actualComposeData.services[`db-${prefix}`].image).toBe(
expect(actualComposeData.services?.[`db-${prefix}`]?.image).toBe(
"postgres:latest",
);
expect(actualComposeData.services).toHaveProperty(`api-${prefix}`);
expect(actualComposeData.services).not.toHaveProperty("api");
expect(actualComposeData.services[`api-${prefix}`].image).toBe(
expect(actualComposeData.services?.[`api-${prefix}`]?.image).toBe(
"myapi:latest",
);
});
@@ -54,23 +54,25 @@ test("Add prefix to service names with volumes_from in compose file", () => {
expect(actualComposeData.services).not.toHaveProperty("web");
// Verificar que la configuración de la imagen sigue igual
expect(actualComposeData.services[`web-${prefix}`].image).toBe(
expect(actualComposeData.services?.[`web-${prefix}`]?.image).toBe(
"nginx:latest",
);
expect(actualComposeData.services[`api-${prefix}`].image).toBe(
expect(actualComposeData.services?.[`api-${prefix}`]?.image).toBe(
"myapi:latest",
);
// Verificar que los nombres en volumes_from tienen el prefijo
expect(actualComposeData.services[`web-${prefix}`].volumes_from).toContain(
expect(actualComposeData.services?.[`web-${prefix}`]?.volumes_from).toContain(
`shared-${prefix}`,
);
expect(actualComposeData.services[`api-${prefix}`].volumes_from).toContain(
expect(actualComposeData.services?.[`api-${prefix}`]?.volumes_from).toContain(
`shared-${prefix}`,
);
// Verificar que el servicio shared también tiene el prefijo
expect(actualComposeData.services).toHaveProperty(`shared-${prefix}`);
expect(actualComposeData.services).not.toHaveProperty("shared");
expect(actualComposeData.services[`shared-${prefix}`].image).toBe("busybox");
expect(actualComposeData.services?.[`shared-${prefix}`]?.image).toBe(
"busybox",
);
});
+1 -1
View File
@@ -1,7 +1,7 @@
import { generateRandomHash } from "@/server/utils/docker/compose";
import {
addPrefixToVolumesRoot,
addPrefixToAllVolumes,
addPrefixToVolumesRoot,
} from "@/server/utils/docker/compose/volume";
import type { ComposeSpecification } from "@/server/utils/docker/types";
import { load } from "js-yaml";
+1 -1
View File
@@ -1,5 +1,5 @@
import { defineConfig } from "vitest/config";
import tsconfigPaths from "vite-tsconfig-paths";
import { defineConfig } from "vitest/config";
export default defineConfig({
plugins: [
+33 -16
View File
@@ -1,17 +1,34 @@
{
"$schema": "./node_modules/@biomejs/biome/configuration_schema.json",
"linter":{
"rules": {
"correctness":{
"useExhaustiveDependencies": "off"
},
"suspicious":{
"noArrayIndexKey": "off"
},
"a11y":{
"noSvgWithoutTitle":"off"
}
}
}
}
"$schema": "./node_modules/@biomejs/biome/configuration_schema.json",
"files": {
"ignore": ["node_modules/**", ".next/**", "drizzle/**", ".docker"]
},
"organizeImports": {
"enabled": true
},
"linter": {
"rules": {
"complexity": {
"noUselessCatch": "off",
"noBannedTypes": "off"
},
"correctness": {
"useExhaustiveDependencies": "off",
"noUnsafeOptionalChaining": "off"
},
"style": {
"noNonNullAssertion": "off"
},
"suspicious": {
"noArrayIndexKey": "off",
"noExplicitAny": "off",
"noRedeclare": "off"
},
"a11y": {
"noSvgWithoutTitle": "off",
"useKeyWithClickEvents": "off",
"useAriaPropsForRole": "off"
}
}
}
}
+16 -16
View File
@@ -1,17 +1,17 @@
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "default",
"rsc": false,
"tsx": true,
"tailwind": {
"config": "tailwind.config.ts",
"css": "styles/globals.css",
"baseColor": "zinc",
"cssVariables": true,
"prefix": ""
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils"
}
}
"$schema": "https://ui.shadcn.com/schema.json",
"style": "default",
"rsc": false,
"tsx": true,
"tailwind": {
"config": "tailwind.config.ts",
"css": "styles/globals.css",
"baseColor": "zinc",
"cssVariables": true,
"prefix": ""
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils"
}
}
+7 -7
View File
@@ -10,19 +10,19 @@ import {
} from "@/components/ui/form";
import { CardTitle } from "@/components/ui/card";
import { api } from "@/utils/api";
import { zodResolver } from "@hookform/resolvers/zod";
import { AlertTriangle } from "lucide-react";
import { useEffect } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
import { z } from "zod";
import {
InputOTP,
InputOTPGroup,
InputOTPSlot,
} from "@/components/ui/input-otp";
import { api } from "@/utils/api";
import { zodResolver } from "@hookform/resolvers/zod";
import { AlertTriangle } from "lucide-react";
import { useRouter } from "next/router";
import { useEffect } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
import { z } from "zod";
const Login2FASchema = z.object({
pin: z.string().min(6, {
@@ -1,3 +1,5 @@
import { AlertBlock } from "@/components/shared/alert-block";
import { CodeEditor } from "@/components/shared/code-editor";
import { Button } from "@/components/ui/button";
import {
Dialog,
@@ -17,21 +19,19 @@ import {
FormLabel,
FormMessage,
} from "@/components/ui/form";
import { api } from "@/utils/api";
import { AlertBlock } from "@/components/shared/alert-block";
import { zodResolver } from "@hookform/resolvers/zod";
import { useEffect } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
import { z } from "zod";
import { HelpCircle, Settings } from "lucide-react";
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "@/components/ui/tooltip";
import { CodeEditor } from "@/components/shared/code-editor";
import { api } from "@/utils/api";
import { zodResolver } from "@hookform/resolvers/zod";
import { HelpCircle, Settings } from "lucide-react";
import { useEffect } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
import { z } from "zod";
const HealthCheckSwarmSchema = z
.object({
@@ -1,4 +1,5 @@
import React from "react";
import { AlertBlock } from "@/components/shared/alert-block";
import { Button } from "@/components/ui/button";
import {
Card,
CardContent,
@@ -6,8 +7,6 @@ import {
CardHeader,
CardTitle,
} from "@/components/ui/card";
import { api } from "@/utils/api";
import { z } from "zod";
import {
Form,
FormControl,
@@ -16,11 +15,6 @@ import {
FormLabel,
FormMessage,
} from "@/components/ui/form";
import { toast } from "sonner";
import { zodResolver } from "@hookform/resolvers/zod";
import { useForm } from "react-hook-form";
import { useEffect } from "react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import {
Select,
@@ -31,10 +25,16 @@ import {
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import Link from "next/link";
import { api } from "@/utils/api";
import { zodResolver } from "@hookform/resolvers/zod";
import { Server } from "lucide-react";
import Link from "next/link";
import React from "react";
import { useEffect } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
import { z } from "zod";
import { AddSwarmSettings } from "./modify-swarm-settings";
import { AlertBlock } from "@/components/shared/alert-block";
interface Props {
applicationId: string;
@@ -1,4 +1,4 @@
import React from "react";
import { Button } from "@/components/ui/button";
import {
Card,
CardContent,
@@ -6,8 +6,6 @@ import {
CardHeader,
CardTitle,
} from "@/components/ui/card";
import { api } from "@/utils/api";
import { z } from "zod";
import {
Form,
FormControl,
@@ -16,12 +14,14 @@ import {
FormLabel,
FormMessage,
} from "@/components/ui/form";
import { toast } from "sonner";
import { zodResolver } from "@hookform/resolvers/zod";
import { useForm } from "react-hook-form";
import { useEffect } from "react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { api } from "@/utils/api";
import { zodResolver } from "@hookform/resolvers/zod";
import React from "react";
import { useEffect } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
import { z } from "zod";
interface Props {
applicationId: string;
}
@@ -1,3 +1,4 @@
import { AlertBlock } from "@/components/shared/alert-block";
import { Button } from "@/components/ui/button";
import {
Dialog,
@@ -17,13 +18,6 @@ import {
FormMessage,
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { api } from "@/utils/api";
import { AlertBlock } from "@/components/shared/alert-block";
import { zodResolver } from "@hookform/resolvers/zod";
import { useEffect } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
import { PlusIcon } from "lucide-react";
import {
Select,
SelectContent,
@@ -31,6 +25,12 @@ import {
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import { api } from "@/utils/api";
import { zodResolver } from "@hookform/resolvers/zod";
import { PlusIcon } from "lucide-react";
import { useEffect } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
import { z } from "zod";
const AddPortSchema = z.object({
@@ -1,4 +1,4 @@
import React from "react";
import { AlertBlock } from "@/components/shared/alert-block";
import {
Card,
CardContent,
@@ -8,10 +8,10 @@ import {
} from "@/components/ui/card";
import { api } from "@/utils/api";
import { Rss } from "lucide-react";
import React from "react";
import { AddPort } from "./add-port";
import { DeletePort } from "./delete-port";
import { UpdatePort } from "./update-port";
import { AlertBlock } from "@/components/shared/alert-block";
interface Props {
applicationId: string;
}
@@ -1,3 +1,4 @@
import { AlertBlock } from "@/components/shared/alert-block";
import { Button } from "@/components/ui/button";
import {
Dialog,
@@ -17,14 +18,6 @@ import {
FormMessage,
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { api } from "@/utils/api";
import { AlertBlock } from "@/components/shared/alert-block";
import { zodResolver } from "@hookform/resolvers/zod";
import { PenBoxIcon, Pencil } from "lucide-react";
import { useEffect } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
import { z } from "zod";
import {
Select,
SelectContent,
@@ -32,6 +25,13 @@ import {
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import { api } from "@/utils/api";
import { zodResolver } from "@hookform/resolvers/zod";
import { PenBoxIcon, Pencil } from "lucide-react";
import { useEffect } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
import { z } from "zod";
const UpdatePortSchema = z.object({
publishedPort: z.number().int().min(1).max(65535),
@@ -1,3 +1,4 @@
import { AlertBlock } from "@/components/shared/alert-block";
import { Button } from "@/components/ui/button";
import {
Dialog,
@@ -11,22 +12,21 @@ import {
import {
Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormDescription,
FormMessage,
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { Switch } from "@/components/ui/switch";
import { api } from "@/utils/api";
import { AlertBlock } from "@/components/shared/alert-block";
import { zodResolver } from "@hookform/resolvers/zod";
import { PlusIcon } from "lucide-react";
import { useEffect } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
import { PlusIcon } from "lucide-react";
import { z } from "zod";
import { Switch } from "@/components/ui/switch";
const AddRedirectchema = z.object({
regex: z.string().min(1, "Regex required"),
@@ -1,4 +1,3 @@
import React from "react";
import {
Card,
CardContent,
@@ -8,6 +7,7 @@ import {
} from "@/components/ui/card";
import { api } from "@/utils/api";
import { Split } from "lucide-react";
import React from "react";
import { AddRedirect } from "./add-redirect";
import { DeleteRedirect } from "./delete-redirect";
import { UpdateRedirect } from "./update-redirect";
@@ -1,3 +1,4 @@
import { AlertBlock } from "@/components/shared/alert-block";
import { Button } from "@/components/ui/button";
import {
Dialog,
@@ -11,22 +12,21 @@ import {
import {
Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormDescription,
FormMessage,
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { Switch } from "@/components/ui/switch";
import { api } from "@/utils/api";
import { AlertBlock } from "@/components/shared/alert-block";
import { zodResolver } from "@hookform/resolvers/zod";
import { PenBoxIcon, Pencil } from "lucide-react";
import { useEffect } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
import { z } from "zod";
import { Switch } from "@/components/ui/switch";
const UpdateRedirectSchema = z.object({
regex: z.string().min(1, "Regex required"),
permanent: z.boolean().default(false),
@@ -1,3 +1,4 @@
import { AlertBlock } from "@/components/shared/alert-block";
import { Button } from "@/components/ui/button";
import {
Dialog,
@@ -18,12 +19,11 @@ import {
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { api } from "@/utils/api";
import { AlertBlock } from "@/components/shared/alert-block";
import { zodResolver } from "@hookform/resolvers/zod";
import { PlusIcon } from "lucide-react";
import { useEffect } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
import { PlusIcon } from "lucide-react";
import { z } from "zod";
const AddSecuritychema = z.object({
@@ -1,4 +1,3 @@
import React from "react";
import {
Card,
CardContent,
@@ -8,6 +7,7 @@ import {
} from "@/components/ui/card";
import { api } from "@/utils/api";
import { LockKeyhole } from "lucide-react";
import React from "react";
import { AddSecurity } from "./add-security";
import { DeleteSecurity } from "./delete-security";
import { UpdateSecurity } from "./update-security";
@@ -1,3 +1,4 @@
import { AlertBlock } from "@/components/shared/alert-block";
import { Button } from "@/components/ui/button";
import {
Dialog,
@@ -18,7 +19,6 @@ import {
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { api } from "@/utils/api";
import { AlertBlock } from "@/components/shared/alert-block";
import { zodResolver } from "@hookform/resolvers/zod";
import { PenBoxIcon, Pencil } from "lucide-react";
import { useEffect } from "react";
@@ -1,3 +1,4 @@
import { AlertBlock } from "@/components/shared/alert-block";
import { Button } from "@/components/ui/button";
import {
Card,
@@ -21,7 +22,6 @@ import React, { useEffect } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
import { z } from "zod";
import { AlertBlock } from "@/components/shared/alert-block";
const addResourcesApplication = z.object({
memoryReservation: z.number().nullable().optional(),
@@ -1,4 +1,4 @@
import React from "react";
import { CodeEditor } from "@/components/shared/code-editor";
import {
Card,
CardContent,
@@ -8,8 +8,8 @@ import {
} from "@/components/ui/card";
import { api } from "@/utils/api";
import { File } from "lucide-react";
import React from "react";
import { UpdateTraefikConfig } from "./update-traefik-config";
import { CodeEditor } from "@/components/shared/code-editor";
interface Props {
applicationId: string;
}
@@ -29,7 +29,7 @@ export const ShowTraefikConfig = ({ applicationId }: Props) => {
<CardTitle className="text-xl">Traefik</CardTitle>
<CardDescription>
Modify the traefik config, in rare cases you may need to add
specific config, becarefull because modifying incorrectly can break
specific config, be careful because modifying incorrectly can break
traefik and your application
</CardDescription>
</div>
@@ -1,3 +1,5 @@
import { AlertBlock } from "@/components/shared/alert-block";
import { CodeEditor } from "@/components/shared/code-editor";
import { Button } from "@/components/ui/button";
import {
Dialog,
@@ -17,14 +19,12 @@ import {
FormMessage,
} from "@/components/ui/form";
import { api } from "@/utils/api";
import { AlertBlock } from "@/components/shared/alert-block";
import { zodResolver } from "@hookform/resolvers/zod";
import jsyaml from "js-yaml";
import { useEffect, useState } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
import { z } from "zod";
import jsyaml from "js-yaml";
import { CodeEditor } from "@/components/shared/code-editor";
const UpdateTraefikConfigSchema = z.object({
traefikConfig: z.string(),
@@ -110,12 +110,15 @@ export const UpdateTraefikConfig = ({ applicationId }: Props) => {
};
return (
<Dialog open={open} onOpenChange={(open) => {
setOpen(open)
if (!open) {
form.reset();
}
}}>
<Dialog
open={open}
onOpenChange={(open) => {
setOpen(open);
if (!open) {
form.reset();
}
}}
>
<DialogTrigger asChild>
<Button isLoading={isLoading}>Modify</Button>
</DialogTrigger>
@@ -1,8 +1,4 @@
import { zodResolver } from "@hookform/resolvers/zod";
import type React from "react";
import { useEffect } from "react";
import { useForm } from "react-hook-form";
import { z } from "zod";
import { Button } from "@/components/ui/button";
import {
Dialog,
DialogContent,
@@ -22,12 +18,16 @@ import {
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
import { Button } from "@/components/ui/button";
import { PlusIcon } from "lucide-react";
import { Textarea } from "@/components/ui/textarea";
import { api } from "@/utils/api";
import { toast } from "sonner";
import { cn } from "@/lib/utils";
import { api } from "@/utils/api";
import { zodResolver } from "@hookform/resolvers/zod";
import { PlusIcon } from "lucide-react";
import type React from "react";
import { useEffect } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
import { z } from "zod";
interface Props {
serviceId: string;
serviceType:
@@ -1,4 +1,3 @@
import React from "react";
import {
AlertDialog,
AlertDialogAction,
@@ -13,6 +12,7 @@ import {
import { Button } from "@/components/ui/button";
import { api } from "@/utils/api";
import { TrashIcon } from "lucide-react";
import React from "react";
import { toast } from "sonner";
interface Props {
@@ -1,4 +1,4 @@
import React from "react";
import { AlertBlock } from "@/components/shared/alert-block";
import {
Card,
CardContent,
@@ -8,10 +8,10 @@ import {
} from "@/components/ui/card";
import { api } from "@/utils/api";
import { AlertTriangle, Package } from "lucide-react";
import React from "react";
import { AddVolumes } from "./add-volumes";
import { DeleteVolume } from "./delete-volume";
import { UpdateVolume } from "./update-volume";
import { AlertBlock } from "@/components/shared/alert-block";
interface Props {
applicationId: string;
}
@@ -1,3 +1,4 @@
import { AlertBlock } from "@/components/shared/alert-block";
import { Button } from "@/components/ui/button";
import {
Dialog,
@@ -17,15 +18,14 @@ import {
FormMessage,
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
import { api } from "@/utils/api";
import { AlertBlock } from "@/components/shared/alert-block";
import { zodResolver } from "@hookform/resolvers/zod";
import { Pencil } from "lucide-react";
import { useEffect } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
import { z } from "zod";
import { Textarea } from "@/components/ui/textarea";
const mountSchema = z.object({
mountPath: z.string().min(1, "Mount path required"),
+188 -188
View File
@@ -1,213 +1,213 @@
import {
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
} from "@/components/ui/form";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import {
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
import { api } from "@/utils/api";
import { zodResolver } from "@hookform/resolvers/zod";
import { Cog } from "lucide-react";
import { useEffect } from "react";
import { useForm } from "react-hook-form";
import { z } from "zod";
import { Button } from "@/components/ui/button";
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
import { toast } from "sonner";
import { Input } from "@/components/ui/input";
import { z } from "zod";
enum BuildType {
dockerfile = "dockerfile",
heroku_buildpacks = "heroku_buildpacks",
paketo_buildpacks = "paketo_buildpacks",
nixpacks = "nixpacks",
dockerfile = "dockerfile",
heroku_buildpacks = "heroku_buildpacks",
paketo_buildpacks = "paketo_buildpacks",
nixpacks = "nixpacks",
}
const mySchema = z.discriminatedUnion("buildType", [
z.object({
buildType: z.literal("dockerfile"),
dockerfile: z
.string({
required_error: "Dockerfile path is required",
invalid_type_error: "Dockerfile path is required",
})
.min(1, "Dockerfile required"),
}),
z.object({
buildType: z.literal("heroku_buildpacks"),
}),
z.object({
buildType: z.literal("paketo_buildpacks"),
}),
z.object({
buildType: z.literal("nixpacks"),
}),
z.object({
buildType: z.literal("dockerfile"),
dockerfile: z
.string({
required_error: "Dockerfile path is required",
invalid_type_error: "Dockerfile path is required",
})
.min(1, "Dockerfile required"),
}),
z.object({
buildType: z.literal("heroku_buildpacks"),
}),
z.object({
buildType: z.literal("paketo_buildpacks"),
}),
z.object({
buildType: z.literal("nixpacks"),
}),
]);
type AddTemplate = z.infer<typeof mySchema>;
interface Props {
applicationId: string;
applicationId: string;
}
export const ShowBuildChooseForm = ({ applicationId }: Props) => {
const { mutateAsync, isLoading } =
api.application.saveBuildType.useMutation();
const { data, refetch } = api.application.one.useQuery(
{
applicationId,
},
{
enabled: !!applicationId,
},
);
const { mutateAsync, isLoading } =
api.application.saveBuildType.useMutation();
const { data, refetch } = api.application.one.useQuery(
{
applicationId,
},
{
enabled: !!applicationId,
},
);
const form = useForm<AddTemplate>({
defaultValues: {
buildType: BuildType.nixpacks,
},
resolver: zodResolver(mySchema),
});
const form = useForm<AddTemplate>({
defaultValues: {
buildType: BuildType.nixpacks,
},
resolver: zodResolver(mySchema),
});
const buildType = form.watch("buildType");
useEffect(() => {
if (data) {
// TODO: refactor this
if (data.buildType === "dockerfile") {
form.reset({
buildType: data.buildType,
...(data.buildType && {
dockerfile: data.dockerfile || "",
}),
});
} else {
form.reset({
buildType: data.buildType,
});
}
}
}, [form.formState.isSubmitSuccessful, form.reset, data, form]);
const buildType = form.watch("buildType");
useEffect(() => {
if (data) {
// TODO: refactor this
if (data.buildType === "dockerfile") {
form.reset({
buildType: data.buildType,
...(data.buildType && {
dockerfile: data.dockerfile || "",
}),
});
} else {
form.reset({
buildType: data.buildType,
});
}
}
}, [form.formState.isSubmitSuccessful, form.reset, data, form]);
const onSubmit = async (data: AddTemplate) => {
await mutateAsync({
applicationId,
buildType: data.buildType,
dockerfile: data.buildType === "dockerfile" ? data.dockerfile : null,
})
.then(async () => {
toast.success("Build type saved");
await refetch();
})
.catch(() => {
toast.error("Error to save the build type");
});
};
const onSubmit = async (data: AddTemplate) => {
await mutateAsync({
applicationId,
buildType: data.buildType,
dockerfile: data.buildType === "dockerfile" ? data.dockerfile : null,
})
.then(async () => {
toast.success("Build type saved");
await refetch();
})
.catch(() => {
toast.error("Error to save the build type");
});
};
return (
<Card className="group relative w-full bg-transparent">
<CardHeader>
<CardTitle className="flex items-start justify-between">
<div className="flex flex-col gap-2">
<span className="flex flex-col space-y-0.5">Build Type</span>
<p className="flex items-center text-sm font-normal text-muted-foreground">
Select the way of building your code
</p>
</div>
<div className="hidden space-y-1 text-sm font-normal md:block">
<Cog className="size-6 text-muted-foreground" />
</div>
</CardTitle>
</CardHeader>
<CardContent>
<Form {...form}>
<form
onSubmit={form.handleSubmit(onSubmit)}
className="grid w-full gap-4 p-2"
>
<FormField
control={form.control}
name="buildType"
defaultValue={form.control._defaultValues.buildType}
render={({ field }) => {
return (
<FormItem className="space-y-3">
<FormLabel>Build Type</FormLabel>
<FormControl>
<RadioGroup
onValueChange={field.onChange}
value={field.value}
className="flex flex-col space-y-1"
>
<FormItem className="flex items-center space-x-3 space-y-0">
<FormControl>
<RadioGroupItem value="dockerfile" />
</FormControl>
<FormLabel className="font-normal">
Dockerfile
</FormLabel>
</FormItem>
<FormItem className="flex items-center space-x-3 space-y-0">
<FormControl>
<RadioGroupItem value="nixpacks" />
</FormControl>
<FormLabel className="font-normal">
Nixpacks
</FormLabel>
</FormItem>
<FormItem className="flex items-center space-x-3 space-y-0">
<FormControl>
<RadioGroupItem value="heroku_buildpacks" />
</FormControl>
<FormLabel className="font-normal">
Heroku Buildpacks
</FormLabel>
</FormItem>
<FormItem className="flex items-center space-x-3 space-y-0">
<FormControl>
<RadioGroupItem value="paketo_buildpacks" />
</FormControl>
<FormLabel className="font-normal">
Paketo Buildpacks
</FormLabel>
</FormItem>
</RadioGroup>
</FormControl>
<FormMessage />
</FormItem>
);
}}
/>
{buildType === "dockerfile" && (
<FormField
control={form.control}
name="dockerfile"
render={({ field }) => {
return (
<FormItem>
<FormLabel>Docker File</FormLabel>
<FormControl>
<Input
placeholder={"Path of your docker file"}
{...field}
value={field.value ?? ""}
/>
</FormControl>
return (
<Card className="group relative w-full bg-transparent">
<CardHeader>
<CardTitle className="flex items-start justify-between">
<div className="flex flex-col gap-2">
<span className="flex flex-col space-y-0.5">Build Type</span>
<p className="flex items-center text-sm font-normal text-muted-foreground">
Select the way of building your code
</p>
</div>
<div className="hidden space-y-1 text-sm font-normal md:block">
<Cog className="size-6 text-muted-foreground" />
</div>
</CardTitle>
</CardHeader>
<CardContent>
<Form {...form}>
<form
onSubmit={form.handleSubmit(onSubmit)}
className="grid w-full gap-4 p-2"
>
<FormField
control={form.control}
name="buildType"
defaultValue={form.control._defaultValues.buildType}
render={({ field }) => {
return (
<FormItem className="space-y-3">
<FormLabel>Build Type</FormLabel>
<FormControl>
<RadioGroup
onValueChange={field.onChange}
value={field.value}
className="flex flex-col space-y-1"
>
<FormItem className="flex items-center space-x-3 space-y-0">
<FormControl>
<RadioGroupItem value="dockerfile" />
</FormControl>
<FormLabel className="font-normal">
Dockerfile
</FormLabel>
</FormItem>
<FormItem className="flex items-center space-x-3 space-y-0">
<FormControl>
<RadioGroupItem value="nixpacks" />
</FormControl>
<FormLabel className="font-normal">
Nixpacks
</FormLabel>
</FormItem>
<FormItem className="flex items-center space-x-3 space-y-0">
<FormControl>
<RadioGroupItem value="heroku_buildpacks" />
</FormControl>
<FormLabel className="font-normal">
Heroku Buildpacks
</FormLabel>
</FormItem>
<FormItem className="flex items-center space-x-3 space-y-0">
<FormControl>
<RadioGroupItem value="paketo_buildpacks" />
</FormControl>
<FormLabel className="font-normal">
Paketo Buildpacks
</FormLabel>
</FormItem>
</RadioGroup>
</FormControl>
<FormMessage />
</FormItem>
);
}}
/>
{buildType === "dockerfile" && (
<FormField
control={form.control}
name="dockerfile"
render={({ field }) => {
return (
<FormItem>
<FormLabel>Docker File</FormLabel>
<FormControl>
<Input
placeholder={"Path of your docker file"}
{...field}
value={field.value ?? ""}
/>
</FormControl>
<FormMessage />
</FormItem>
);
}}
/>
)}
<div className="flex w-full justify-end">
<Button isLoading={isLoading} type="submit">
Save
</Button>
</div>
</form>
</Form>
</CardContent>
</Card>
);
<FormMessage />
</FormItem>
);
}}
/>
)}
<div className="flex w-full justify-end">
<Button isLoading={isLoading} type="submit">
Save
</Button>
</div>
</form>
</Form>
</CardContent>
</Card>
);
};
@@ -1,4 +1,3 @@
import React from "react";
import {
AlertDialog,
AlertDialogAction,
@@ -12,6 +11,7 @@ import {
} from "@/components/ui/alert-dialog";
import { api } from "@/utils/api";
import { RefreshCcw } from "lucide-react";
import React from "react";
import { toast } from "sonner";
interface Props {
@@ -1,3 +1,5 @@
import { DateTooltip } from "@/components/shared/date-tooltip";
import { StatusTooltip } from "@/components/shared/status-tooltip";
import { Button } from "@/components/ui/button";
import {
Card,
@@ -10,10 +12,8 @@ import { api } from "@/utils/api";
import { RocketIcon } from "lucide-react";
import React, { useEffect, useState } from "react";
import { CancelQueues } from "./cancel-queues";
import { ShowDeployment } from "./show-deployment";
import { StatusTooltip } from "@/components/shared/status-tooltip";
import { DateTooltip } from "@/components/shared/date-tooltip";
import { RefreshToken } from "./refresh-token";
import { ShowDeployment } from "./show-deployment";
interface Props {
applicationId: string;
@@ -1,3 +1,4 @@
import { AlertBlock } from "@/components/shared/alert-block";
import { Button } from "@/components/ui/button";
import {
Dialog,
@@ -27,7 +28,6 @@ import {
} from "@/components/ui/select";
import { Switch } from "@/components/ui/switch";
import { api } from "@/utils/api";
import { AlertBlock } from "@/components/shared/alert-block";
import { zodResolver } from "@hookform/resolvers/zod";
import { PlusIcon } from "lucide-react";
import { useEffect } from "react";
@@ -1,4 +1,3 @@
import React from "react";
import {
AlertDialog,
AlertDialogAction,
@@ -13,6 +12,7 @@ import {
import { Button } from "@/components/ui/button";
import { api } from "@/utils/api";
import { TrashIcon } from "lucide-react";
import React from "react";
import { toast } from "sonner";
interface Props {
@@ -7,11 +7,11 @@ import {
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog";
import { api } from "@/utils/api";
import { RefreshCcw } from "lucide-react";
import Link from "next/link";
import { GenerateTraefikMe } from "./generate-traefikme";
import { GenerateWildCard } from "./generate-wildcard";
import Link from "next/link";
import { api } from "@/utils/api";
interface Props {
applicationId: string;
@@ -1,4 +1,3 @@
import React from "react";
import {
AlertDialog,
AlertDialogAction,
@@ -13,6 +12,7 @@ import {
import { Button } from "@/components/ui/button";
import { api } from "@/utils/api";
import { RefreshCcw } from "lucide-react";
import React from "react";
import { toast } from "sonner";
interface Props {
@@ -1,4 +1,3 @@
import React from "react";
import {
AlertDialog,
AlertDialogAction,
@@ -13,6 +12,7 @@ import {
import { Button } from "@/components/ui/button";
import { api } from "@/utils/api";
import { SquareAsterisk } from "lucide-react";
import React from "react";
import { toast } from "sonner";
interface Props {
@@ -1,4 +1,4 @@
import React from "react";
import { Button } from "@/components/ui/button";
import {
Card,
CardContent,
@@ -6,15 +6,15 @@ import {
CardHeader,
CardTitle,
} from "@/components/ui/card";
import { ExternalLink, GlobeIcon, RefreshCcw } from "lucide-react";
import { Button } from "@/components/ui/button";
import { api } from "@/utils/api";
import { Input } from "@/components/ui/input";
import { DeleteDomain } from "./delete-domain";
import { api } from "@/utils/api";
import { ExternalLink, GlobeIcon, RefreshCcw } from "lucide-react";
import Link from "next/link";
import React from "react";
import { AddDomain } from "./add-domain";
import { UpdateDomain } from "./update-domain";
import { DeleteDomain } from "./delete-domain";
import { GenerateDomain } from "./generate-domain";
import { UpdateDomain } from "./update-domain";
interface Props {
applicationId: string;
@@ -1,3 +1,4 @@
import { AlertBlock } from "@/components/shared/alert-block";
import { Button } from "@/components/ui/button";
import {
Dialog,
@@ -27,7 +28,6 @@ import {
} from "@/components/ui/select";
import { Switch } from "@/components/ui/switch";
import { api } from "@/utils/api";
import { AlertBlock } from "@/components/shared/alert-block";
import { zodResolver } from "@hookform/resolvers/zod";
import { PenBoxIcon } from "lucide-react";
import { useEffect } from "react";
@@ -1,4 +1,5 @@
import React, { useEffect, useState } from "react";
import { CodeEditor } from "@/components/shared/code-editor";
import { Button } from "@/components/ui/button";
import {
Card,
CardContent,
@@ -6,10 +7,6 @@ import {
CardHeader,
CardTitle,
} from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { z } from "zod";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import {
Form,
FormControl,
@@ -17,11 +14,14 @@ import {
FormItem,
FormMessage,
} from "@/components/ui/form";
import { api } from "@/utils/api";
import { toast } from "sonner";
import { Toggle } from "@/components/ui/toggle";
import { CodeEditor } from "@/components/shared/code-editor";
import { api } from "@/utils/api";
import { zodResolver } from "@hookform/resolvers/zod";
import { EyeIcon, EyeOffIcon } from "lucide-react";
import React, { useEffect, useState } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
import { z } from "zod";
const addEnvironmentSchema = z.object({
environment: z.string(),
@@ -1,8 +1,4 @@
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { z } from "zod";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import {
Form,
FormControl,
@@ -11,9 +7,13 @@ import {
FormLabel,
FormMessage,
} from "@/components/ui/form";
import { useEffect } from "react";
import { Input } from "@/components/ui/input";
import { api } from "@/utils/api";
import { zodResolver } from "@hookform/resolvers/zod";
import { useEffect } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
import { z } from "zod";
const DockerProviderSchema = z.object({
dockerImage: z.string().min(1, {
@@ -4,13 +4,13 @@ import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Toggle } from "@/components/ui/toggle";
import { api } from "@/utils/api";
import { CheckCircle2, Terminal } from "lucide-react";
import React from "react";
import { toast } from "sonner";
import { DockerTerminalModal } from "../../settings/web-server/docker-terminal-modal";
import { RedbuildApplication } from "../rebuild-application";
import { StartApplication } from "../start-application";
import { StopApplication } from "../stop-application";
import { DockerTerminalModal } from "../../settings/web-server/docker-terminal-modal";
import { CheckCircle2, Terminal } from "lucide-react";
import { DeployApplication } from "./deploy-application";
import { ResetApplication } from "./reset-application";
interface Props {
@@ -1,4 +1,3 @@
import dynamic from "next/dynamic";
import {
Card,
CardContent,
@@ -6,6 +5,7 @@ import {
CardHeader,
CardTitle,
} from "@/components/ui/card";
import { Label } from "@/components/ui/label";
import {
Select,
SelectContent,
@@ -16,8 +16,8 @@ import {
SelectValue,
} from "@/components/ui/select";
import { api } from "@/utils/api";
import dynamic from "next/dynamic";
import { useEffect, useState } from "react";
import { Label } from "@/components/ui/label";
export const DockerLogs = dynamic(
() =>
import("@/components/dashboard/docker/logs/docker-logs-id").then(
@@ -1,3 +1,5 @@
import { AlertBlock } from "@/components/shared/alert-block";
import { Button } from "@/components/ui/button";
import {
Dialog,
DialogContent,
@@ -7,7 +9,6 @@ import {
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import {
Form,
FormControl,
@@ -16,16 +17,15 @@ import {
FormLabel,
FormMessage,
} from "@/components/ui/form";
import { useForm } from "react-hook-form";
import { z } from "zod";
import { AlertBlock } from "@/components/shared/alert-block";
import { zodResolver } from "@hookform/resolvers/zod";
import { useEffect } from "react";
import { toast } from "sonner";
import { Input } from "@/components/ui/input";
import { AlertTriangle, SquarePen } from "lucide-react";
import { Textarea } from "@/components/ui/textarea";
import { api } from "@/utils/api";
import { zodResolver } from "@hookform/resolvers/zod";
import { AlertTriangle, SquarePen } from "lucide-react";
import { useEffect } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
import { z } from "zod";
const updateApplicationSchema = z.object({
name: z.string().min(1, {
@@ -1,4 +1,4 @@
import React from "react";
import { Button } from "@/components/ui/button";
import {
Card,
CardContent,
@@ -6,8 +6,6 @@ import {
CardHeader,
CardTitle,
} from "@/components/ui/card";
import { api } from "@/utils/api";
import { z } from "zod";
import {
Form,
FormControl,
@@ -17,12 +15,14 @@ import {
FormLabel,
FormMessage,
} from "@/components/ui/form";
import { toast } from "sonner";
import { zodResolver } from "@hookform/resolvers/zod";
import { useForm } from "react-hook-form";
import { useEffect } from "react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { api } from "@/utils/api";
import { zodResolver } from "@hookform/resolvers/zod";
import React from "react";
import { useEffect } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
import { z } from "zod";
interface Props {
composeId: string;
}
@@ -1,4 +1,4 @@
import React from "react";
import { AlertBlock } from "@/components/shared/alert-block";
import {
Card,
CardContent,
@@ -8,10 +8,10 @@ import {
} from "@/components/ui/card";
import { api } from "@/utils/api";
import { Package } from "lucide-react";
import { DeleteVolume } from "../../application/advanced/volumes/delete-volume";
import React from "react";
import { AddVolumes } from "../../application/advanced/volumes/add-volumes";
import { DeleteVolume } from "../../application/advanced/volumes/delete-volume";
import { UpdateVolume } from "../../application/advanced/volumes/update-volume";
import { AlertBlock } from "@/components/shared/alert-block";
interface Props {
composeId: string;
}
@@ -1,4 +1,3 @@
import React from "react";
import {
AlertDialog,
AlertDialogAction,
@@ -12,6 +11,7 @@ import {
} from "@/components/ui/alert-dialog";
import { api } from "@/utils/api";
import { RefreshCcw } from "lucide-react";
import React from "react";
import { toast } from "sonner";
interface Props {
@@ -1,3 +1,5 @@
import { DateTooltip } from "@/components/shared/date-tooltip";
import { StatusTooltip } from "@/components/shared/status-tooltip";
import { Button } from "@/components/ui/button";
import {
Card,
@@ -9,11 +11,9 @@ import {
import { api } from "@/utils/api";
import { RocketIcon } from "lucide-react";
import React, { useEffect, useState } from "react";
import { StatusTooltip } from "@/components/shared/status-tooltip";
import { DateTooltip } from "@/components/shared/date-tooltip";
import { ShowDeploymentCompose } from "./show-deployment-compose";
import { RefreshTokenCompose } from "./refresh-token-compose";
import { CancelQueuesCompose } from "./cancel-queues-compose";
import { RefreshTokenCompose } from "./refresh-token-compose";
import { ShowDeploymentCompose } from "./show-deployment-compose";
interface Props {
composeId: string;
@@ -1,4 +1,5 @@
import React, { useEffect, useState } from "react";
import { CodeEditor } from "@/components/shared/code-editor";
import { Button } from "@/components/ui/button";
import {
Card,
CardContent,
@@ -6,10 +7,6 @@ import {
CardHeader,
CardTitle,
} from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { z } from "zod";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import {
Form,
FormControl,
@@ -17,11 +14,14 @@ import {
FormItem,
FormMessage,
} from "@/components/ui/form";
import { api } from "@/utils/api";
import { toast } from "sonner";
import { CodeEditor } from "@/components/shared/code-editor";
import { Toggle } from "@/components/ui/toggle";
import { api } from "@/utils/api";
import { zodResolver } from "@hookform/resolvers/zod";
import { EyeIcon, EyeOffIcon } from "lucide-react";
import React, { useEffect, useState } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
import { z } from "zod";
const addEnvironmentSchema = z.object({
environment: z.string(),
@@ -1,12 +1,4 @@
import { Button } from "@/components/ui/button";
import { ExternalLink, Globe, Terminal } from "lucide-react";
import { api } from "@/utils/api";
import { toast } from "sonner";
import { Toggle } from "@/components/ui/toggle";
import { RedbuildCompose } from "./rebuild-compose";
import { DeployCompose } from "./deploy-compose";
import { StopCompose } from "./stop-compose";
import { DockerTerminalModal } from "../../settings/web-server/docker-terminal-modal";
import {
DropdownMenu,
DropdownMenuContent,
@@ -16,7 +8,15 @@ import {
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { Toggle } from "@/components/ui/toggle";
import { api } from "@/utils/api";
import { ExternalLink, Globe, Terminal } from "lucide-react";
import Link from "next/link";
import { toast } from "sonner";
import { DockerTerminalModal } from "../../settings/web-server/docker-terminal-modal";
import { DeployCompose } from "./deploy-compose";
import { RedbuildCompose } from "./rebuild-compose";
import { StopCompose } from "./stop-compose";
interface Props {
composeId: string;
@@ -1,5 +1,5 @@
import { api } from "@/utils/api";
import { useEffect } from "react";
import { CodeEditor } from "@/components/shared/code-editor";
import { Button } from "@/components/ui/button";
import {
Form,
FormControl,
@@ -7,14 +7,14 @@ import {
FormItem,
FormMessage,
} from "@/components/ui/form";
import { api } from "@/utils/api";
import { zodResolver } from "@hookform/resolvers/zod";
import { useEffect } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
import { z } from "zod";
import { validateAndFormatYAML } from "../../application/advanced/traefik/update-traefik-config";
import { toast } from "sonner";
import { Button } from "@/components/ui/button";
import { RandomizeCompose } from "./randomize-compose";
import { CodeEditor } from "@/components/shared/code-editor";
interface Props {
composeId: string;
@@ -4,9 +4,9 @@ import { api } from "@/utils/api";
import { GitBranch, LockIcon } from "lucide-react";
import Link from "next/link";
import { useState } from "react";
import { SaveGithubProviderCompose } from "./save-github-provider-compose";
import { ComposeFileEditor } from "../compose-file-editor";
import { SaveGitProviderCompose } from "./save-git-provider-compose";
import { SaveGithubProviderCompose } from "./save-github-provider-compose";
type TabState = "github" | "git" | "raw";
interface Props {
@@ -1,3 +1,4 @@
import { AlertBlock } from "@/components/shared/alert-block";
import { Button } from "@/components/ui/button";
import {
Dialog,
@@ -7,12 +8,11 @@ import {
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { api } from "@/utils/api";
import { AlertBlock } from "@/components/shared/alert-block";
import { Dices } from "lucide-react";
import { useState } from "react";
import { toast } from "sonner";
import { Input } from "@/components/ui/input";
interface Props {
composeId: string;
@@ -1,3 +1,4 @@
import { Badge } from "@/components/ui/badge";
import {
Card,
CardContent,
@@ -5,11 +6,10 @@ import {
CardHeader,
CardTitle,
} from "@/components/ui/card";
import React from "react";
import { ShowProviderFormCompose } from "./generic/show";
import { ComposeActions } from "./actions";
import { Badge } from "@/components/ui/badge";
import { api } from "@/utils/api";
import React from "react";
import { ComposeActions } from "./actions";
import { ShowProviderFormCompose } from "./generic/show";
interface Props {
composeId: string;
}
+2 -2
View File
@@ -1,4 +1,3 @@
import dynamic from "next/dynamic";
import {
Card,
CardContent,
@@ -6,6 +5,7 @@ import {
CardHeader,
CardTitle,
} from "@/components/ui/card";
import { Label } from "@/components/ui/label";
import {
Select,
SelectContent,
@@ -16,8 +16,8 @@ import {
SelectValue,
} from "@/components/ui/select";
import { api } from "@/utils/api";
import dynamic from "next/dynamic";
import { useEffect, useState } from "react";
import { Label } from "@/components/ui/label";
export const DockerLogs = dynamic(
() =>
import("@/components/dashboard/docker/logs/docker-logs-id").then(
@@ -5,8 +5,7 @@ import {
CardHeader,
CardTitle,
} from "@/components/ui/card";
import { api } from "@/utils/api";
import { useEffect, useState } from "react";
import { Label } from "@/components/ui/label";
import {
Select,
SelectContent,
@@ -16,7 +15,8 @@ import {
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import { Label } from "@/components/ui/label";
import { api } from "@/utils/api";
import { useEffect, useState } from "react";
import { DockerMonitoring } from "../../monitoring/docker/show";
interface Props {
@@ -1,3 +1,5 @@
import { AlertBlock } from "@/components/shared/alert-block";
import { Button } from "@/components/ui/button";
import {
Dialog,
DialogContent,
@@ -7,7 +9,6 @@ import {
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import {
Form,
FormControl,
@@ -16,16 +17,15 @@ import {
FormLabel,
FormMessage,
} from "@/components/ui/form";
import { useForm } from "react-hook-form";
import { z } from "zod";
import { AlertBlock } from "@/components/shared/alert-block";
import { zodResolver } from "@hookform/resolvers/zod";
import { useEffect } from "react";
import { toast } from "sonner";
import { Input } from "@/components/ui/input";
import { SquarePen } from "lucide-react";
import { Textarea } from "@/components/ui/textarea";
import { api } from "@/utils/api";
import { zodResolver } from "@hookform/resolvers/zod";
import { SquarePen } from "lucide-react";
import { useEffect } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
import { z } from "zod";
const updateComposeSchema = z.object({
name: z.string().min(1, {
@@ -1,4 +1,11 @@
import { Button } from "@/components/ui/button";
import {
Command,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
} from "@/components/ui/command";
import {
Dialog,
DialogContent,
@@ -11,36 +18,29 @@ import {
import {
Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormDescription,
FormMessage,
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { api } from "@/utils/api";
import { zodResolver } from "@hookform/resolvers/zod";
import { PlusIcon } from "lucide-react";
import { useEffect } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
import { CheckIcon, ChevronsUpDown } from "lucide-react";
import { ScrollArea } from "@/components/ui/scroll-area";
import {
Command,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
} from "@/components/ui/command";
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@/components/ui/popover";
import { z } from "zod";
import { cn } from "@/lib/utils";
import { ScrollArea } from "@/components/ui/scroll-area";
import { Switch } from "@/components/ui/switch";
import { cn } from "@/lib/utils";
import { api } from "@/utils/api";
import { zodResolver } from "@hookform/resolvers/zod";
import { PlusIcon } from "lucide-react";
import { CheckIcon, ChevronsUpDown } from "lucide-react";
import { useEffect } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
import { z } from "zod";
const AddPostgresBackup1Schema = z.object({
destinationId: z.string().min(1, "Destination required"),
@@ -1,4 +1,11 @@
import { Button } from "@/components/ui/button";
import {
Command,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
} from "@/components/ui/command";
import {
Dialog,
DialogContent,
@@ -18,28 +25,21 @@ import {
FormMessage,
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { api } from "@/utils/api";
import { zodResolver } from "@hookform/resolvers/zod";
import { Pencil, CheckIcon, ChevronsUpDown, PenBoxIcon } from "lucide-react";
import { useEffect } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
import { ScrollArea } from "@/components/ui/scroll-area";
import { z } from "zod";
import { Switch } from "@/components/ui/switch";
import {
Command,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
} from "@/components/ui/command";
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@/components/ui/popover";
import { ScrollArea } from "@/components/ui/scroll-area";
import { Switch } from "@/components/ui/switch";
import { cn } from "@/lib/utils";
import { api } from "@/utils/api";
import { zodResolver } from "@hookform/resolvers/zod";
import { CheckIcon, ChevronsUpDown, PenBoxIcon, Pencil } from "lucide-react";
import { useEffect } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
import { z } from "zod";
const UpdateBackupSchema = z.object({
destinationId: z.string().min(1, "Destination required"),
@@ -1,7 +1,7 @@
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import React, { useEffect } from "react";
import { Terminal } from "@xterm/xterm";
import React, { useEffect } from "react";
import { FitAddon } from "xterm-addon-fit";
import "@xterm/xterm/css/xterm.css";
@@ -1,5 +1,3 @@
import dynamic from "next/dynamic";
import React from "react";
import {
Dialog,
DialogContent,
@@ -9,6 +7,8 @@ import {
DialogTrigger,
} from "@/components/ui/dialog";
import { DropdownMenuItem } from "@/components/ui/dropdown-menu";
import dynamic from "next/dynamic";
import type React from "react";
export const DockerLogsId = dynamic(
() =>
import("@/components/dashboard/docker/logs/docker-logs-id").then(
+1 -1
View File
@@ -1,6 +1,6 @@
import * as React from "react";
import type { ColumnDef } from "@tanstack/react-table";
import { ArrowUpDown, MoreHorizontal } from "lucide-react";
import * as React from "react";
import { Button } from "@/components/ui/button";
import {
@@ -1,4 +1,3 @@
import * as React from "react";
import {
type ColumnFiltersState,
type SortingState,
@@ -11,6 +10,7 @@ import {
useReactTable,
} from "@tanstack/react-table";
import { ChevronDown } from "lucide-react";
import * as React from "react";
import { Button } from "@/components/ui/button";
import {
@@ -28,7 +28,7 @@ import {
TableHeader,
TableRow,
} from "@/components/ui/table";
import { api, type RouterOutputs } from "@/utils/api";
import { type RouterOutputs, api } from "@/utils/api";
import { columns } from "./colums";
export type Container = NonNullable<
RouterOutputs["docker"]["getContainers"]
@@ -6,8 +6,8 @@ import {
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog";
import dynamic from "next/dynamic";
import { DropdownMenuItem } from "@/components/ui/dropdown-menu";
import dynamic from "next/dynamic";
const Terminal = dynamic(
() => import("./docker-terminal").then((e) => e.DockerTerminal),
@@ -1,9 +1,9 @@
import React, { useEffect, useRef } from "react";
import { Terminal } from "@xterm/xterm";
import React, { useEffect, useRef } from "react";
import { FitAddon } from "xterm-addon-fit";
import "@xterm/xterm/css/xterm.css";
import { AttachAddon } from "@xterm/addon-attach";
import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { AttachAddon } from "@xterm/addon-attach";
interface Props {
id: string;
@@ -1,5 +1,7 @@
import { Button } from "@/components/ui/button";
import { AlertBlock } from "@/components/shared/alert-block";
import { CodeEditor } from "@/components/shared/code-editor";
import {
Form,
FormControl,
@@ -10,14 +12,12 @@ import {
FormMessage,
} from "@/components/ui/form";
import { api } from "@/utils/api";
import { AlertBlock } from "@/components/shared/alert-block";
import { zodResolver } from "@hookform/resolvers/zod";
import { useEffect, useState } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
import { z } from "zod";
import { validateAndFormatYAML } from "../application/advanced/traefik/update-traefik-config";
import { CodeEditor } from "@/components/shared/code-editor";
const UpdateServerMiddlewareConfigSchema = z.object({
traefikConfig: z.string(),
@@ -1,8 +1,8 @@
import React from "react";
import { api } from "@/utils/api";
import { Workflow, Folder, FileIcon } from "lucide-react";
import { Tree } from "@/components/ui/file-tree";
import { api } from "@/utils/api";
import { FileIcon, Folder, Workflow } from "lucide-react";
import { cn } from "@/lib/utils";
import { ShowTraefikFile } from "./show-traefik-file";
@@ -1,12 +1,5 @@
import React, { useEffect } from "react";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { api } from "@/utils/api";
import { z } from "zod";
import { Input } from "@/components/ui/input";
import { ShowMariadbResources } from "./show-mariadb-resources";
import { toast } from "sonner";
import { zodResolver } from "@hookform/resolvers/zod";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import {
Form,
FormControl,
@@ -15,8 +8,15 @@ import {
FormLabel,
FormMessage,
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { api } from "@/utils/api";
import { zodResolver } from "@hookform/resolvers/zod";
import React, { useEffect } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
import { z } from "zod";
import { ShowVolumes } from "../volumes/show-volumes";
import { ShowMariadbResources } from "./show-mariadb-resources";
const addDockerImage = z.object({
dockerImage: z.string().min(1, "Docker image is required"),
@@ -1,3 +1,4 @@
import { AlertBlock } from "@/components/shared/alert-block";
import { Button } from "@/components/ui/button";
import {
Card,
@@ -21,7 +22,6 @@ import React, { useEffect } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
import { z } from "zod";
import { AlertBlock } from "@/components/shared/alert-block";
const addResourcesMariadb = z.object({
memoryReservation: z.number().nullable().optional(),
@@ -1,4 +1,4 @@
import React from "react";
import { Button } from "@/components/ui/button";
import {
Card,
CardContent,
@@ -6,20 +6,20 @@ import {
CardHeader,
CardTitle,
} from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { api } from "@/utils/api";
import { DatabaseBackup, Play } from "lucide-react";
import Link from "next/link";
import { AddBackup } from "../../database/backups/add-backup";
import { DeleteBackup } from "../../database/backups/delete-backup";
import { UpdateBackup } from "../../database/backups/update-backup";
import { toast } from "sonner";
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "@/components/ui/tooltip";
import { api } from "@/utils/api";
import { DatabaseBackup, Play } from "lucide-react";
import Link from "next/link";
import React from "react";
import { toast } from "sonner";
import { AddBackup } from "../../database/backups/add-backup";
import { DeleteBackup } from "../../database/backups/delete-backup";
import { UpdateBackup } from "../../database/backups/update-backup";
interface Props {
mariadbId: string;
}
@@ -1,4 +1,5 @@
import React, { useEffect } from "react";
import { CodeEditor } from "@/components/shared/code-editor";
import { Button } from "@/components/ui/button";
import {
Card,
CardContent,
@@ -6,10 +7,6 @@ import {
CardHeader,
CardTitle,
} from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { z } from "zod";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import {
Form,
FormControl,
@@ -18,8 +15,11 @@ import {
FormMessage,
} from "@/components/ui/form";
import { api } from "@/utils/api";
import { zodResolver } from "@hookform/resolvers/zod";
import React, { useEffect } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
import { CodeEditor } from "@/components/shared/code-editor";
import { z } from "zod";
const addEnvironmentSchema = z.object({
environment: z.string(),
@@ -1,3 +1,4 @@
import { ToggleVisibilityInput } from "@/components/shared/toggle-visibility-input";
import { Button } from "@/components/ui/button";
import {
Card,
@@ -22,7 +23,6 @@ import React, { useEffect, useState } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
import { z } from "zod";
import { ToggleVisibilityInput } from "@/components/shared/toggle-visibility-input";
const DockerProviderSchema = z.object({
externalPort: z.preprocess((a) => {
@@ -1,13 +1,13 @@
import React from "react";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { api } from "@/utils/api";
import { StopMariadb } from "./stop-mariadb";
import { StartMariadb } from "../start-mariadb";
import { DockerTerminalModal } from "../../settings/web-server/docker-terminal-modal";
import { Terminal } from "lucide-react";
import React from "react";
import { DockerTerminalModal } from "../../settings/web-server/docker-terminal-modal";
import { StartMariadb } from "../start-mariadb";
import { DeployMariadb } from "./deploy-mariadb";
import { ResetMariadb } from "./reset-mariadb";
import { StopMariadb } from "./stop-mariadb";
interface Props {
mariadbId: string;
@@ -1,9 +1,9 @@
import React from "react";
import { ToggleVisibilityInput } from "@/components/shared/toggle-visibility-input";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { api } from "@/utils/api";
import { ToggleVisibilityInput } from "@/components/shared/toggle-visibility-input";
import React from "react";
interface Props {
mariadbId: string;
@@ -1,13 +1,13 @@
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
AlertDialogTrigger,
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
AlertDialogTrigger,
} from "@/components/ui/alert-dialog";
import { Button } from "@/components/ui/button";
import { api } from "@/utils/api";
@@ -15,51 +15,51 @@ import { Ban } from "lucide-react";
import { toast } from "sonner";
interface Props {
mariadbId: string;
mariadbId: string;
}
export const StopMariadb = ({ mariadbId }: Props) => {
const { mutateAsync, isLoading } = api.mariadb.stop.useMutation();
const utils = api.useUtils();
return (
<AlertDialog>
<AlertDialogTrigger asChild>
<Button variant="destructive" isLoading={isLoading}>
Stop
<Ban className="size-4" />
</Button>
</AlertDialogTrigger>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>
Are you absolutely sure to stop the database?
</AlertDialogTitle>
<AlertDialogDescription>
This will stop the database
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel>Cancel</AlertDialogCancel>
<AlertDialogAction
onClick={async () => {
await mutateAsync({
mariadbId,
})
.then(async () => {
await utils.mariadb.one.invalidate({
mariadbId,
});
toast.success("Application stopped succesfully");
})
.catch(() => {
toast.error("Error to stop the Application");
});
}}
>
Confirm
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
);
const { mutateAsync, isLoading } = api.mariadb.stop.useMutation();
const utils = api.useUtils();
return (
<AlertDialog>
<AlertDialogTrigger asChild>
<Button variant="destructive" isLoading={isLoading}>
Stop
<Ban className="size-4" />
</Button>
</AlertDialogTrigger>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>
Are you absolutely sure to stop the database?
</AlertDialogTitle>
<AlertDialogDescription>
This will stop the database
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel>Cancel</AlertDialogCancel>
<AlertDialogAction
onClick={async () => {
await mutateAsync({
mariadbId,
})
.then(async () => {
await utils.mariadb.one.invalidate({
mariadbId,
});
toast.success("Application stopped succesfully");
})
.catch(() => {
toast.error("Error to stop the Application");
});
}}
>
Confirm
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
);
};
+53 -53
View File
@@ -1,13 +1,13 @@
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
AlertDialogTrigger,
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
AlertDialogTrigger,
} from "@/components/ui/alert-dialog";
import { Button } from "@/components/ui/button";
import { api } from "@/utils/api";
@@ -15,51 +15,51 @@ import { CheckCircle2 } from "lucide-react";
import { toast } from "sonner";
interface Props {
mariadbId: string;
mariadbId: string;
}
export const StartMariadb = ({ mariadbId }: Props) => {
const { mutateAsync, isLoading } = api.mariadb.start.useMutation();
const utils = api.useUtils();
return (
<AlertDialog>
<AlertDialogTrigger asChild>
<Button variant="secondary" isLoading={isLoading}>
Start
<CheckCircle2 className="size-4" />
</Button>
</AlertDialogTrigger>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>
Are you sure to start the database?
</AlertDialogTitle>
<AlertDialogDescription>
This will start the database
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel>Cancel</AlertDialogCancel>
<AlertDialogAction
onClick={async () => {
await mutateAsync({
mariadbId,
})
.then(async () => {
await utils.mariadb.one.invalidate({
mariadbId,
});
toast.success("Database started succesfully");
})
.catch(() => {
toast.error("Error to start the Database");
});
}}
>
Confirm
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
);
const { mutateAsync, isLoading } = api.mariadb.start.useMutation();
const utils = api.useUtils();
return (
<AlertDialog>
<AlertDialogTrigger asChild>
<Button variant="secondary" isLoading={isLoading}>
Start
<CheckCircle2 className="size-4" />
</Button>
</AlertDialogTrigger>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>
Are you sure to start the database?
</AlertDialogTitle>
<AlertDialogDescription>
This will start the database
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel>Cancel</AlertDialogCancel>
<AlertDialogAction
onClick={async () => {
await mutateAsync({
mariadbId,
})
.then(async () => {
await utils.mariadb.one.invalidate({
mariadbId,
});
toast.success("Database started succesfully");
})
.catch(() => {
toast.error("Error to start the Database");
});
}}
>
Confirm
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
);
};
@@ -1,3 +1,5 @@
import { AlertBlock } from "@/components/shared/alert-block";
import { Button } from "@/components/ui/button";
import {
Dialog,
DialogContent,
@@ -7,7 +9,6 @@ import {
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import {
Form,
FormControl,
@@ -16,16 +17,15 @@ import {
FormLabel,
FormMessage,
} from "@/components/ui/form";
import { useForm } from "react-hook-form";
import { z } from "zod";
import { AlertBlock } from "@/components/shared/alert-block";
import { zodResolver } from "@hookform/resolvers/zod";
import { useEffect } from "react";
import { toast } from "sonner";
import { Input } from "@/components/ui/input";
import { AlertTriangle, SquarePen } from "lucide-react";
import { Textarea } from "@/components/ui/textarea";
import { api } from "@/utils/api";
import { zodResolver } from "@hookform/resolvers/zod";
import { AlertTriangle, SquarePen } from "lucide-react";
import { useEffect } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
import { z } from "zod";
const updateMariadbSchema = z.object({
name: z.string().min(1, {
@@ -1,4 +1,4 @@
import React from "react";
import { AlertBlock } from "@/components/shared/alert-block";
import {
Card,
CardContent,
@@ -8,10 +8,10 @@ import {
} from "@/components/ui/card";
import { api } from "@/utils/api";
import { AlertTriangle, Package } from "lucide-react";
import { DeleteVolume } from "../../application/advanced/volumes/delete-volume";
import React from "react";
import { AddVolumes } from "../../application/advanced/volumes/add-volumes";
import { DeleteVolume } from "../../application/advanced/volumes/delete-volume";
import { UpdateVolume } from "../../application/advanced/volumes/update-volume";
import { AlertBlock } from "@/components/shared/alert-block";
interface Props {
mariadbId: string;
}
@@ -1,11 +1,5 @@
import React, { useEffect } from "react";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { api } from "@/utils/api";
import { z } from "zod";
import { Input } from "@/components/ui/input";
import { toast } from "sonner";
import { zodResolver } from "@hookform/resolvers/zod";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import {
Form,
FormControl,
@@ -14,9 +8,15 @@ import {
FormLabel,
FormMessage,
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { api } from "@/utils/api";
import { zodResolver } from "@hookform/resolvers/zod";
import React, { useEffect } from "react";
import { useForm } from "react-hook-form";
import { ShowMongoResources } from "./show-mongo-resources";
import { toast } from "sonner";
import { z } from "zod";
import { ShowVolumes } from "../volumes/show-volumes";
import { ShowMongoResources } from "./show-mongo-resources";
const addDockerImage = z.object({
dockerImage: z.string().min(1, "Docker image is required"),
@@ -1,3 +1,4 @@
import { AlertBlock } from "@/components/shared/alert-block";
import { Button } from "@/components/ui/button";
import {
Card,
@@ -21,7 +22,6 @@ import React, { useEffect } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
import { z } from "zod";
import { AlertBlock } from "@/components/shared/alert-block";
const addResourcesMongo = z.object({
memoryReservation: z.number().nullable().optional(),
@@ -1,4 +1,4 @@
import React from "react";
import { Button } from "@/components/ui/button";
import {
Card,
CardContent,
@@ -6,20 +6,20 @@ import {
CardHeader,
CardTitle,
} from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { api } from "@/utils/api";
import { DatabaseBackup, Play } from "lucide-react";
import Link from "next/link";
import { AddBackup } from "../../database/backups/add-backup";
import { DeleteBackup } from "../../database/backups/delete-backup";
import { UpdateBackup } from "../../database/backups/update-backup";
import { toast } from "sonner";
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "@/components/ui/tooltip";
import { api } from "@/utils/api";
import { DatabaseBackup, Play } from "lucide-react";
import Link from "next/link";
import React from "react";
import { toast } from "sonner";
import { AddBackup } from "../../database/backups/add-backup";
import { DeleteBackup } from "../../database/backups/delete-backup";
import { UpdateBackup } from "../../database/backups/update-backup";
interface Props {
mongoId: string;
}
@@ -1,13 +1,13 @@
import React from "react";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { api } from "@/utils/api";
import { StopMongo } from "./stop-mongo";
import { StartMongo } from "../start-mongo";
import { DockerTerminalModal } from "../../settings/web-server/docker-terminal-modal";
import { Terminal } from "lucide-react";
import React from "react";
import { DockerTerminalModal } from "../../settings/web-server/docker-terminal-modal";
import { StartMongo } from "../start-mongo";
import { DeployMongo } from "./deploy-mongo";
import { ResetMongo } from "./reset-mongo";
import { StopMongo } from "./stop-mongo";
interface Props {
mongoId: string;
}
@@ -1,9 +1,9 @@
import React from "react";
import { ToggleVisibilityInput } from "@/components/shared/toggle-visibility-input";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { api } from "@/utils/api";
import { ToggleVisibilityInput } from "@/components/shared/toggle-visibility-input";
import React from "react";
interface Props {
mongoId: string;
@@ -1,13 +1,13 @@
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
AlertDialogTrigger,
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
AlertDialogTrigger,
} from "@/components/ui/alert-dialog";
import { Button } from "@/components/ui/button";
import { api } from "@/utils/api";
@@ -15,51 +15,51 @@ import { Ban } from "lucide-react";
import { toast } from "sonner";
interface Props {
mongoId: string;
mongoId: string;
}
export const StopMongo = ({ mongoId }: Props) => {
const { mutateAsync, isLoading } = api.mongo.stop.useMutation();
const utils = api.useUtils();
return (
<AlertDialog>
<AlertDialogTrigger asChild>
<Button variant="destructive" isLoading={isLoading}>
Stop
<Ban className="size-4" />
</Button>
</AlertDialogTrigger>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>
Are you absolutely sure to stop the database?
</AlertDialogTitle>
<AlertDialogDescription>
This will stop the database
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel>Cancel</AlertDialogCancel>
<AlertDialogAction
onClick={async () => {
await mutateAsync({
mongoId,
})
.then(async () => {
await utils.mongo.one.invalidate({
mongoId,
});
toast.success("Application stopped succesfully");
})
.catch(() => {
toast.error("Error to stop the Application");
});
}}
>
Confirm
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
);
const { mutateAsync, isLoading } = api.mongo.stop.useMutation();
const utils = api.useUtils();
return (
<AlertDialog>
<AlertDialogTrigger asChild>
<Button variant="destructive" isLoading={isLoading}>
Stop
<Ban className="size-4" />
</Button>
</AlertDialogTrigger>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>
Are you absolutely sure to stop the database?
</AlertDialogTitle>
<AlertDialogDescription>
This will stop the database
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel>Cancel</AlertDialogCancel>
<AlertDialogAction
onClick={async () => {
await mutateAsync({
mongoId,
})
.then(async () => {
await utils.mongo.one.invalidate({
mongoId,
});
toast.success("Application stopped succesfully");
})
.catch(() => {
toast.error("Error to stop the Application");
});
}}
>
Confirm
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
);
};
+53 -53
View File
@@ -1,13 +1,13 @@
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
AlertDialogTrigger,
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
AlertDialogTrigger,
} from "@/components/ui/alert-dialog";
import { Button } from "@/components/ui/button";
import { api } from "@/utils/api";
@@ -15,51 +15,51 @@ import { CheckCircle2 } from "lucide-react";
import { toast } from "sonner";
interface Props {
mongoId: string;
mongoId: string;
}
export const StartMongo = ({ mongoId }: Props) => {
const { mutateAsync, isLoading } = api.mongo.start.useMutation();
const utils = api.useUtils();
return (
<AlertDialog>
<AlertDialogTrigger asChild>
<Button variant="secondary" isLoading={isLoading}>
Start
<CheckCircle2 className="size-4" />
</Button>
</AlertDialogTrigger>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>
Are you sure to start the database?
</AlertDialogTitle>
<AlertDialogDescription>
This will start the database
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel>Cancel</AlertDialogCancel>
<AlertDialogAction
onClick={async () => {
await mutateAsync({
mongoId,
})
.then(async () => {
await utils.mongo.one.invalidate({
mongoId,
});
toast.success("Database started succesfully");
})
.catch(() => {
toast.error("Error to start the Database");
});
}}
>
Confirm
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
);
const { mutateAsync, isLoading } = api.mongo.start.useMutation();
const utils = api.useUtils();
return (
<AlertDialog>
<AlertDialogTrigger asChild>
<Button variant="secondary" isLoading={isLoading}>
Start
<CheckCircle2 className="size-4" />
</Button>
</AlertDialogTrigger>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>
Are you sure to start the database?
</AlertDialogTitle>
<AlertDialogDescription>
This will start the database
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel>Cancel</AlertDialogCancel>
<AlertDialogAction
onClick={async () => {
await mutateAsync({
mongoId,
})
.then(async () => {
await utils.mongo.one.invalidate({
mongoId,
});
toast.success("Database started succesfully");
})
.catch(() => {
toast.error("Error to start the Database");
});
}}
>
Confirm
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
);
};
+8 -8
View File
@@ -1,3 +1,5 @@
import { AlertBlock } from "@/components/shared/alert-block";
import { Button } from "@/components/ui/button";
import {
Dialog,
DialogContent,
@@ -7,7 +9,6 @@ import {
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import {
Form,
FormControl,
@@ -16,16 +17,15 @@ import {
FormLabel,
FormMessage,
} from "@/components/ui/form";
import { useForm } from "react-hook-form";
import { z } from "zod";
import { AlertBlock } from "@/components/shared/alert-block";
import { zodResolver } from "@hookform/resolvers/zod";
import { useEffect } from "react";
import { toast } from "sonner";
import { Input } from "@/components/ui/input";
import { AlertTriangle, SquarePen } from "lucide-react";
import { Textarea } from "@/components/ui/textarea";
import { api } from "@/utils/api";
import { zodResolver } from "@hookform/resolvers/zod";
import { AlertTriangle, SquarePen } from "lucide-react";
import { useEffect } from "react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
import { z } from "zod";
const updateMongoSchema = z.object({
name: z.string().min(1, {
@@ -1,4 +1,4 @@
import React from "react";
import { AlertBlock } from "@/components/shared/alert-block";
import {
Card,
CardContent,
@@ -8,10 +8,10 @@ import {
} from "@/components/ui/card";
import { api } from "@/utils/api";
import { AlertTriangle, Package } from "lucide-react";
import { DeleteVolume } from "../../application/advanced/volumes/delete-volume";
import React from "react";
import { AddVolumes } from "../../application/advanced/volumes/add-volumes";
import { DeleteVolume } from "../../application/advanced/volumes/delete-volume";
import { UpdateVolume } from "../../application/advanced/volumes/update-volume";
import { AlertBlock } from "@/components/shared/alert-block";
interface Props {
mongoId: string;
}
@@ -1,14 +1,14 @@
import { format } from "date-fns";
import {
AreaChart,
Area,
YAxis,
AreaChart,
CartesianGrid,
Tooltip,
ResponsiveContainer,
Legend,
ResponsiveContainer,
Tooltip,
YAxis,
} from "recharts";
import type { DockerStatsJSON } from "./show";
import { format } from "date-fns";
interface Props {
acummulativeData: DockerStatsJSON["block"];
@@ -1,14 +1,14 @@
import { format } from "date-fns";
import {
AreaChart,
Area,
YAxis,
AreaChart,
CartesianGrid,
Tooltip,
ResponsiveContainer,
Legend,
ResponsiveContainer,
Tooltip,
YAxis,
} from "recharts";
import type { DockerStatsJSON } from "./show";
import { format } from "date-fns";
interface Props {
acummulativeData: DockerStatsJSON["cpu"];

Some files were not shown because too many files have changed in this diff Show More