Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@ build
js/templates.js
js/quicknotes-dashboard.js*
js/quicknotes-talk.js*
js/vendor
css/vendor
node_modules
vendor
translationfiles/
translationtool.phar
translationtool.phar

# Docker dev environment
.env
*.log
12 changes: 7 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -58,26 +58,28 @@ l10n-deps:
deps:
mkdir -p vendor
mkdir -p js/vendor
mkdir -p css/vendor
rm -rf js/vendor/*
npm i
cp node_modules/handlebars/dist/handlebars.js js/vendor/
cp node_modules/isotope-layout/dist/isotope.pkgd.js js/vendor/
cp node_modules/medium-editor/dist/js/medium-editor.js js/vendor/
cp node_modules/medium-editor/dist/css/medium-editor.css vendor/
cp node_modules/medium-editor/dist/css/medium-editor.css css/vendor/medium-editor.css
cp node_modules/medium-editor-autolist/dist/autolist.js js/vendor/
cp node_modules/lozad/dist/lozad.js js/vendor/

depsmin:
mkdir -p vendor
mkdir -p js/vendor
mkdir -p css/vendor
rm -rf js/vendor/*
npm i
cp node_modules/handlebars/dist/handlebars.min.js js/vendor/handlebars.js
cp node_modules/isotope-layout/dist/isotope.pkgd.min.js js/vendor/isotope.pkgd.js
cp node_modules/handlebars/dist/handlebars.min.js js/vendor/handlebars.js
cp node_modules/isotope-layout/dist/isotope.pkgd.min.js js/vendor/isotope.pkgd.js
cp node_modules/medium-editor/dist/js/medium-editor.min.js js/vendor/medium-editor.js
cp node_modules/medium-editor/dist/css/medium-editor.min.css vendor/medium-editor.css
cp node_modules/medium-editor/dist/css/medium-editor.min.css css/vendor/medium-editor.css
cp node_modules/medium-editor-autolist/dist/autolist.min.js js/vendor/autolist.js
cp node_modules/lozad/dist/lozad.min.js js/vendor/lozad.js
cp node_modules/lozad/dist/lozad.min.js js/vendor/lozad.js


# Build Rules
Expand Down
11 changes: 11 additions & 0 deletions docker/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
MARIADB_ROOT_PASSWORD=changeme-root
MARIADB_DATABASE=nextcloud
MARIADB_USER=nextcloud
MARIADB_PASSWORD=changeme-db

NEXTCLOUD_HTTP_PORT=8080

NEXTCLOUD_ADMIN_USER=admin
NEXTCLOUD_ADMIN_PASSWORD=changeme-admin
NEXTCLOUD_TRUSTED_DOMAINS=localhost:8080
NEXTCLOUD_OVERWRITEPROTOCOL=http
114 changes: 114 additions & 0 deletions docker/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
# Entorno de desarrollo local (Docker)

Levanta un Nextcloud 32 + MariaDB y monta este repositorio dentro de
`custom_apps/quicknotes` para poder probar la app sin instalar Nextcloud
a mano.

Todo lo necesario para el entorno vive en este directorio:

```
docker/
β”œβ”€β”€ docker-compose.yml
β”œβ”€β”€ .env.example
β”œβ”€β”€ scripts/
β”‚ β”œβ”€β”€ up.sh
β”‚ β”œβ”€β”€ down.sh
β”‚ β”œβ”€β”€ build.sh
β”‚ └── enable-app.sh
└── README.md ← este archivo
```

## Requisitos

- Docker 20.10+ y Docker Compose v2 (o `docker-compose` v1.29+)
- ~2 GB de RAM libres
- Puertos: `8080` (configurable en `.env`)

## Arranque rΓ‘pido

```bash
# 1) Configurar credenciales (la primera vez)
cp .env.example .env
# editar .env si querΓ©s cambiar puertos/contraseΓ±as

# 2) Levantar y habilitar la app
./docker/scripts/up.sh
```

> Nota: el `.env` se mantiene en la raΓ­z del repo para que `docker
> compose` (que busca `.env` relativo al compose) lo encuentre. Si
> preferΓ­s tenerlo todo dentro de `docker/`, movΓ© `.env` tambiΓ©n a esa
> carpeta y borrΓ‘ el `--env-file` que pasa `up.sh`.

El script:
1. Levanta MariaDB y Nextcloud.
2. **Si faltan assets compilados** (`js/templates.js`, `js/vendor/`,
`js/quicknotes-*.js`), corre `./docker/scripts/build.sh`
automΓ‘ticamente usando el servicio `builder` (Node 20) de
docker-compose.
3. Espera a que Nextcloud termine el primer arranque.
4. Pregunta si querΓ©s habilitar Quick notes (responde `s`).

Una vez listo, abrΓ­ <http://localhost:8080> y entrΓ‘ con las credenciales
definidas en `.env` (`NEXTCLOUD_ADMIN_USER` / `NEXTCLOUD_ADMIN_PASSWORD`).

## Compilar assets manualmente

Si tocΓ‘s un `.vue` en `src/components/`, un template Handlebars en
`js/templates/` o un `.js` en `js/`, hay que re-compilar:

```bash
./docker/scripts/build.sh
```

El build se hace dentro del contenedor `quicknotes-builder` (Node 20)
y escribe los artefactos en el host, que ya estΓ‘n montados en
`custom_apps/quicknotes` dentro de Nextcloud. Para que el navegador
tome los cambios, refrescΓ‘ con Ctrl+Shift+R (Nextcloud cachea JS
agresivamente).

## Comandos ΓΊtiles

```bash
# Re-habilitar la app luego de cambios de cΓ³digo PHP/templates
./docker/scripts/enable-app.sh

# Re-compilar assets luego de tocar .vue, .handlebars, .js
./docker/scripts/build.sh

# Entrar al contenedor de Nextcloud
docker exec -it -u www-data quicknotes-app bash

# Ver logs de Nextcloud
docker logs -f quicknotes-app

# Ver logs de la DB
docker logs -f quicknotes-db

# Bajar los contenedores (conservando los datos)
./docker/scripts/down.sh

# Bajar y borrar TODO (DB + archivos de Nextcloud + cachΓ© de npm)
./docker/scripts/down.sh --purge
```

## CΓ³mo funciona

- `docker-compose.yml` define tres servicios: `db` (MariaDB 11.4),
`app` (Nextcloud 32) y `builder` (Node 20, para compilar assets).
- El directorio raΓ­z del repo se monta como volumen en
`/var/www/html/custom_apps/quicknotes` (los volΓΊmenes del compose
usan `../` para salir de `docker/` y montar el proyecto completo).
- Los datos persistentes (DB + `data/`, `config/`, `apps/` no montados)
viven en los volΓΊmenes `quicknotes_db`, `quicknotes_nc` y
`quicknotes_npm_cache`.

## Limitaciones

- El `info.xml` declara la app para Nextcloud 32. Si necesitΓ‘s otra
versiΓ³n, cambiΓ‘ el tag de la imagen en `docker-compose.yml` (p. ej.
`nextcloud:31`).
- SELinux en Enforcing requiere el sufijo `:z` en el bind mount (ya
estΓ‘ configurado). Si tu distro no usa SELinux podΓ©s sacarlo.
- El bundle Vue de dashboard pesa ~3 MB (warning de webpack). Es
tamaΓ±o aceptable para dev; la app oficial lo reduce con code-split.
64 changes: 64 additions & 0 deletions docker/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
name: quicknotes

services:
db:
image: mariadb:11.4
container_name: quicknotes-db
restart: unless-stopped
command: --transaction-isolation=READ-COMMITTED --log-bin=binlog --binlog-format=ROW
environment:
MARIADB_ROOT_PASSWORD: ${MARIADB_ROOT_PASSWORD}
MARIADB_DATABASE: ${MARIADB_DATABASE}
MARIADB_USER: ${MARIADB_USER}
MARIADB_PASSWORD: ${MARIADB_PASSWORD}
volumes:
- db:/var/lib/mysql
healthcheck:
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
interval: 10s
timeout: 5s
retries: 10

app:
image: nextcloud:32
container_name: quicknotes-app
restart: unless-stopped
depends_on:
db:
condition: service_healthy
ports:
- "${NEXTCLOUD_HTTP_PORT}:80"
environment:
MYSQL_HOST: db
MYSQL_DATABASE: ${MARIADB_DATABASE}
MYSQL_USER: ${MARIADB_USER}
MYSQL_PASSWORD: ${MARIADB_PASSWORD}
NEXTCLOUD_ADMIN_USER: ${NEXTCLOUD_ADMIN_USER}
NEXTCLOUD_ADMIN_PASSWORD: ${NEXTCLOUD_ADMIN_PASSWORD}
NEXTCLOUD_TRUSTED_DOMAINS: ${NEXTCLOUD_TRUSTED_DOMAINS}
NEXTCLOUD_OVERWRITEPROTOCOL: ${NEXTCLOUD_OVERWRITEPROTOCOL}
volumes:
- nc:/var/www/html
- ../:/var/www/html/custom_apps/quicknotes:z
healthcheck:
test: ["CMD", "curl", "-fsS", "http://localhost/status.php"]
interval: 30s
timeout: 10s
retries: 5

builder:
image: node:20-bookworm
container_name: quicknotes-builder
working_dir: /app
volumes:
- ../:/app:z
- npm_cache:/root/.npm
command: ["sh", "-c", "echo 'Use docker/scripts/build.sh to trigger the build' && sleep infinity"]

volumes:
db:
name: quicknotes_db
nc:
name: quicknotes_nc
npm_cache:
name: quicknotes_npm_cache
46 changes: 46 additions & 0 deletions docker/scripts/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#!/usr/bin/env bash
# Compila los assets de la app (vendors JS, templates Handlebars, bundles Vue).
# Requiere el servicio `builder` del docker-compose (node:20).
set -euo pipefail

cd "$(dirname "$0")/.." # -> docker/

if ! docker compose ps builder --status running >/dev/null 2>&1; then
echo ">> El servicio 'builder' no estΓ‘ corriendo. Levantando..."
docker compose up -d builder
echo ">> Esperando a que 'builder' estΓ© listo..."
for i in {1..30}; do
if docker compose ps builder --status running >/dev/null 2>&1; then
break
fi
sleep 1
done
fi

echo ">> Ejecutando make build dentro del contenedor builder..."
docker compose exec -T builder sh -c '
set -e
cd /app

echo "[1/3] npm install (puede tardar varios minutos la primera vez)..."
npm ci --no-audit --no-fund || npm install --no-audit --no-fund

echo "[2/3] copy deps (depsmin) + precompilar templates handlebars..."
mkdir -p vendor js/vendor css/vendor
rm -rf js/vendor/*
cp node_modules/handlebars/dist/handlebars.min.js js/vendor/handlebars.js
cp node_modules/isotope-layout/dist/isotope.pkgd.min.js js/vendor/isotope.pkgd.js
cp node_modules/medium-editor/dist/js/medium-editor.min.js js/vendor/medium-editor.js
cp node_modules/medium-editor/dist/css/medium-editor.min.css css/vendor/medium-editor.css
cp node_modules/medium-editor-autolist/dist/autolist.min.js js/vendor/autolist.js
cp node_modules/lozad/dist/lozad.min.js js/vendor/lozad.js

node_modules/.bin/handlebars js/templates -f js/templates.js

echo "[3/3] webpack build (vue + js principal)..."
npm run build

echo ""
echo "Build OK."
ls -la js/templates.js js/quicknotes*.js* 2>/dev/null || true
'
13 changes: 13 additions & 0 deletions docker/scripts/down.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/usr/bin/env bash
# Baja los contenedores y opcionalmente borra volΓΊmenes.
set -euo pipefail

cd "$(dirname "$0")/.." # -> docker/

if [[ "${1:-}" == "--purge" || "${1:-}" == "-p" ]]; then
echo ">> Bajando contenedores y borrando volΓΊmenes..."
docker compose down -v
else
echo ">> Bajando contenedores (los volΓΊmenes se conservan)..."
docker compose down
fi
20 changes: 20 additions & 0 deletions docker/scripts/enable-app.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/usr/bin/env bash
# Habilita la app Quick notes dentro del contenedor de Nextcloud.
set -euo pipefail

cd "$(dirname "$0")/.." # -> docker/

echo ">> Verificando que el cΓ³digo de la app estΓ© montado en el contenedor..."
docker exec quicknotes-app test -f /var/www/html/custom_apps/quicknotes/appinfo/info.xml

echo ">> Ajustando permisos..."
docker exec --user root quicknotes-app chown -R www-data:www-data /var/www/html/custom_apps/quicknotes

echo ">> Deshabilitando por si estaba activa, luego habilitando..."
docker exec --user www-data quicknotes-app php occ app:disable quicknotes || true
docker exec --user www-data quicknotes-app php occ app:enable quicknotes

echo ">> Estado:"
docker exec --user www-data quicknotes-app php occ app:list | grep -A1 '^Enabled:' | grep quicknotes || true

echo "OK."
52 changes: 52 additions & 0 deletions docker/scripts/up.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#!/usr/bin/env bash
# Arranca Nextcloud 32 + MariaDB y monta este repo como custom_apps/quicknotes.
set -euo pipefail

cd "$(dirname "$0")/.." # -> docker/
REPO_ROOT="$(cd .. && pwd)"

if [[ ! -f "$REPO_ROOT/.env" ]]; then
echo "Falta $REPO_ROOT/.env. CopiΓ‘ docker/.env.example: cp $REPO_ROOT/.env.example $REPO_ROOT/.env" >&2
exit 1
fi

set -a
# shellcheck disable=SC1091
source "$REPO_ROOT/.env"
set +a

echo ">> Levantando contenedores..."
docker compose --env-file "$REPO_ROOT/.env" up -d

echo
echo ">> Verificando assets compilados de la app..."
if [[ ! -f "$REPO_ROOT/js/templates.js" \
|| ! -d "$REPO_ROOT/js/vendor" \
|| ! -f "$REPO_ROOT/js/quicknotes-dashboard.js" ]]; then
echo " Faltan assets (templates.js / vendor / bundles Vue). Compilando..."
"$(dirname "$0")/build.sh"
else
echo " Assets OK."
fi

echo
echo ">> Esperando a que Nextcloud termine el primer arranque (puede tardar 1-2 min)..."
for i in {1..60}; do
if docker exec quicknotes-app curl -fsS http://localhost/status.php >/dev/null 2>&1; then
echo " Nextcloud estΓ‘ respondiendo."
break
fi
printf "."
sleep 5
done
echo

echo ">> ΒΏHabilitar Quick notes ahora? [s/N]"
read -r ans
if [[ "${ans:-N}" =~ ^[sSyY]$ ]]; then
"$(dirname "$0")/enable-app.sh"
fi

echo
echo "Listo. AbrΓ­ http://localhost:${NEXTCLOUD_HTTP_PORT:-8080}"
echo "Usuario: ${NEXTCLOUD_ADMIN_USER:-admin}"
8 changes: 8 additions & 0 deletions js/script.js
Original file line number Diff line number Diff line change
Expand Up @@ -995,6 +995,14 @@ View.prototype = {
},
_initEditor: function() {
var modalcontent = $('#modal-note-div #content-editable');
if (modalcontent.length === 0) {
console.error('[quicknotes] _initEditor: #content-editable not found in DOM');
return;
}
if (this._editor) {
this._editor.destroy();
this._editor = undefined;
}
var editor = new MediumEditor(modalcontent, {
toolbar: {
buttons: [
Expand Down
Loading
Loading