Skip to content

Commit

Permalink
feat: Add new pages for index, images, stacks, volumes, and networks
Browse files Browse the repository at this point in the history
  • Loading branch information
tacxou committed Jul 6, 2024
1 parent 115ba11 commit bce4b10
Show file tree
Hide file tree
Showing 21 changed files with 542 additions and 0 deletions.
2 changes: 2 additions & 0 deletions apps/web/src/assets/styles/global.sass
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
@import './variables.sass'
@import './quasar-custom.sass'
2 changes: 2 additions & 0 deletions apps/web/src/assets/styles/quasar-custom.sass
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.rounded-borders
border-radius: 4px !important
Empty file.
60 changes: 60 additions & 0 deletions apps/web/src/components/layout/default/drawer.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<template lang="pug">
q-drawer.q-py-md.q-pl-md(
v-model="drawer"
side="left" :mini="true" :breakpoint="0" :mini-width="72"
:style="{background: $q.dark.isActive ? 'var(--q-dark-page) !important' : ''}"
persistent
)
q-card.full-height.bg-transparent(flat)
.row.no-wrap.column.full-height
q-card.bg-primary.q-mb-md(flat)
q-toolbar.q-px-none
q-btn.rounded-borders(icon="mdi-docker" color="white" flat stretch)
q-card.bg-primary.full-height.overflow-y-auto(flat)
q-list
q-item.rounded-borders(v-for="item in list" clickable :to="item.to" :key="item.name" active-class="text-orange")
q-item-section(avatar)
q-icon(:name="item.icon || 'mdi-square-rounded'")
q-tooltip.text-body2(anchor="center left" self="center right") {{ item.name }}
q-space
q-list
</template>

<script lang="ts" setup>
import { inject, ref } from 'vue'
const drawer = inject('drawer')
const list = ref([
{
name: 'Tableau de bord',
icon: 'mdi-view-dashboard',
to: '/',
},
{
name: 'Stacks',
icon: 'mdi-layers-outline',
to: '/stacks',
},
{
name: 'Containers',
icon: 'mdi-cube',
to: '/containers',
},
{
name: 'Images',
icon: 'mdi-image-text',
to: '/images',
},
{
name: 'Networks',
icon: 'mdi-lan-connect',
to: '/networks',
},
{
name: 'Volumes',
icon: 'mdi-database-outline',
to: '/volumes',
},
])
</script>
7 changes: 7 additions & 0 deletions apps/web/src/components/layout/default/footer.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<template lang="pug">
q-footer.q-pa-md.bg-transparent
q-bar.bg-primary.rounded-borders
div test
q-space
div lang
</template>
32 changes: 32 additions & 0 deletions apps/web/src/components/layout/default/header.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<template lang="pug">
q-header.q-pa-md.bg-white(:style="{background: $q.dark.isActive ? 'var(--q-dark-page) !important' : '', border: $q.dark.isActive ? '1px solid var(--q-dark-page) !important' : ''}")
.row
q-card.bg-primary.q-mr-md(v-if="$q.screen.width <= 700 && !drawer" flat)
q-toolbar.q-px-none
q-btn.rounded-borders(icon="mdi-docker" color="white" flat stretch)
.col
q-card.bg-primary(flat)
.row.no-wrap
q-toolbar
q-toolbar-title(v-if="$q.screen.width > 700") Dockilot
q-btn(v-else icon="mdi-menu" color="white" @click="drawer = !drawer" flat dense)
q-space
q-toolbar
//- q-input.block.full-width(
//- v-model="search"
//- placeholder="Rechercher un personnage, un item, ..." color="white"
//- dense filled
//- )
q-toolbar.q-gutter-sm
q-space
q-btn(icon="mdi-theme-light-dark" @click="$q.dark.toggle()" flat dense)
q-btn(icon="mdi-account" flat dense)
</template>

<script lang="ts" setup>
import { inject } from 'vue'
import { useQuasar } from 'quasar'
const $q = useQuasar()
const drawer = inject('drawer')
</script>
14 changes: 14 additions & 0 deletions apps/web/src/components/page/characters/avatar.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<template lang="pug">
.col-3
q-card.bg-primary.q-mb-md(flat)
q-img(src="/img/New_Store_Huntress.webp")
.absolute-bottom.full-width
q-toolbar
q-toolbar-title La Chasseuse
q-card.bg-primary(flat)
.row
.col(v-for="i in 3")
q-btn.fit(flat)
q-avatar(size="128px")
q-img(src="/img/IconPerks_hexHuntressLullaby.webp")
</template>
80 changes: 80 additions & 0 deletions apps/web/src/components/page/characters/infos.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<template lang="pug">
.col-9.flex.relative.column
.row.q-col-gutter-md.q-mb-md
div
q-card.bg-secondary.full-height.content-center(flat)
q-btn.full-height(color="white" icon="mdi-reply" flat)
.col
q-card.bg-primary.q-pa-md(flat)
div Anna
div
q-card.bg-primary.q-pa-sm.full-height.content-center(flat)
//- q-icon.q-mr-sm(name="mdi-radar" size="sm")
span Grand
div
q-card.bg-primary.q-pa-sm.full-height.content-center(flat)
q-icon.q-mr-sm(name="mdi-radar" size="sm")
span 20m
div
q-card.bg-primary.q-pa-sm.full-height.content-center(flat)
q-icon.q-mr-sm(name="mdi-run-fast" size="sm")
span 4.4 m/s
div
q-card.bg-primary.q-pa-sm.full-height.content-center(flat)
q-icon(name="mdi-gender-female" size="md")
div
q-card.bg-warning.full-height.content-center(flat)
q-btn.full-height(color="white" flat) Voir en plus +
.col.q-mb-md
.row.full-height
.col-3
q-card.bg-primary.full-height.q-mr-md(flat)
div
q-img.fit(src="/img/IconPowers_huntingHatchets.webp" fit="contain")
q-toolbar.absolute-bottom.text-center
q-toolbar-title Hunting Hatchets
.col
q-card.bg-primary.full-height(flat)
q-card-section.q-pa-md.text-center
.text-h6 A propos
q-card-section.q-pa-md
div Une tueuse à distance capable de lancer des <b>Hachettes de chasse</b> sur les survivants pour les blesser de loin.<br><br>Ses compétences personnelles <b>Prédation</b>, <b>Instinct territorial</b> et <b>Sort : Berceuse de la Chasseuse</b> lui permettent de mettre les survivants sous pression au moyen d'une meilleure lecture de carte et de compétences de poursuite améliorées.
q-card.bg-primary(flat)
q-carousel.bg-transparent(
v-model="slide"
transition-prev="slide-right"
transition-next="slide-left"
swipeable
animated
control-color="warning"
infinite
padding
arrows
height="200px"
class="rounded-borders"
)
q-carousel-slide(:name="1" class="column no-wrap")
.row.fit.justify-start.items-center.q-gutter-xs.q-col-gutter.no-wrap
q-img.rounded-borders.col.full-height(src="/img/IconPerks_beastOfPrey.webp")
q-img.rounded-borders.col.full-height(src="/img/IconPerks_beastOfPrey.webp")
q-img.rounded-borders.col.full-height(src="/img/IconPerks_beastOfPrey.webp")
q-img.rounded-borders.col.full-height(src="/img/IconPerks_beastOfPrey.webp")
q-carousel-slide(:name="2" class="column no-wrap")
.row.fit.justify-start.items-center.q-gutter-xs.q-col-gutter.no-wrap
q-img.rounded-borders.col.full-height(src="/img/IconPerks_beastOfPrey.webp")
q-img.rounded-borders.col.full-height(src="/img/IconPerks_beastOfPrey.webp")
q-img.rounded-borders.col.full-height(src="/img/IconPerks_beastOfPrey.webp")
q-img.rounded-borders.col.full-height(src="/img/IconPerks_beastOfPrey.webp")
q-carousel-slide(:name="3" class="column no-wrap")
.row.fit.justify-start.items-center.q-gutter-xs.q-col-gutter.no-wrap
q-img.rounded-borders.col.full-height(src="/img/IconPerks_beastOfPrey.webp")
q-img.rounded-borders.col.full-height(src="/img/IconPerks_beastOfPrey.webp")
q-img.rounded-borders.col.full-height(src="/img/IconPerks_beastOfPrey.webp")
q-img.rounded-borders.col.full-height(src="/img/IconPerks_beastOfPrey.webp")
</template>

<script lang="ts" setup>
import { ref } from 'vue'
const slide = ref(1)
</script>
6 changes: 6 additions & 0 deletions apps/web/src/composables/useDebug.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export function useDebug() {
const route = useRoute()
const debug = process.env.NODE_ENV === 'development' || /yes|true|1|on/.test(`${route.query.debug}`)

return { debug }
}
19 changes: 19 additions & 0 deletions apps/web/src/layouts/default.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<template lang="pug">
q-layout(view="lHh Lpr lff")
q-custom-layout-default-header
q-custom-layout-default-drawer
q-page-container.q-mx-md
nuxt-page
q-custom-layout-default-footer
</template>

<script lang="ts" setup>
import { provide, ref } from 'vue'
import { useQuasar } from 'quasar'
const $q = useQuasar()
const drawer = ref($q.screen.width > 700)
provide('drawer', drawer)
</script>
34 changes: 34 additions & 0 deletions apps/web/src/pages/containers.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<template lang="pug">
q-page
.row.q-col-gutter-md
.col-3
q-card(flat)
q-list
q-item(v-for="container in containers" clickable :to="`/containers/${container.Id}`")
q-item-section(avatar)
q-icon(name="mdi-cube" :color="state(container)")
q-item-section
div.text-body2(v-text="container.Names[0]")
.col
nuxt-page
</template>

<script lang="ts" setup>
import { ref } from 'vue'
const containers = ref<any[]>([])
const { data } = await useHttp<any>('/docker/containers')
containers.value = data.value.data
function state(container: any) {
switch (container.State) {
case 'running':
return 'green'
case 'exited':
return 'red'
default:
return 'grey'
}
}
</script>
64 changes: 64 additions & 0 deletions apps/web/src/pages/containers/[id].vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<template lang="pug">
div
q-card(flat)
q-toolbar.bg-primary.q-pa-none(style="height:48px")
q-btn.icon(stretch icon='mdi-arrow-left' flat :to='`/containers`')
q-separator.q-mr-sm(vertical)
q-toolbar-title.q-pa-none
q-icon(left name='mdi-cube' :color='stateColor' size='md')
span(v-text='container.Name')
q-space
q-btn.icon(flat :to='`/containers/${container.Id}/console`' icon='mdi-console' round)
q-btn.icon(flat :to='`/containers/${container.Id}/logs`' icon='mdi-file-document' round)
q-btn.icon(flat :to='`/containers/${container.Id}/stats`' icon='mdi-chart-areaspline' round)
q-separator.q-ml-sm(vertical)
q-btn.icon(flat @click="action" :icon='stateIcon' stretch)

nuxt-page

q-expansion-item.bg-blue-grey-10(v-if='debug' label='Debug' icon='mdi-bug' dark dense)
q-card.overflow-auto.bg-blue-grey-8.text-white(:style='{maxHeight: "250px", height: "250px"}')
q-card-section.q-pa-xs
pre.q-ma-none(v-html='JSON.stringify(container, null, 2)')
</template>

<script lang="ts" setup>
import { computed, ref } from 'vue'
const $route = useRoute()
const { debug } = useDebug()
const container = ref<any>({})
const { data } = await useHttp<any>(`/docker/containers/` + $route.params.id)
container.value = data.value.data
const stateColor = computed(() => {
switch (container.value.State.Status) {
case 'running':
return 'green'
case 'exited':
return 'red'
default:
return 'grey'
}
})
const stateIcon = computed(() => {
switch (container.value.State.Status) {
case 'running':
return 'mdi-stop'
case 'exited':
return 'mdi-play'
default:
return 'mdi-pause'
}
})
async function action() {
const action = container.value.State.Status === 'running' ? 'stop' : 'start'
await useHttp<any>(`/docker/containers/${container.value.Id}/${action}`, { method: 'POST' })
}
</script>
Loading

0 comments on commit bce4b10

Please sign in to comment.