Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added 'Goto Today functionality (#22), Added Auto-Save functionality … #48

Merged
merged 17 commits into from
Nov 24, 2021
Merged
11 changes: 8 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,26 @@ WORKDIR /app

COPY . .

RUN apk add build-base libffi-dev
RUN apk add build-base libffi-dev shadow

RUN \
addgroup -g 911 abc && \
adduser -D -H -u 911 -G abc abc && \
usermod -G users abc

RUN \
cd /app && \
pip install gunicorn && \
pip install -r requirements.txt && \
chmod +x run.sh && \
chmod +x verify_env.py && \
chmod +x verify_data_migrations.py

RUN \
cd /app/client && \
npm install node-sass && \
npm ci && \
npm install node-sass && \
npm run build

USER abc
EXPOSE 5000
ENTRYPOINT "./run.sh"
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
</svg>
</p>

Current version: **1.0-beta10**
Current version: **1.0-beta11**

## About
The idea for this app came from using my Hobonichi Techo planner every morning to write down what I needed to accomplish that day & using it for scratching down random thoughts and notes as the day went on. The closest thing I've seen to an app for replacing this system is Noteplan, but I don't use a Mac or an iOS device, and it's not self-hostable, so I decided to write my own.
Expand All @@ -17,7 +17,7 @@ Since I had the need for keeping track of to-dos throughout the day, regular Mar
## Roadmap
I'd like to try add include at least of some the following features to get to a final v1.0 release:

- CalDAV support
- iCal support
- HTML preview (instead of just markdown)
- Kanban board for tasks (and new syntax to attach meta info like swimlane and project for each task)
- Nested tagging
Expand Down Expand Up @@ -50,7 +50,10 @@ The recommended way of running is to pull the image from [Docker Hub](https://hu
| API_SECRET_KEY | Used to sign API tokens. | Will be generated automatically if not passed in. |
| DATABASE_URI | Connection string for DB. | Will create and use a SQLite DB if not passed in. |
| DB_ENCRYPTION_KEY | Secret key for encrypting data. Length must be a multiple of 16.<br><br>*Warning*: If changed data will not be able to be decrypted! | Will be generated automatically if not passed in. |
| PREVENT_SIGNUPS | Disable signup form? Anything in this variable will prevent signups. | |
| PREVENT_SIGNUPS | Disable signup form? Anything in this variable will prevent signups. | False |
| BASE_URL | Used when using a subfolder on a reverse proxy | None |
| PUID | User ID (for folder permissions) | None |
| PGID | Group ID (for folder permissions) | None |


#### Volumes
Expand Down
1 change: 1 addition & 0 deletions app/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class User(db.Model):
uuid = db.Column(GUID, primary_key=True, index=True, unique=True, default=lambda: uuid.uuid4())
username = db.Column(db.String(64), unique=True, nullable=False)
password_hash = db.Column(db.String(128), nullable=False)
auto_save = db.Column(db.Boolean, nullable=True)
notes = db.relationship('Note', lazy='dynamic', cascade='all, delete, delete-orphan')
meta = db.relationship('Meta', lazy='dynamic', cascade='all, delete, delete-orphan')

Expand Down
32 changes: 30 additions & 2 deletions app/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -306,8 +306,34 @@ def sidebar_data():
tags = sorted(set([a.name for a in user.meta.filter_by(kind="tag").all()]), key=lambda s: s.lower())
projects = sorted(set([a.name for a in user.meta.filter_by(kind="project").all()]), key=lambda s: s.lower())
tasks = sorted([a.serialize for a in user.meta.filter_by(kind="task").all()], key=lambda task: task['note_id'])
auto_save = user.auto_save

return jsonify(tags=tags,projects=projects,notes=notes,tasks=tasks), 200
return jsonify(tags=tags,projects=projects,notes=notes,tasks=tasks,auto_save=auto_save), 200


@app.route('/api/toggle_auto_save', methods=['POST'])
@jwt_required()
def toggle_auto_save():
req = request.get_json()
auto_save = req.get('auto_save', False)

username = get_jwt_identity()

if not username:
abort(401)

user = User.query.filter_by(username=username.lower()).first()

if not user:
abort(400)

user.auto_save = auto_save

db.session.add(user)
db.session.flush()
db.session.commit()

return jsonify({}), 200


@app.route('/api/search', methods=['POST'])
Expand Down Expand Up @@ -365,7 +391,9 @@ def search():
cleaned_note['projects'] = sorted(set([x.name for x in note.meta.filter_by(kind="project").all()]), key=lambda s: s.lower())
notes.append(cleaned_note)

return jsonify(notes=notes), 200
sorted_nodes = sorted(notes, key=lambda s: s['title'].lower())

return jsonify(notes=sorted_nodes), 200


@app.route('/', defaults={'path': ''})
Expand Down
4 changes: 2 additions & 2 deletions client/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 7 additions & 2 deletions client/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
{
"name": "daily-notes",
"version": "0.1.0",
"version": "1.0.0-beta.11",
"private": true,
"license": "MIT",
"repository": {
"url": "https://github.com/m0ngr31/DailyNotes"
},
"readme": "https://github.com/m0ngr31/DailyNotes/blob/master/README.md",
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
Expand Down Expand Up @@ -55,4 +60,4 @@
"git add"
]
}
}
}
18 changes: 10 additions & 8 deletions client/src/components/Header.vue
Original file line number Diff line number Diff line change
Expand Up @@ -76,14 +76,16 @@
</b-tooltip>
</div>
<div class="level-item alt-button">
<b-dropdown position="is-bottom-left">
<b-icon
slot="trigger"
icon="ellipsis-v"
>
</b-icon>

<b-dropdown-item>Settings (coming soon)</b-dropdown-item>
<b-dropdown position="is-bottom-left" :close-on-click="false">
<b-icon slot="trigger" icon="ellipsis-v"></b-icon>
<b-dropdown-item>
<b-switch
v-model="sidebar.autoSave"
@input="sidebar.toggleAutoSave"
>
{{ sidebar.autoSave ? 'Disable Auto-Save' : 'Enable Auto-Save' }}
</b-switch>
</b-dropdown-item>
<b-dropdown-item @click="logout()">Logout</b-dropdown-item>
</b-dropdown>
</div>
Expand Down
4 changes: 3 additions & 1 deletion client/src/services/requests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import {getToken, clearToken, setToken} from './user';
import router from '../router/index';
import {SharedBuefy} from './sharedBuefy';

axios.defaults.baseURL = '/api';
axios.defaults.baseURL = process.env.VUE_APP_BASE_URL
? process.env.VUE_APP_BASE_URL
: '/api';

axios.interceptors.request.use(config => {
// Get token
Expand Down
9 changes: 9 additions & 0 deletions client/src/services/sidebar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class SidebarSerivce {
public projects: string[] = [];
public notes: INote[] = [];
public calLoading: boolean = false;
public autoSave: boolean = false;
public date: any = null;
public sidebarLoading: boolean = false;
public searchLoading: boolean = false;
Expand Down Expand Up @@ -99,6 +100,7 @@ class SidebarSerivce {
this.tasks = res.data.tasks;
this.projects = res.data.projects;
this.notes = res.data.notes;
this.autoSave = res.data.auto_save;
}

if (this.selectedSearch.length && this.searchString.length) {
Expand Down Expand Up @@ -138,6 +140,13 @@ class SidebarSerivce {
this.getSidebarInfo();
} catch (e) {}
}

public async toggleAutoSave(autoSave: boolean) {
try {
await Requests.post('/toggle_auto_save', {auto_save: autoSave});
this.getSidebarInfo();
} catch (e) {}
}
}

// Make it a singleton
Expand Down
9 changes: 9 additions & 0 deletions client/src/views/Day.vue
Original file line number Diff line number Diff line change
Expand Up @@ -231,12 +231,21 @@ export default class Day extends Vue {
this.unsavedChanges = true;
this.title = `* ${this.headerOptions.title}`;
this.headerOptions.saveDisabled = false;

if (this.sidebar.autoSave) {
this.autoSaveThrottle();
}
} else {
this.title = this.headerOptions.title;
this.headerOptions.saveDisabled = true;
}
}

public autoSaveThrottle = _.debounce(() => this.saveDay(), 3000, {
leading: false,
trailing: true
});

unsavedAlert(e: Event) {
if (this.unsavedChanges) {
// Attempt to modify event will trigger Chrome/Firefox alert msg
Expand Down
26 changes: 19 additions & 7 deletions client/src/views/Home.vue
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
<template>
<div class="columns no-margin is-mobile full-height">
<div class="column sidebar is-6-mobile is-6-tablet is-two-fifths-desktop is-4-widescreen is-3-fullhd" v-show="!sidebar.hide">
<div
class="column sidebar is-6-mobile is-6-tablet is-two-fifths-desktop is-4-widescreen is-3-fullhd"
v-show="!sidebar.hide"
>
<div class="columns light-white center-columns text-center">
<div class="column">
<b-icon
icon="book-open"
size="is-medium"
style="margin-top: .8em"
>
</b-icon>
<b-tooltip label="Go to Today" position="is-bottom">
<div @click="today()">
<b-icon
icon="book-open"
size="is-medium"
style="margin-top: .8em"
class="alt-button"
>
</b-icon>
</div>
</b-tooltip>
</div>
</div>
<Calendar />
Expand Down Expand Up @@ -54,6 +62,10 @@ export default class Admin extends Vue {
this.auth_timer = setInterval(() => updateJWT(), HOUR);
}

today() {
this.$router.push({name: 'Home Redirect'});
}

beforeDestroy() {
if (this.auth_timer) {
clearInterval(this.auth_timer);
Expand Down
9 changes: 9 additions & 0 deletions client/src/views/Note.vue
Original file line number Diff line number Diff line change
Expand Up @@ -182,12 +182,21 @@ export default class Note extends Vue {
this.unsavedChanges = true;
this.title = `* ${this.note.title}`;
this.headerOptions.saveDisabled = false;

if (this.sidebar.autoSave) {
this.autoSaveThrottle();
}
} else {
this.title = this.note.title || '';
this.headerOptions.saveDisabled = true;
}
}

public autoSaveThrottle = _.debounce(() => this.saveNote(), 3000, {
leading: false,
trailing: true
});

unsavedAlert(e: Event) {
if (this.unsavedChanges) {
// Attempt to modify event will trigger Chrome/Firefox alert msg
Expand Down
1 change: 1 addition & 0 deletions client/vue.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ var webpack = require('webpack');
var path = require('path');

process.env.VUE_APP_PREVENT_SIGNUPS = process.env.PREVENT_SIGNUPS ? true : '';
process.env.VUE_APP_BASE_URL = process.env.BASE_URL;

module.exports = {
lintOnSave: false,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
"""Added auto_save column to User table

Revision ID: ad68860179f2
Revises: 9bd71ed6ccff
Create Date: 2021-11-23 17:33:25.117589

"""
from alembic import op
import sqlalchemy as sa
import app.model_types


# revision identifiers, used by Alembic.
revision = 'ad68860179f2'
down_revision = '9bd71ed6ccff'
branch_labels = None
depends_on = None


def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('user', schema=None) as batch_op:
batch_op.add_column(sa.Column('auto_save', sa.Boolean(), nullable=True))

# ### end Alembic commands ###


def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('user', schema=None) as batch_op:
batch_op.drop_column('auto_save')

# ### end Alembic commands ###
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
flask
flask_sqlalchemy
flask-migrate
flask-jwt-extended
gunicorn
flask-jwt-extended>4
flask-argon2
python-frontmatter
pycrypto
11 changes: 11 additions & 0 deletions run.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
#!/bin/sh

PUID=${PUID:-911}
PGID=${PGID:-911}

if [ "$(whoami)" = "abc" ]; then
echo "Setting container permissions"
groupmod -o -g "$PGID" abc
usermod -o -u "$PUID" abc
chown abc:abc /app
chown abc:abc /config
fi

if test -f "./config/.env"; then
. ./config/.env
fi
Expand Down