Compare commits

...

7 Commits

Author SHA1 Message Date
Julien Aldon
84369911cd add restart always to nginx service
All checks were successful
Deploy Bookshelf / deploy (push) Successful in 6s
2026-01-14 13:49:17 +01:00
Julien Aldon
443cfd7615 add front responsiveness for phone
All checks were successful
Deploy Bookshelf / deploy (push) Successful in 20s
2026-01-13 17:02:16 +01:00
Julien Aldon
ed22dfd412 fix docker-compose version
All checks were successful
Deploy Bookshelf / deploy (push) Successful in 36s
2026-01-13 16:03:08 +01:00
Julien Aldon
aec31fbd06 fix docker-compose version
Some checks failed
Deploy Bookshelf / deploy (push) Failing after 5s
2026-01-13 15:59:28 +01:00
Julien Aldon
2e5aeb46ab fix docker-compose prod ROOT_FQDN var
All checks were successful
Deploy Bookshelf / deploy (push) Successful in 36s
2026-01-13 15:57:07 +01:00
Julien Aldon
b718865030 add ROOT_FQDN env variable
Some checks failed
Deploy Bookshelf / deploy (push) Failing after 5s
2026-01-13 15:55:32 +01:00
Julien Aldon
e8208363c0 fix front config.js
All checks were successful
Deploy Bookshelf / deploy (push) Successful in 19s
2026-01-13 15:28:26 +01:00
9 changed files with 128 additions and 16 deletions

52
docker-compose.dev.yml Normal file
View File

@@ -0,0 +1,52 @@
version: "3.9"
services:
back:
image: python:3.10
working_dir: /code
volumes:
- ./back:/code
command: >
sh -c "pip install -r requirements.txt &&
uvicorn main:app --host 0.0.0.0 --port 8000 --reload"
environment:
SERVICE_ORIGIN: ${SERVICE_ORIGIN}
DB_HOST: database
MARIADB_USER: ${MARIADB_USER}
MARIADB_PASSWORD: ${MARIADB_PASSWORD}
MARIADB_DATABASE: ${MARIADB_DATABASE}
SERVICE_SECRET_KEY: ${SERVICE_SECRET_KEY}
ports:
- "8000:8000"
depends_on:
- database
front:
image: node:19.1-alpine
working_dir: /app
volumes:
- ./front:/app
command: sh -c "npm install && npm run serve"
ports:
- "8080:8080"
environment:
VUE_APP_ROOT_FQDN: ${SERVICE_ROOT_FQDN}
depends_on:
- back
database:
image: mariadb
restart: always
environment:
MARIADB_USER: ${MARIADB_USER}
MARIADB_PASSWORD: ${MARIADB_PASSWORD}
MARIADB_ROOT_PASSWORD: ${MARIADB_ROOT_PASSWORD}
MARIADB_DATABASE: ${MARIADB_DATABASE}
volumes:
- db:/var/lib/mysql
- ./back/db/:/docker-entrypoint-initdb.d/
ports:
- "3306:3306"
volumes:
db:

View File

@@ -1,9 +1,12 @@
version: "2" version: "3.9"
services: services:
nginx: nginx:
restart: always
build: build:
context: . context: .
dockerfile: front/Dockerfile dockerfile: front/Dockerfile
args:
VUE_APP_ROOT_FQDN: ${SERVICE_ROOT_FQDN}
ports: ports:
- 80:80 - 80:80
depends_on: depends_on:
@@ -32,6 +35,7 @@ services:
MARIADB_PASSWORD: ${MARIADB_PASSWORD} MARIADB_PASSWORD: ${MARIADB_PASSWORD}
MARIADB_ROOT_PASSWORD: ${MARIADB_ROOT_PASSWORD} MARIADB_ROOT_PASSWORD: ${MARIADB_ROOT_PASSWORD}
MARIADB_DATABASE: ${MARIADB_DATABASE} MARIADB_DATABASE: ${MARIADB_DATABASE}
ROOT_FQDN: ${ROOT_FQDN}
volumes: volumes:
- db:/var/lib/mysql - db:/var/lib/mysql
- ./back/db/:/docker-entrypoint-initdb.d/ - ./back/db/:/docker-entrypoint-initdb.d/

View File

@@ -2,6 +2,9 @@ FROM node:19.1-alpine AS build
WORKDIR /app WORKDIR /app
ARG VUE_APP_ROOT_FQDN
ENV VUE_APP_ROOT_FQDN=$VUE_APP_ROOT_FQDN
COPY front/package.json front/package-lock.json /app/ COPY front/package.json front/package-lock.json /app/
RUN npm install RUN npm install

View File

@@ -85,7 +85,6 @@ body {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
margin-top: 5rem;
} }
.router { .router {

View File

@@ -26,7 +26,7 @@
.page { .page {
border: none; border: none;
padding: 1rem; padding: 0.5rem;
margin: 0.2rem; margin: 0.2rem;
} }
@@ -34,6 +34,7 @@ footer {
display: flex; display: flex;
padding: 0.2rem; padding: 0.2rem;
align-items: center; align-items: center;
max-width: 100%;
} }

View File

@@ -37,7 +37,7 @@ export default {
.search { .search {
display: flex; display: flex;
min-width: 95%; width: 100vw;
margin-top: 1rem; margin-top: 1rem;
margin-bottom: 1rem; margin-bottom: 1rem;
} }

View File

@@ -1,7 +1,7 @@
<template> <template>
<table> <table>
<tr> <tr>
<th v-bind:style="{ 'min-width': this.width }" v-for="head in headings" :key="head">{{ head }}</th> <th v-for="head in headings" :key="head">{{ head }}</th>
</tr> </tr>
<slot></slot> <slot></slot>
</table> </table>
@@ -19,5 +19,25 @@ export default {
<style scoped> <style scoped>
th { th {
text-align: left; text-align: left;
width: 20%;
} }
tr {
display: flex;
flex-direction: row;
justify-content: flex-start;
}
table {
display: flex;
flex-direction: column;
}
@media (max-width: 30em) {
tr {
width: 100vw;
}
}
</style> </style>

View File

@@ -1,5 +1,4 @@
// const ROOT_FQDN = 'https://bookshelf.aldon.fr/api'; const ROOT_FQDN = process.env.VUE_APP_ROOT_FQDN
const ROOT_FQDN = 'http://localhost:8000/api';
export { export {
ROOT_FQDN ROOT_FQDN

View File

@@ -20,7 +20,7 @@
</button> </button>
</form> </form>
<SearchHeader page="Books" @changeSearch="(s) => {editSearch(s)}"/> <SearchHeader page="Books" @changeSearch="(s) => {editSearch(s)}"/>
<TableView ref="table" :headings="headings" width="15rem"> <TableView ref="table" :headings="headings">
<tr v-for="book in this.$store.getters.getBooks" :key="book"> <tr v-for="book in this.$store.getters.getBooks" :key="book">
<td v-if="editRow === book.biblio_Index"> <td v-if="editRow === book.biblio_Index">
<DropDown <DropDown
@@ -28,7 +28,7 @@
field="Auteur" field="Auteur"
:inputValue="book.Auteur" :inputValue="book.Auteur"
@selected="(n) => {formEdit.author = n}" @selected="(n) => {formEdit.author = n}"
/> />
</td> </td>
<td v-else>{{ book.Auteur }}</td> <td v-else>{{ book.Auteur }}</td>
<td v-if="editRow === book.biblio_Index"> <td v-if="editRow === book.biblio_Index">
@@ -37,7 +37,7 @@
field="Titre" field="Titre"
:inputValue="book.Titre" :inputValue="book.Titre"
@selected="(n) => {formEdit.title = n}" @selected="(n) => {formEdit.title = n}"
/> />
</td> </td>
<td v-else>{{ book.Titre }}</td> <td v-else>{{ book.Titre }}</td>
<td v-if="editRow === book.biblio_Index"> <td v-if="editRow === book.biblio_Index">
@@ -46,7 +46,7 @@
field="Editeur" field="Editeur"
:inputValue="book.Editeur" :inputValue="book.Editeur"
@selected="(n) => {formEdit.editor = n}" @selected="(n) => {formEdit.editor = n}"
/> />
</td> </td>
<td v-else>{{ book.Editeur }}</td> <td v-else>{{ book.Editeur }}</td>
<td v-if="editRow === book.biblio_Index"> <td v-if="editRow === book.biblio_Index">
@@ -55,7 +55,7 @@
field="Type" field="Type"
:inputValue="book.Type" :inputValue="book.Type"
@selected="(n) => {formEdit.type = n}" @selected="(n) => {formEdit.type = n}"
/> />
</td> </td>
<td v-else>{{ book.Type }}</td> <td v-else>{{ book.Type }}</td>
<div class="button-panel"> <div class="button-panel">
@@ -87,7 +87,7 @@ export default {
}, },
data() { data() {
return { return {
headings: ['Author', 'Title', 'Editor', 'Type'], headings: ['Author', 'Title', 'Editor', 'Type', 'Control'],
editMode: false, editMode: false,
editRow: undefined, editRow: undefined,
addMode: false, addMode: false,
@@ -188,11 +188,45 @@ export default {
</script> </script>
<style scoped> <style scoped>
main { main {
max-width: 60.5vw; width: 80vw
} }
td input { header {
width: 14.5rem; width: 80vw;
}
tr {
display: flex;
flex-direction: row;
justify-content: flex-start;
width: 80vw;
align-items: center;
}
td {
width: 20%;
}
.button-panel {
width: 20%;
display: flex;
flex-direction: flex-end;
}
@media (max-width: 30em) {
main {
width: 100vw;
}
tr {
width: 100vw;
}
td {
overflow-x: hidden;
white-space: nowrap
}
} }
@keyframes lineInsertedIn { @keyframes lineInsertedIn {