Skip to content

Commit 7932ea6

Browse files
refactor: standardize checkbox component
1 parent b80ee3c commit 7932ea6

4 files changed

Lines changed: 67 additions & 7 deletions

File tree

‎web/src/components/applications/DomainsPanel.vue‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<script setup lang="ts">
22
import { onMounted, ref, watch } from "vue";
33
import BaseModal from "../ui/BaseModal.vue";
4+
import Checkbox from "../ui/Checkbox.vue";
45
import { api, RequestError } from "../../composables/useApi";
56
import { useToast } from "../../composables/useToast";
67
@@ -111,8 +112,8 @@ onMounted(load);
111112
<label v-if="props.services.length">Serviço<select v-model="serviceName" required><option v-for="service in props.services" :key="service" :value="service">{{ service }}</option></select></label>
112113
<label v-else>Serviço<input v-model="serviceName" required placeholder="web" /></label>
113114
<label>Porta<input v-model.number="targetPort" type="number" min="1" max="65535" required /></label>
114-
<label class="checkbox"><input v-model="httpsEnabled" type="checkbox" /> HTTPS automático</label>
115-
<label class="checkbox"><input v-model="redirectHttps" type="checkbox" /> Redirecionar HTTP</label>
115+
<Checkbox v-model="httpsEnabled" label="HTTPS automático" />
116+
<Checkbox v-model="redirectHttps" label="Redirecionar HTTP" />
116117
</form>
117118
<template #footer><button class="secondary" type="button" :disabled="saving" @click="addOpen = false">Cancelar</button><button class="primary" form="add-domain-form" type="submit" :disabled="saving">{{ saving ? "Salvando…" : "Adicionar domínio" }}</button></template>
118119
</BaseModal>
@@ -124,7 +125,7 @@ onMounted(load);
124125
.domain-form { display: grid; grid-template-columns: minmax(220px, 1.5fr) minmax(140px, 1fr) 110px; gap: 14px; align-items: end; }
125126
.domain-form label { display: grid; gap: 7px; color: #b9bec9; font-size: 12px; }
126127
.domain-form input, .domain-form select { min-width: 0; border: 1px solid #343842; border-radius: 7px; padding: 10px 11px; background: #17191e; color: #e7e9ee; }
127-
.domain-form .checkbox { display: flex; align-items: center; gap: 7px; }
128+
.domain-form .checkbox { display: flex; align-items: center; gap: 7px; font-size: 14px; line-height: 1.2; }
128129
.domain-form .checkbox input { accent-color: #e8f55b; }
129130
.domain-list { display: grid; gap: 10px; margin: 0; padding: 0; list-style: none; }
130131
.domain-list li { display: grid; gap: 10px; padding: 16px; border: 1px solid #2a2d34; border-radius: 10px; background: #17191e; }

‎web/src/components/applications/EnvironmentVariablesEditor.vue‎

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<script setup lang="ts">
22
import { ref } from "vue";
3+
import Checkbox from "../ui/Checkbox.vue";
34
type Variable = {
45
key: string;
56
value: string;
@@ -46,9 +47,7 @@ function valueFor(item: DetectedVariable) { return props.modelValue.find((variab
4647
placeholder="Valor"
4748
:type="draft.secret ? 'password' : 'text'"
4849
/>
49-
<label class="check"
50-
><input v-model="draft.secret" type="checkbox" /> Secret</label
51-
>
50+
<Checkbox v-model="draft.secret" label="Secret" />
5251
<button class="secondary" type="button" @click="add">Adicionar</button>
5352
</div>
5453
<p v-if="!modelValue.length" class="muted">Nenhuma variável configurada.</p>

‎web/src/components/applications/LogsPanel.vue‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import { nextTick, onMounted, onUnmounted, ref, watch } from "vue";
33
import { api } from "../../composables/useApi";
44
import { useToast } from "../../composables/useToast";
5+
import Checkbox from "../ui/Checkbox.vue";
56
67
const props = defineProps<{ applicationId: number }>();
78
const toast = useToast();
@@ -55,7 +56,7 @@ onUnmounted(stopFollowing);
5556
<template>
5657
<section class="logs-panel">
5758
<div class="section-head"><div><p class="kicker">LOGS</p><h2>Saída operacional</h2><p class="muted">{{ connected ? "Conectado em tempo real" : "Histórico do serviço" }}</p></div><div class="log-actions"><button class="ghost" type="button" :disabled="!logs" @click="copyLogs">Copiar</button><button class="ghost" type="button" :disabled="!logs" @click="downloadLogs">Baixar</button><button class="ghost" type="button" :disabled="!logs" @click="logs = ''">Limpar</button><button class="secondary" type="button" :class="{ active: following }" @click="toggleFollowing">{{ following ? "Pausar" : "Acompanhar" }}</button></div></div>
58-
<div class="logs-toolbar"><label>Serviço<select v-model="service"><option v-for="item in services" :key="item" :value="item">{{ item }}</option></select></label><label>Linhas<select v-model.number="tail"><option :value="100">100</option><option :value="500">500</option><option :value="1000">1000</option></select></label><label>Buscar<input v-model="query" type="search" placeholder="Filtrar linhas" /></label><label class="checkbox"><input v-model="autoScroll" type="checkbox" /> Auto-scroll</label><button class="ghost" type="button" @click="loadLogs">Atualizar</button></div>
59+
<div class="logs-toolbar"><label>Serviço<select v-model="service"><option v-for="item in services" :key="item" :value="item">{{ item }}</option></select></label><label>Linhas<select v-model.number="tail"><option :value="100">100</option><option :value="500">500</option><option :value="1000">1000</option></select></label><label>Buscar<input v-model="query" type="search" placeholder="Filtrar linhas" /></label><Checkbox v-model="autoScroll" label="Auto-scroll" /><button class="ghost" type="button" @click="loadLogs">Atualizar</button></div>
5960
<pre ref="viewer" class="logs-viewer" :aria-busy="loading">{{ (logs.split("\n").filter((line) => !query || line.toLowerCase().includes(query.toLowerCase())).join("\n")) || "Nenhum log disponível para este serviço." }}</pre>
6061
</section>
6162
</template>

‎web/src/components/ui/Checkbox.vue‎

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<script setup lang="ts">
2+
defineProps<{
3+
modelValue: boolean;
4+
label: string;
5+
disabled?: boolean;
6+
}>();
7+
8+
const emit = defineEmits<{ "update:modelValue": [value: boolean] }>();
9+
</script>
10+
11+
<template>
12+
<label class="checkbox-control" :class="{ disabled }">
13+
<input
14+
type="checkbox"
15+
:checked="modelValue"
16+
:disabled="disabled"
17+
@change="emit('update:modelValue', ($event.target as HTMLInputElement).checked)"
18+
/>
19+
<span>{{ label }}</span>
20+
</label>
21+
</template>
22+
23+
<style scoped>
24+
.checkbox-control {
25+
display: inline-flex;
26+
align-items: center;
27+
gap: 8px;
28+
margin: 0;
29+
color: #b9bec9;
30+
cursor: pointer;
31+
font-size: 14px;
32+
line-height: 1.2;
33+
}
34+
.checkbox-control.disabled { cursor: not-allowed; opacity: 0.55; }
35+
.checkbox-control input {
36+
appearance: none;
37+
width: 48px;
38+
height: 48px;
39+
flex: 0 0 48px;
40+
margin: 0;
41+
padding: 0;
42+
border: 1px solid #454a55;
43+
border-radius: 7px;
44+
background: #191c21;
45+
cursor: inherit;
46+
}
47+
.checkbox-control input:checked {
48+
border-color: #e8f55b;
49+
background-color: #e8f55b;
50+
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='m5 12 4 4L19 6' fill='none' stroke='%23151616' stroke-linecap='round' stroke-linejoin='round' stroke-width='3'/%3E%3C/svg%3E");
51+
background-position: center;
52+
background-repeat: no-repeat;
53+
background-size: 23px;
54+
}
55+
.checkbox-control input:focus-visible {
56+
outline: 2px solid #e8f55b;
57+
outline-offset: -2px;
58+
}
59+
</style>

0 commit comments

Comments
 (0)