Compare commits
10 Commits
870c36a15d
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 389bc63592 | |||
| 5d5cc18678 | |||
| 93798904d1 | |||
| 2749791eed | |||
| 57dd7d169f | |||
| 9890563dc2 | |||
| f4895eaa03 | |||
| ab5f7c3854 | |||
| 5bfbe6a172 | |||
| 356c1b3295 |
22
.gitea/workflows/deploy.yml
Normal file
22
.gitea/workflows/deploy.yml
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
name: Deploy Application
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
deploy:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Create .env file from Gitea secret
|
||||||
|
run: echo "${{ secrets.BACKEND_ENV }}" > backend/.env
|
||||||
|
|
||||||
|
- name: Build and restart Docker containers
|
||||||
|
run: |
|
||||||
|
docker compose down
|
||||||
|
docker compose build
|
||||||
|
docker compose up -d
|
||||||
@@ -2,9 +2,9 @@ FROM python:3.12-slim
|
|||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
COPY backend/requirements.txt /app/
|
COPY requirements.txt /app/
|
||||||
RUN pip install --no-cache-dir -r requirements.txt
|
RUN pip install --no-cache-dir -r requirements.txt
|
||||||
|
|
||||||
COPY backend /app
|
COPY . /app
|
||||||
|
|
||||||
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
|
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
|
||||||
|
|||||||
@@ -3,16 +3,16 @@ version: "3.9"
|
|||||||
services:
|
services:
|
||||||
backend:
|
backend:
|
||||||
build:
|
build:
|
||||||
context: .
|
context: ./backend
|
||||||
dockerfile: backend/Dockerfile
|
dockerfile: Dockerfile
|
||||||
container_name: my-backend
|
container_name: odoo-hours-backend
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|
||||||
frontend:
|
frontend:
|
||||||
build:
|
build:
|
||||||
context: .
|
context: ./frontend
|
||||||
dockerfile: frontend/Dockerfile
|
dockerfile: Dockerfile
|
||||||
container_name: my-frontend
|
container_name: odoo-hours-frontend
|
||||||
ports:
|
ports:
|
||||||
- "6080:80"
|
- "6080:80"
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
# Etap 1: Build Vue
|
# Etap 1: Build Vue
|
||||||
FROM node:20 AS build
|
FROM node:20 AS build
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY frontend/package*.json ./
|
COPY package*.json ./
|
||||||
RUN npm install
|
RUN npm install
|
||||||
COPY frontend ./
|
COPY . ./
|
||||||
RUN npm run build
|
RUN npm run build
|
||||||
|
|
||||||
# Etap 2: Nginx serwujący Vue + proxy do backendu
|
# Etap 2: Nginx serwujący Vue + proxy do backendu
|
||||||
FROM nginx:alpine
|
FROM nginx:alpine
|
||||||
COPY --from=build /app/dist /usr/share/nginx/html
|
COPY --from=build /app/dist /usr/share/nginx/html/odoo
|
||||||
|
|
||||||
# Konfiguracja Nginx z proxy
|
# Konfiguracja Nginx z proxy
|
||||||
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
||||||
|
|||||||
@@ -1,32 +1,13 @@
|
|||||||
server {
|
server {
|
||||||
listen 80;
|
listen 80;
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
index index.html;
|
||||||
|
|
||||||
# Przekierowanie bez / na /odoo/
|
# Przekierowanie bez / na /odoo/
|
||||||
location = /odoo {
|
location = /odoo {
|
||||||
return 301 /odoo/;
|
return 301 /odoo/;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Serwowanie Vue
|
|
||||||
location /odoo/ {
|
|
||||||
alias /usr/share/nginx/html/;
|
|
||||||
index index.html;
|
|
||||||
try_files $uri $uri/ /odoo/index.html;
|
|
||||||
}
|
|
||||||
|
|
||||||
# no cache index.html
|
|
||||||
location = /odoo/index.html {
|
|
||||||
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
|
||||||
expires 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
# cache JS/CSS/OBRAZY na długo
|
|
||||||
location ~* \.(?:js|css|png|jpg|jpeg|gif|ico|svg|woff2?)$ {
|
|
||||||
add_header Cache-Control "public, max-age=31536000, immutable";
|
|
||||||
access_log off;
|
|
||||||
expires 1y;
|
|
||||||
alias /usr/share/nginx/html/;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Proxy do backendu
|
# Proxy do backendu
|
||||||
location /odoo/api/ {
|
location /odoo/api/ {
|
||||||
proxy_pass http://backend:8000/;
|
proxy_pass http://backend:8000/;
|
||||||
@@ -35,5 +16,23 @@ server {
|
|||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Serwowanie Vue
|
||||||
|
location /odoo/ {
|
||||||
|
try_files $uri $uri/ /odoo/index.html;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Ustawienia cache dla assetów
|
||||||
|
location ~* /odoo/.*\.(?:js|css|png|jpg|jpeg|gif|ico|svg|woff2?)$ {
|
||||||
|
add_header Cache-Control "public, max-age=31536000, immutable";
|
||||||
|
access_log off;
|
||||||
|
expires 1y;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Brak cache'owania dla pliku index.html
|
||||||
|
location = /odoo/index.html {
|
||||||
|
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
||||||
|
expires 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,13 +6,13 @@
|
|||||||
</button>
|
</button>
|
||||||
<div class="dropdown-content">
|
<div class="dropdown-content">
|
||||||
<button
|
<button
|
||||||
v-for="option in attendanceStore.lastThreeMonth"
|
v-for="option in attendanceStore.lastMonths"
|
||||||
:key="option"
|
:key="`${option.year}-${option.month}`"
|
||||||
@click="select(option)"
|
@click="select(option)"
|
||||||
>
|
>
|
||||||
<span class="button-text">
|
<span class="button-text">
|
||||||
<span>{{ utils.getMonthName(option) }}</span>
|
<span>{{ utils.getMonthName(option.month) }}</span>
|
||||||
<span>{{ attendanceStore.year }}</span>
|
<span>{{ option.year }}</span>
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -30,15 +30,13 @@ const showMenu = ref(false)
|
|||||||
const dropdownRef = ref(null)
|
const dropdownRef = ref(null)
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
|
|
||||||
const select = async (newMonth) => {
|
const select = async (option) => {
|
||||||
// console.log('newMonth: ', newMonth)
|
// console.log('newMonth: ', newMonth)
|
||||||
showMenu.value = false
|
showMenu.value = false
|
||||||
loading.value = true
|
loading.value = true
|
||||||
|
|
||||||
const year = attendanceStore.year
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await getData(year, newMonth) // przykładowa data
|
const response = await getData(option.year, option.month) // przykładowa data
|
||||||
attendanceStore.loadFromResponse(response)
|
attendanceStore.loadFromResponse(response)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
error.value = 'Błąd pobierania danych.'
|
error.value = 'Błąd pobierania danych.'
|
||||||
|
|||||||
@@ -12,7 +12,8 @@ export const useAttendanceStore = defineStore('attendanceStore', () => {
|
|||||||
const days = ref([])
|
const days = ref([])
|
||||||
|
|
||||||
// const lastThreeMonth = ['lipiec', 'czerwiec', 'maj']
|
// const lastThreeMonth = ['lipiec', 'czerwiec', 'maj']
|
||||||
const lastThreeMonth = utils.getLastMonths(new Date().getMonth() + 1, 5)
|
// const lastMonths = ref(utils.getLastMonthsWithYear(5))
|
||||||
|
const lastMonths = utils.getLastMonthsWithYear(5)
|
||||||
const sumOfHours = computed(() => days.value[days.value.length - 1]?.accumulatedHours || 0)
|
const sumOfHours = computed(() => days.value[days.value.length - 1]?.accumulatedHours || 0)
|
||||||
const workedHours = computed(() => sumOfHours.value - holidayHours.value - sickHours.value)
|
const workedHours = computed(() => sumOfHours.value - holidayHours.value - sickHours.value)
|
||||||
const overtimeHours = computed(() => days.value[days.value.length - 1]?.balanceHours || 0)
|
const overtimeHours = computed(() => days.value[days.value.length - 1]?.balanceHours || 0)
|
||||||
@@ -115,7 +116,7 @@ export const useAttendanceStore = defineStore('attendanceStore', () => {
|
|||||||
holidayHours,
|
holidayHours,
|
||||||
sickHours,
|
sickHours,
|
||||||
toGoHours,
|
toGoHours,
|
||||||
lastThreeMonth,
|
lastMonths,
|
||||||
// actions
|
// actions
|
||||||
loadFromResponse,
|
loadFromResponse,
|
||||||
updateDay,
|
updateDay,
|
||||||
|
|||||||
@@ -253,6 +253,23 @@ function calculateMonthFromDay(startDay, days) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getLastMonthsWithYear(count) {
|
||||||
|
const result = []
|
||||||
|
const today = new Date()
|
||||||
|
let year = today.getFullYear()
|
||||||
|
let month = today.getMonth() // 0-11
|
||||||
|
|
||||||
|
for (let i = 0; i < count; i++) {
|
||||||
|
result.push({ year: year, month: month + 1 })
|
||||||
|
month--
|
||||||
|
if (month < 0) {
|
||||||
|
month = 11
|
||||||
|
year--
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
getDayOfWeek,
|
getDayOfWeek,
|
||||||
extractTimeFromDateString,
|
extractTimeFromDateString,
|
||||||
@@ -267,4 +284,5 @@ export default {
|
|||||||
getMonthNumber,
|
getMonthNumber,
|
||||||
getMonthName,
|
getMonthName,
|
||||||
daysOfWeek,
|
daysOfWeek,
|
||||||
|
getLastMonthsWithYear,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ onMounted(async () => {
|
|||||||
loading.value = true
|
loading.value = true
|
||||||
const currentDate = new Date()
|
const currentDate = new Date()
|
||||||
try {
|
try {
|
||||||
const response = await getData(currentDate.getFullYear(), currentDate.getMonth())
|
const response = await getData(currentDate.getFullYear(), currentDate.getMonth() + 1)
|
||||||
input.value = response
|
input.value = response
|
||||||
attendanceStore.loadFromResponse(response)
|
attendanceStore.loadFromResponse(response)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|||||||
Reference in New Issue
Block a user