Merge pull request #71 from Freika/settings

Settings
This commit is contained in:
Evgenii Burmakin 2024-06-20 23:59:45 +02:00 committed by GitHub
commit c86c3052d9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 141 additions and 9 deletions

View file

@ -1 +1 @@
0.7.0
0.7.1

View file

@ -5,6 +5,23 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).
## [0.7.1] — 2024-06-20
In new Settings page you can now change the following settings:
- Maximum distance between two points to consider them as one route
- Maximum time between two points to consider them as one route
### Added
- New Settings page to change Dawarich settings.
### Changed
- Settings link in user menu now redirects to the new Settings page.
- Old settings page is now available undeer Account link in user menu.
---
## [0.7.0] — 2024-06-19
## The GPX MVP Release

File diff suppressed because one or more lines are too long

View file

@ -3,6 +3,17 @@
class SettingsController < ApplicationController
before_action :authenticate_user!
def index
end
def update
current_user.update(settings: settings_params)
flash.now[:notice] = 'Settings updated'
redirect_to settings_path, notice: 'Settings updated'
end
def theme
current_user.update(theme: params[:theme])
@ -14,4 +25,10 @@ class SettingsController < ApplicationController
redirect_back(fallback_location: root_path)
end
private
def settings_params
params.require(:settings).permit(:meters_between_routes, :minutes_between_routes)
end
end

View file

@ -206,8 +206,8 @@ export default class extends Controller {
createPolylinesLayer(markers, map, timezone) {
const splitPolylines = [];
let currentPolyline = [];
const distanceThresholdMeters = parseInt(this.getUrlParameter("meters_between_routes")) || 500;
const timeThresholdMinutes = parseInt(this.getUrlParameter("minutes_between_routes")) || 60;
const distanceThresholdMeters = parseInt(this.element.dataset.meters_between_routes) || 500;
const timeThresholdMinutes = parseInt(this.element.dataset.minutes_between_routes) || 60;
for (let i = 0, len = markers.length; i < len; i++) {
if (currentPolyline.length === 0) {

View file

@ -1,3 +1,5 @@
<% content_for :title, 'Account' %>
<div class="hero min-h-content bg-base-200">
<div class="hero-content flex-col lg:flex-row-reverse w-full my-10">
<div class="text-center lg:text-left">

View file

@ -44,7 +44,9 @@
data-controller="maps"
data-coordinates="<%= @coordinates %>"
data-center="<%= MAP_CENTER %>"
data-timezone="<%= Rails.configuration.time_zone %>">
data-timezone="<%= Rails.configuration.time_zone %>"
data-meters_between_routes="<%= current_user.settings['meters_between_routes'] %>"
data-minutes_between_routes="<%= current_user.settings['minutes_between_routes'] %>">
<div data-maps-target="container" class="h-[25rem] w-auto min-h-screen"></div>
</div>
</div>

View file

@ -0,0 +1,65 @@
<% content_for :title, 'Settings' %>
<div class="hero min-h-content bg-base-200">
<div class="hero-content flex-col lg:flex-row-reverse w-full my-10">
<div class="text-center lg:text-left">
<h1 class="text-5xl font-bold">Edit your Dawarich settings!</h1>
</div>
<div class="card flex-shrink-0 w-full max-w-sm shadow-2xl bg-base-100 px-5 py-5">
<%= form_for :settings, url: settings_path, method: :patch, data: { turbo_method: :patch, turbo: false } do |f| %>
<div class="form-control my-2">
<%= f.label :meters_between_routes do %>
Meters between routes
<!-- The button to open modal -->
<label for="meters_between_routes_info" class="btn">?</label>
<!-- Put this part before </body> tag -->
<input type="checkbox" id="meters_between_routes_info" class="modal-toggle" />
<div class="modal" role="dialog">
<div class="modal-box">
<h3 class="text-lg font-bold">Meters between routes</h3>
<p class="py-4">
Value in meters.
</p>
<p class="py-4">
Points on the map are connected by lines. This value is the maximum distance between two points to be connected by a line. If the distance between two points is greater than this value, they will not be connected, and the line will not be drawn. This allows to split the route into smaller segments, and to avoid drawing lines between two points that are far from each other.
</p>
</div>
<label class="modal-backdrop" for="meters_between_routes_info">Close</label>
</div>
<% end %>
<%= f.number_field :meters_between_routes, value: current_user.settings['meters_between_routes'], class: "input input-bordered" %>
</div>
<div class="form-control my-2">
<%= f.label :minutes_between_routes do %>
Minutes between routes
<!-- The button to open modal -->
<label for="minutes_between_routes_info" class="btn">?</label>
<!-- Put this part before </body> tag -->
<input type="checkbox" id="minutes_between_routes_info" class="modal-toggle" />
<div class="modal" role="dialog">
<div class="modal-box">
<h3 class="text-lg font-bold">Minutes between routes</h3>
<p class="py-4">
Value in minutes.
</p>
<p class="py-4">
Points on the map are connected by lines. This value is the maximum time between two points to be connected by a line. If the time between two points is greater than this value, they will not be connected. This allows to split the route into smaller segments, and to avoid drawing lines between two points that are far in time from each other.
</p>
</div>
<label class="modal-backdrop" for="minutes_between_routes_info">Close</label>
</div>
<% end %>
<%= f.number_field :minutes_between_routes, value: current_user.settings['minutes_between_routes'], class: "input input-bordered" %>
</div>
<div class="form-control my-2">
<%= f.submit "Update", class: "btn btn-primary" %>
</div>
<% end %>
</div>
</div>
</div>

View file

@ -55,7 +55,8 @@
<%= "#{current_user.email}" %>
</summary>
<ul class="p-2 bg-base-100 rounded-t-none z-10">
<li><%= link_to 'Settings', edit_user_registration_path %></li>
<li><%= link_to 'Account', edit_user_registration_path %></li>
<li><%= link_to 'Settings', settings_path %></li>
<li><%= link_to 'Logout', destroy_user_session_path, method: :delete, data: { turbo_method: :delete } %></li>
</ul>
</details>

View file

@ -7,7 +7,11 @@ Rails.application.routes.draw do
mount Rswag::Ui::Engine => '/api-docs'
mount Sidekiq::Web => '/sidekiq'
resources :settings, only: :index
patch 'settings', to: 'settings#update'
get 'settings/theme', to: 'settings#theme'
post 'settings/generate_api_key', to: 'settings#generate_api_key', as: :generate_api_key
resources :imports
resources :exports, only: %i[index create destroy]
@ -26,8 +30,6 @@ Rails.application.routes.draw do
root to: 'home#index'
devise_for :users
post 'settings/generate_api_key', to: 'settings#generate_api_key', as: :generate_api_key
get 'map', to: 'map#index'
namespace :api do

View file

@ -0,0 +1,10 @@
# frozen_string_literal: true
class AddSettingsToUsers < ActiveRecord::Migration[7.1]
def change
add_column :users, :settings, :jsonb, default: {
meters_between_routes: 500,
minutes_between_routes: 60
}
end
end

3
db/schema.rb generated
View file

@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[7.1].define(version: 2024_06_12_152451) do
ActiveRecord::Schema[7.1].define(version: 2024_06_20_205120) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@ -135,6 +135,7 @@ ActiveRecord::Schema[7.1].define(version: 2024_06_12_152451) do
t.datetime "updated_at", null: false
t.string "api_key", default: "", null: false
t.string "theme", default: "dark", null: false
t.jsonb "settings", default: {"meters_between_routes"=>500, "minutes_between_routes"=>60}
t.index ["email"], name: "index_users_on_email", unique: true
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
end

View file

@ -68,4 +68,19 @@ RSpec.describe 'Settings', type: :request do
end
end
end
describe 'PATCH /settings' do
let(:user) { create(:user) }
let(:params) { { settings: { 'meters_between_routes' => '1000', 'minutes_between_routes' => '10' } } }
before do
sign_in user
end
it 'updates the user settings' do
patch '/settings', params: params
expect(user.reload.settings).to eq(params[:settings])
end
end
end