Skip to content

Commit 096bb40

Browse files
committed
feat: #102 try the service templates concept
1 parent c41c1a4 commit 096bb40

File tree

5 files changed

+2723
-1066
lines changed

5 files changed

+2723
-1066
lines changed

config/mail.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@
109109
*/
110110

111111
'from' => [
112-
'address' => env('MAIL_FROM_ADDRESS', 'noreply@ptah.sh'),
112+
'address' => env('MAIL_FROM_ADDRESS', 'noreply@watchtower.ptah.sh'),
113113
'name' => env('MAIL_FROM_NAME', 'Ptah.sh'),
114114
],
115115

resources/js/Components/ConfirmationModal.vue

+30-10
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<script setup>
2-
import Modal from './Modal.vue';
2+
import Modal from "./Modal.vue";
33
4-
const emit = defineEmits(['close']);
4+
const emit = defineEmits(["close"]);
55
66
defineProps({
77
show: {
@@ -10,7 +10,7 @@ defineProps({
1010
},
1111
maxWidth: {
1212
type: String,
13-
default: '2xl',
13+
default: "2xl",
1414
},
1515
closeable: {
1616
type: Boolean,
@@ -19,7 +19,7 @@ defineProps({
1919
});
2020
2121
const close = () => {
22-
emit('close');
22+
emit("close");
2323
};
2424
</script>
2525

@@ -32,25 +32,45 @@ const close = () => {
3232
>
3333
<div class="bg-white dark:bg-gray-800 px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
3434
<div class="sm:flex sm:items-start">
35-
<div class="mx-auto shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-red-100 sm:mx-0 sm:h-10 sm:w-10">
36-
<svg class="h-6 w-6 text-red-600 dark:text-red-400" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
37-
<path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z" />
35+
<div
36+
class="mx-auto shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-red-100 sm:mx-0 sm:h-10 sm:w-10"
37+
>
38+
<svg
39+
class="h-6 w-6 text-red-600 dark:text-red-400"
40+
xmlns="http://www.w3.org/2000/svg"
41+
fill="none"
42+
viewBox="0 0 24 24"
43+
stroke-width="1.5"
44+
stroke="currentColor"
45+
>
46+
<path
47+
stroke-linecap="round"
48+
stroke-linejoin="round"
49+
d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z"
50+
/>
3851
</svg>
3952
</div>
4053

4154
<div class="mt-3 text-center sm:mt-0 sm:ms-4 sm:text-start">
42-
<h3 class="text-lg font-medium text-gray-900 dark:text-gray-100">
55+
<h3
56+
class="text-lg font-medium text-gray-900 dark:text-gray-100"
57+
>
4358
<slot name="title" />
4459
</h3>
4560

46-
<div class="mt-4 text-sm text-gray-600 dark:text-gray-400">
61+
<div
62+
class="mt-4 text-sm text-gray-600 dark:text-gray-400"
63+
v-auto-animate
64+
>
4765
<slot name="content" />
4866
</div>
4967
</div>
5068
</div>
5169
</div>
5270

53-
<div class="flex flex-row justify-end px-6 py-4 bg-gray-100 dark:bg-gray-800 text-end">
71+
<div
72+
class="flex flex-row justify-end px-6 py-4 bg-gray-100 dark:bg-gray-800 text-end gap-2"
73+
>
5474
<slot name="footer" />
5575
</div>
5676
</Modal>
+123-61
Original file line numberDiff line numberDiff line change
@@ -1,88 +1,150 @@
11
<script setup>
2-
32
import InputError from "@/Components/InputError.vue";
43
import InputLabel from "@/Components/InputLabel.vue";
54
import PrimaryButton from "@/Components/PrimaryButton.vue";
65
import AppLayout from "@/Layouts/AppLayout.vue";
76
import TextInput from "@/Components/TextInput.vue";
87
import ActionSection from "@/Components/ActionSection.vue";
9-
import {useForm} from "@inertiajs/vue3";
8+
import { useForm } from "@inertiajs/vue3";
109
import FormField from "@/Components/FormField.vue";
1110
import Select from "@/Components/Select.vue";
1211
import SecondaryButton from "@/Components/SecondaryButton.vue";
1312
import TextArea from "@/Components/TextArea.vue";
14-
import {computed, effect, reactive} from "vue";
13+
import { computed, effect, reactive } from "vue";
1514
import ServiceDetailsForm from "@/Pages/Services/Partials/ServiceDetailsForm.vue";
1615
import DeploymentData from "@/Pages/Services/Partials/DeploymentData.vue";
16+
import TemplatePicker from "@/Pages/Services/Partials/TemplatePicker.vue";
1717
1818
const props = defineProps({
19-
'swarms': Array,
20-
'networks': Array,
21-
'nodes': Array,
22-
'deploymentData': Object,
23-
'dockerRegistries': Array,
24-
's3Storages': Array,
25-
})
19+
swarms: Array,
20+
networks: Array,
21+
nodes: Array,
22+
deploymentData: Object,
23+
dockerRegistries: Array,
24+
s3Storages: Array,
25+
});
2626
2727
const form = useForm({
28-
name: '',
29-
swarm_id: props.swarms[0]?.id,
30-
deploymentData: props.deploymentData
28+
name: "",
29+
swarm_id: props.swarms[0]?.id,
30+
deploymentData: props.deploymentData,
3131
});
3232
3333
const createService = () => {
34-
form.post(route('services.store'))
35-
}
34+
form.post(route("services.store"));
35+
};
36+
37+
const showTemplatePicker = reactive({
38+
show: false,
39+
});
40+
41+
const openTemplatePicker = () => {
42+
showTemplatePicker.show = true;
43+
};
44+
45+
const hideTemplatePicker = () => {
46+
showTemplatePicker.show = false;
47+
};
48+
49+
const applyTemplate = (template) => {
50+
form.name = template.name;
51+
console.log(JSON.stringify(template.deploymentData.processes));
52+
form.deploymentData.processes = template.deploymentData.processes;
53+
54+
hideTemplatePicker();
55+
};
3656
</script>
3757

3858
<template>
39-
<AppLayout title="Dashboard">
40-
<template #header>
41-
<h2 class="font-semibold text-xl text-gray-800 dark:text-gray-200 leading-tight">
42-
Create Service
43-
</h2>
44-
</template>
45-
46-
<div class="py-12">
47-
<form class="max-w-7xl mx-auto sm:px-6 lg:px-8" @submit.prevent="createService">
48-
<ActionSection>
49-
<template #title>
50-
Service Details
51-
</template>
52-
53-
<template #description>
54-
<p>Select a swarm where the service will be deployed to.</p>
55-
<p>The name of the service can be changed at any time. Be aware, that the service name in the Swarm cluster
56-
will not be changed.</p>
57-
58-
<p>You can isolate containers from each other by using different networks.</p>
59-
<p>Service will be accessible by the internal domain name to other containers on the same network.</p>
60-
<p>You can make certain ports of the containers accessible from the host network. Please set up the firewall
61-
rule on your host to prevent unwanted access.</p>
62-
<p>If you don't select the Placement Node, the containers will be able to run on any node of the Swarm
63-
Cluster.</p>
64-
</template>
65-
66-
<template #content>
67-
<ServiceDetailsForm v-model="form" :team="$page.props.auth.user.current_team" :swarms="swarms" />
68-
</template>
69-
</ActionSection>
70-
71-
<DeploymentData v-model="form.deploymentData"
72-
:networks="networks"
73-
:nodes="nodes"
74-
:errors="form.errors"
75-
:service-name="form.name"
76-
:docker-registries="props.dockerRegistries"
77-
:s3-storages="props.s3Storages"
59+
<AppLayout title="Dashboard">
60+
<TemplatePicker
61+
:show="showTemplatePicker.show"
62+
@apply="applyTemplate"
63+
@close="hideTemplatePicker"
7864
/>
7965

80-
<div class="flex justify-end">
81-
<PrimaryButton :class="{ 'opacity-25': form.processing }" :disabled="form.processing">
82-
Create Service
83-
</PrimaryButton>
66+
<template #header>
67+
<h2
68+
class="font-semibold text-xl text-gray-800 dark:text-gray-200 leading-tight"
69+
>
70+
Create Service
71+
</h2>
72+
</template>
73+
74+
<template #actions>
75+
<SecondaryButton @click="openTemplatePicker"
76+
>Use a Template</SecondaryButton
77+
>
78+
</template>
79+
80+
<div class="py-12">
81+
<form
82+
class="max-w-7xl mx-auto sm:px-6 lg:px-8"
83+
@submit.prevent="createService"
84+
>
85+
<ActionSection>
86+
<template #title> Service Details </template>
87+
88+
<template #description>
89+
<p>
90+
Select a swarm where the service will be deployed
91+
to.
92+
</p>
93+
<p>
94+
The name of the service can be changed at any time.
95+
Be aware, that the service name in the Swarm cluster
96+
will not be changed.
97+
</p>
98+
99+
<p>
100+
You can isolate containers from each other by using
101+
different networks.
102+
</p>
103+
<p>
104+
Service will be accessible by the internal domain
105+
name to other containers on the same network.
106+
</p>
107+
<p>
108+
You can make certain ports of the containers
109+
accessible from the host network. Please set up the
110+
firewall rule on your host to prevent unwanted
111+
access.
112+
</p>
113+
<p>
114+
If you don't select the Placement Node, the
115+
containers will be able to run on any node of the
116+
Swarm Cluster.
117+
</p>
118+
</template>
119+
120+
<template #content>
121+
<ServiceDetailsForm
122+
v-model="form"
123+
:team="$page.props.auth.user.current_team"
124+
:swarms="swarms"
125+
/>
126+
</template>
127+
</ActionSection>
128+
129+
<DeploymentData
130+
v-model="form.deploymentData"
131+
:networks="networks"
132+
:nodes="nodes"
133+
:errors="form.errors"
134+
:service-name="form.name"
135+
:docker-registries="props.dockerRegistries"
136+
:s3-storages="props.s3Storages"
137+
/>
138+
139+
<div class="flex justify-end">
140+
<PrimaryButton
141+
:class="{ 'opacity-25': form.processing }"
142+
:disabled="form.processing"
143+
>
144+
Create Service
145+
</PrimaryButton>
146+
</div>
147+
</form>
84148
</div>
85-
</form>
86-
</div>
87-
</AppLayout>
149+
</AppLayout>
88150
</template>

0 commit comments

Comments
 (0)