From 35f2a69048e00cc965184004ad6e533f5a858798 Mon Sep 17 00:00:00 2001 From: Karen Date: Thu, 2 Feb 2023 15:18:09 +0100 Subject: [PATCH] (feat) Add unsaved form alert and refreshed tabs on admin machines and trainings view --- .../components/machines/machines-settings.tsx | 8 +- .../trainings/trainings-settings.tsx | 8 +- .../javascript/controllers/admin/machines.js | 7 +- .../javascript/controllers/admin/trainings.js | 7 +- .../templates/admin/machines/index.html | 10 +- .../templates/admin/trainings/index.html | 4 +- db/schema.rb | 137 +----------------- 7 files changed, 33 insertions(+), 148 deletions(-) diff --git a/app/frontend/src/javascript/components/machines/machines-settings.tsx b/app/frontend/src/javascript/components/machines/machines-settings.tsx index 9cb4a348e..194a6a502 100644 --- a/app/frontend/src/javascript/components/machines/machines-settings.tsx +++ b/app/frontend/src/javascript/components/machines/machines-settings.tsx @@ -10,6 +10,8 @@ import { EditorialKeys, EditorialBlockForm } from '../editorial-block/editorial- import SettingAPI from '../../api/setting'; import SettingLib from '../../lib/setting'; import { SettingName, SettingValue, machinesSettings } from '../../models/setting'; +import { UnsavedFormAlert } from '../form/unsaved-form-alert'; +import { UIRouter } from '@uirouter/angularjs'; declare const Application: IApplication; @@ -17,12 +19,13 @@ interface MachinesSettingsProps { onError: (message: string) => void, onSuccess: (message: string) => void, beforeSubmit?: (data: Record) => void, + uiRouter: UIRouter } /** * Machines settings */ -export const MachinesSettings: React.FC = ({ onError, onSuccess, beforeSubmit }) => { +export const MachinesSettings: React.FC = ({ onError, onSuccess, beforeSubmit, uiRouter }) => { const { t } = useTranslation('admin'); const { register, control, formState, handleSubmit, reset } = useForm>(); @@ -59,6 +62,7 @@ export const MachinesSettings: React.FC = ({ onError, onS {t('app.admin.machines_settings.save')}
+
= (props) => { ); }; -Application.Components.component('machinesSettings', react2angular(MachinesSettingsWrapper, ['onError', 'onSuccess'])); +Application.Components.component('machinesSettings', react2angular(MachinesSettingsWrapper, ['onError', 'onSuccess', 'beforeSubmit', 'uiRouter'])); diff --git a/app/frontend/src/javascript/components/trainings/trainings-settings.tsx b/app/frontend/src/javascript/components/trainings/trainings-settings.tsx index b59499fc5..1401ed44b 100644 --- a/app/frontend/src/javascript/components/trainings/trainings-settings.tsx +++ b/app/frontend/src/javascript/components/trainings/trainings-settings.tsx @@ -13,18 +13,21 @@ import { EditorialKeys, EditorialBlockForm } from '../editorial-block/editorial- import { SettingName, SettingValue, trainingsSettings } from '../../models/setting'; import SettingAPI from '../../api/setting'; import SettingLib from '../../lib/setting'; +import { UnsavedFormAlert } from '../form/unsaved-form-alert'; +import { UIRouter } from '@uirouter/angularjs'; declare const Application: IApplication; interface TrainingsSettingsProps { onError: (message: string) => void, onSuccess: (message: string) => void, + uiRouter: UIRouter } /** * Trainings settings */ -export const TrainingsSettings: React.FC = ({ onError, onSuccess }) => { +export const TrainingsSettings: React.FC = ({ onError, onSuccess, uiRouter }) => { const { t } = useTranslation('admin'); const { register, control, formState, handleSubmit, reset } = useForm>(); @@ -68,6 +71,7 @@ export const TrainingsSettings: React.FC = ({ onError, o handleSubmit(onSubmit)()} className='save-btn is-main'>{t('app.admin.trainings_settings.save')} +
= (props) => { ); }; -Application.Components.component('trainingsSettings', react2angular(TrainingsSettingsWrapper, ['onError', 'onSuccess'])); +Application.Components.component('trainingsSettings', react2angular(TrainingsSettingsWrapper, ['onError', 'onSuccess', 'uiRouter'])); diff --git a/app/frontend/src/javascript/controllers/admin/machines.js b/app/frontend/src/javascript/controllers/admin/machines.js index f3a3e4d01..1df424daf 100644 --- a/app/frontend/src/javascript/controllers/admin/machines.js +++ b/app/frontend/src/javascript/controllers/admin/machines.js @@ -4,10 +4,13 @@ */ 'use strict'; -Application.Controllers.controller('AdminMachinesController', ['$scope', 'CSRF', 'growl', '$state', '_t', 'AuthService', 'settingsPromise', 'Member', 'uiTourService', 'machinesPromise', 'helpers', - function ($scope, CSRF, growl, $state, _t, AuthService, settingsPromise, Member, uiTourService, machinesPromise, helpers) { +Application.Controllers.controller('AdminMachinesController', ['$scope', 'CSRF', 'growl', '$state', '_t', 'AuthService', 'settingsPromise', 'Member', 'uiTourService', 'machinesPromise', 'helpers', '$uiRouter', + function ($scope, CSRF, growl, $state, _t, AuthService, settingsPromise, Member, uiTourService, machinesPromise, helpers, $uiRouter) { /* PUBLIC SCOPE */ + // the following item is used by the UnsavedFormAlert component to detect a page change + $scope.uiRouter = $uiRouter; + // default tab: machines list $scope.tabs = { active: 0 }; diff --git a/app/frontend/src/javascript/controllers/admin/trainings.js b/app/frontend/src/javascript/controllers/admin/trainings.js index ebd172e90..b49df7797 100644 --- a/app/frontend/src/javascript/controllers/admin/trainings.js +++ b/app/frontend/src/javascript/controllers/admin/trainings.js @@ -169,8 +169,11 @@ Application.Controllers.controller('EditTrainingController', ['$scope', '$state' /** * Controller used in the trainings management page, allowing admins users to see and manage the list of trainings and reservations. */ -Application.Controllers.controller('TrainingsAdminController', ['$scope', '$state', '$uibModal', 'Training', 'trainingsPromise', 'machinesPromise', '_t', 'growl', 'dialogs', 'Member', 'uiTourService', 'settingsPromise', - function ($scope, $state, $uibModal, Training, trainingsPromise, machinesPromise, _t, growl, dialogs, Member, uiTourService, settingsPromise) { +Application.Controllers.controller('TrainingsAdminController', ['$scope', '$state', '$uibModal', 'Training', 'trainingsPromise', 'machinesPromise', '_t', 'growl', 'dialogs', 'Member', 'uiTourService', 'settingsPromise', '$uiRouter', + function ($scope, $state, $uibModal, Training, trainingsPromise, machinesPromise, _t, growl, dialogs, Member, uiTourService, settingsPromise, $uiRouter) { + // the following item is used by the UnsavedFormAlert component to detect a page change + $scope.uiRouter = $uiRouter; + // list of trainings $scope.trainings = trainingsPromise; diff --git a/app/frontend/templates/admin/machines/index.html b/app/frontend/templates/admin/machines/index.html index a911f9d99..6ebdf94c3 100644 --- a/app/frontend/templates/admin/machines/index.html +++ b/app/frontend/templates/admin/machines/index.html @@ -11,11 +11,11 @@
- - + + - +

{{ 'app.admin.machines.all_machines' }}

@@ -37,11 +37,11 @@
- +
- + diff --git a/app/frontend/templates/admin/trainings/index.html b/app/frontend/templates/admin/trainings/index.html index e5e3f6c5d..d7873040a 100644 --- a/app/frontend/templates/admin/trainings/index.html +++ b/app/frontend/templates/admin/trainings/index.html @@ -26,10 +26,10 @@
- + - + diff --git a/db/schema.rb b/db/schema.rb index e43d4e49b..b1fd69c3b 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2023_01_27_100506) do +ActiveRecord::Schema.define(version: 2023_01_31_104958) do # These are extensions that must be enabled in order to support this database enable_extension "fuzzystrmatch" @@ -150,110 +150,6 @@ ActiveRecord::Schema.define(version: 2023_01_27_100506) do t.index ["tag_id"], name: "index_availability_tags_on_tag_id" end - create_table "cart_item_coupons", force: :cascade do |t| - t.bigint "coupon_id" - t.bigint "customer_profile_id" - t.bigint "operator_profile_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index ["coupon_id"], name: "index_cart_item_coupons_on_coupon_id" - t.index ["customer_profile_id"], name: "index_cart_item_coupons_on_customer_profile_id" - t.index ["operator_profile_id"], name: "index_cart_item_coupons_on_operator_profile_id" - end - - create_table "cart_item_event_reservation_tickets", force: :cascade do |t| - t.integer "booked" - t.bigint "event_price_category_id" - t.bigint "cart_item_event_reservation_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index ["cart_item_event_reservation_id"], name: "index_cart_item_tickets_on_cart_item_event_reservation" - t.index ["event_price_category_id"], name: "index_cart_item_tickets_on_event_price_category" - end - - create_table "cart_item_event_reservations", force: :cascade do |t| - t.integer "normal_tickets" - t.bigint "event_id" - t.bigint "operator_profile_id" - t.bigint "customer_profile_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index ["customer_profile_id"], name: "index_cart_item_event_reservations_on_customer_profile_id" - t.index ["event_id"], name: "index_cart_item_event_reservations_on_event_id" - t.index ["operator_profile_id"], name: "index_cart_item_event_reservations_on_operator_profile_id" - end - - create_table "cart_item_free_extensions", force: :cascade do |t| - t.bigint "subscription_id" - t.datetime "new_expiration_date" - t.bigint "customer_profile_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index ["customer_profile_id"], name: "index_cart_item_free_extensions_on_customer_profile_id" - t.index ["subscription_id"], name: "index_cart_item_free_extensions_on_subscription_id" - end - - create_table "cart_item_payment_schedules", force: :cascade do |t| - t.bigint "plan_id" - t.bigint "coupon_id" - t.boolean "requested" - t.datetime "start_at" - t.bigint "customer_profile_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index ["coupon_id"], name: "index_cart_item_payment_schedules_on_coupon_id" - t.index ["customer_profile_id"], name: "index_cart_item_payment_schedules_on_customer_profile_id" - t.index ["plan_id"], name: "index_cart_item_payment_schedules_on_plan_id" - end - - create_table "cart_item_prepaid_packs", force: :cascade do |t| - t.bigint "prepaid_pack_id" - t.bigint "customer_profile_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index ["customer_profile_id"], name: "index_cart_item_prepaid_packs_on_customer_profile_id" - t.index ["prepaid_pack_id"], name: "index_cart_item_prepaid_packs_on_prepaid_pack_id" - end - - create_table "cart_item_reservation_slots", force: :cascade do |t| - t.string "cart_item_type" - t.bigint "cart_item_id" - t.bigint "slot_id" - t.bigint "slots_reservation_id" - t.boolean "offered", default: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index ["cart_item_type", "cart_item_id"], name: "index_cart_item_slots_on_cart_item" - t.index ["slot_id"], name: "index_cart_item_reservation_slots_on_slot_id" - t.index ["slots_reservation_id"], name: "index_cart_item_reservation_slots_on_slots_reservation_id" - end - - create_table "cart_item_reservations", force: :cascade do |t| - t.string "reservable_type" - t.bigint "reservable_id" - t.bigint "plan_id" - t.boolean "new_subscription" - t.bigint "customer_profile_id" - t.bigint "operator_profile_id" - t.string "type" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index ["customer_profile_id"], name: "index_cart_item_reservations_on_customer_profile_id" - t.index ["operator_profile_id"], name: "index_cart_item_reservations_on_operator_profile_id" - t.index ["plan_id"], name: "index_cart_item_reservations_on_plan_id" - t.index ["reservable_type", "reservable_id"], name: "index_cart_item_reservations_on_reservable" - end - - create_table "cart_item_subscriptions", force: :cascade do |t| - t.bigint "plan_id" - t.datetime "start_at" - t.bigint "customer_profile_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.index ["customer_profile_id"], name: "index_cart_item_subscriptions_on_customer_profile_id" - t.index ["plan_id"], name: "index_cart_item_subscriptions_on_plan_id" - end - create_table "categories", id: :serial, force: :cascade do |t| t.string "name" t.datetime "created_at" @@ -277,7 +173,6 @@ ActiveRecord::Schema.define(version: 2023_01_27_100506) do t.datetime "updated_at", null: false t.string "validity_per_user" t.integer "amount_off" - t.index ["code"], name: "index_coupons_on_code", unique: true end create_table "credits", id: :serial, force: :cascade do |t| @@ -1026,15 +921,13 @@ ActiveRecord::Schema.define(version: 2023_01_27_100506) do t.datetime "end_at" t.datetime "created_at" t.datetime "updated_at" - t.integer "availability_id", null: false - t.jsonb "places", default: [], null: false + t.integer "availability_id" t.index ["availability_id"], name: "index_slots_on_availability_id" - t.index ["places"], name: "index_slots_on_places", using: :gin end create_table "slots_reservations", id: :serial, force: :cascade do |t| - t.integer "slot_id", null: false - t.integer "reservation_id", null: false + t.integer "slot_id" + t.integer "reservation_id" t.datetime "ex_start_at" t.datetime "ex_end_at" t.datetime "canceled_at" @@ -1359,28 +1252,6 @@ ActiveRecord::Schema.define(version: 2023_01_27_100506) do add_foreign_key "auth_provider_mappings", "auth_providers" add_foreign_key "availability_tags", "availabilities" add_foreign_key "availability_tags", "tags" - add_foreign_key "cart_item_coupons", "coupons" - add_foreign_key "cart_item_coupons", "invoicing_profiles", column: "customer_profile_id" - add_foreign_key "cart_item_coupons", "invoicing_profiles", column: "operator_profile_id" - add_foreign_key "cart_item_event_reservation_tickets", "cart_item_event_reservations" - add_foreign_key "cart_item_event_reservation_tickets", "event_price_categories" - add_foreign_key "cart_item_event_reservations", "events" - add_foreign_key "cart_item_event_reservations", "invoicing_profiles", column: "customer_profile_id" - add_foreign_key "cart_item_event_reservations", "invoicing_profiles", column: "operator_profile_id" - add_foreign_key "cart_item_free_extensions", "invoicing_profiles", column: "customer_profile_id" - add_foreign_key "cart_item_free_extensions", "subscriptions" - add_foreign_key "cart_item_payment_schedules", "coupons" - add_foreign_key "cart_item_payment_schedules", "invoicing_profiles", column: "customer_profile_id" - add_foreign_key "cart_item_payment_schedules", "plans" - add_foreign_key "cart_item_prepaid_packs", "invoicing_profiles", column: "customer_profile_id" - add_foreign_key "cart_item_prepaid_packs", "prepaid_packs" - add_foreign_key "cart_item_reservation_slots", "slots" - add_foreign_key "cart_item_reservation_slots", "slots_reservations" - add_foreign_key "cart_item_reservations", "invoicing_profiles", column: "customer_profile_id" - add_foreign_key "cart_item_reservations", "invoicing_profiles", column: "operator_profile_id" - add_foreign_key "cart_item_reservations", "plans" - add_foreign_key "cart_item_subscriptions", "invoicing_profiles", column: "customer_profile_id" - add_foreign_key "cart_item_subscriptions", "plans" add_foreign_key "event_price_categories", "events" add_foreign_key "event_price_categories", "price_categories" add_foreign_key "events", "categories"