From 903dd943421eb287cb62af56a51cedf4e95a54c3 Mon Sep 17 00:00:00 2001 From: Saurabh Bhatia Date: Sat, 26 Oct 2024 06:39:59 +1100 Subject: [PATCH] Add Motor Admin --- Gemfile | 1 + Gemfile.lock | 20 ++ config/routes.rb | 14 +- .../20241024192032_install_motor_admin.rb | 271 ++++++++++++++++++ db/schema.rb | 200 ++++++++++++- 5 files changed, 497 insertions(+), 9 deletions(-) create mode 100644 db/migrate/20241024192032_install_motor_admin.rb diff --git a/Gemfile b/Gemfile index 1ff55c5a..c000fdae 100644 --- a/Gemfile +++ b/Gemfile @@ -57,6 +57,7 @@ gem "httparty" gem "dotenv-rails" gem "honeybadger" gem "rack-cors" +gem "motor-admin" # Windows does not include zoneinfo files, so bundle the tzinfo-data gem gem "tzinfo-data", platforms: %i[mingw mswin x64_mingw jruby] diff --git a/Gemfile.lock b/Gemfile.lock index 49ac2630..c3aeced8 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -94,7 +94,12 @@ GEM tzinfo (~> 2.0) addressable (2.8.7) public_suffix (>= 2.0.2, < 7.0) + ar_lazy_preload (1.1.2) + rails (>= 5.2) ast (2.4.2) + audited (5.7.0) + activerecord (>= 5.2, < 8.0) + activesupport (>= 5.2, < 8.0) aws-eventstream (1.3.0) aws-partitions (1.991.0) aws-sdk-core (3.209.1) @@ -119,6 +124,7 @@ GEM msgpack (~> 1.2) brotli (0.6.0) builder (3.3.0) + cancancan (3.6.1) capybara (3.40.0) addressable matrix @@ -155,6 +161,8 @@ GEM railties (>= 6.1) drb (2.2.1) erubi (1.13.0) + et-orbi (1.2.11) + tzinfo factory_bot (6.5.0) activesupport (>= 5.0.0) factory_bot_rails (6.4.3) @@ -176,6 +184,9 @@ GEM rack-protection (>= 1.5.3, < 5.0.0) rack-session (>= 1.0.2, < 3.0.0) sanitize (< 7) + fugit (1.11.1) + et-orbi (~> 1, >= 1.2.11) + raabro (~> 1.4) globalid (1.2.1) activesupport (>= 6.1) graphiql-rails (1.10.1) @@ -240,6 +251,13 @@ GEM monetize (~> 1.9) money (~> 6.13) railties (>= 3.0) + motor-admin (0.4.31) + ar_lazy_preload (~> 1.0) + audited (~> 5.0) + cancancan (~> 3.0) + csv (>= 3.0) + fugit (~> 1.0) + rails (>= 5.2) msgpack (1.7.3) multi_xml (0.7.1) bigdecimal (~> 3.1) @@ -286,6 +304,7 @@ GEM nio4r (~> 2.0) pundit (2.4.0) activesupport (>= 3.0.0) + raabro (1.4.0) racc (1.8.1) rack (3.1.8) rack-brotli (2.0.0) @@ -488,6 +507,7 @@ DEPENDENCIES jsbundling-rails meta-tags money-rails + motor-admin omniauth (~> 2.1) pagy pg diff --git a/config/routes.rb b/config/routes.rb index 43a7b90c..abd20126 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -13,17 +13,15 @@ sign_in: "login", sign_out: "logout" } + namespace :admin do - root "dashboard#index" - resources :posts, param: :slug - resources :creator_profiles, param: :slug - resources :stores, param: :slug - resources :products, param: :slug do - get :add_product_to_stripe, on: :member + authenticate(:admin_user) do + mount Motor::Admin => "/panel" + mount Flipper::UI.app(Flipper) => "/flipper" + mount Sidekiq::Web => "/sidekiq" end - mount Flipper::UI.app(Flipper) => "/flipper" - mount Sidekiq::Web => "/sidekiq" end + root "home#index" get "about", to: "pages#about", as: "about" get "for-creators", to: "pages#for_creators", as: "for_creators" diff --git a/db/migrate/20241024192032_install_motor_admin.rb b/db/migrate/20241024192032_install_motor_admin.rb new file mode 100644 index 00000000..4a37db21 --- /dev/null +++ b/db/migrate/20241024192032_install_motor_admin.rb @@ -0,0 +1,271 @@ +class InstallMotorAdmin < ActiveRecord::Migration[7.1] + def self.up + create_table :motor_queries do |t| + t.column :name, :string, null: false + t.column :description, :text + t.column :sql_body, :text, null: false + t.column :preferences, :text, null: false + t.column :author_id, :bigint + t.column :author_type, :string + t.column :deleted_at, :datetime + + t.timestamps + + t.index :updated_at + t.index 'name', + name: 'motor_queries_name_unique_index', + unique: true, + where: 'deleted_at IS NULL' + end + + create_table :motor_dashboards do |t| + t.column :title, :string, null: false + t.column :description, :text + t.column :preferences, :text, null: false + t.column :author_id, :bigint + t.column :author_type, :string + t.column :deleted_at, :datetime + + t.timestamps + + t.index :updated_at + t.index 'title', + name: 'motor_dashboards_title_unique_index', + unique: true, + where: 'deleted_at IS NULL' + end + + create_table :motor_forms do |t| + t.column :name, :string, null: false + t.column :description, :text + t.column :api_path, :text, null: false + t.column :http_method, :string, null: false + t.column :preferences, :text, null: false + t.column :author_id, :bigint + t.column :author_type, :string + t.column :deleted_at, :datetime + t.column :api_config_name, :string, null: false + + t.timestamps + + t.index :updated_at + t.index 'name', + name: 'motor_forms_name_unique_index', + unique: true, + where: 'deleted_at IS NULL' + end + + create_table :motor_resources do |t| + t.column :name, :string, null: false, index: { unique: true } + t.column :preferences, :text, null: false + + t.timestamps + + t.index :updated_at + end + + create_table :motor_configs do |t| + t.column :key, :string, null: false, index: { unique: true } + t.column :value, :text, null: false + + t.timestamps + + t.index :updated_at + end + + create_table :motor_alerts do |t| + t.references :query, null: false, foreign_key: { to_table: :motor_queries }, index: true + t.column :name, :string, null: false + t.column :description, :text + t.column :to_emails, :text, null: false + t.column :is_enabled, :boolean, null: false, default: true + t.column :preferences, :text, null: false + t.column :author_id, :bigint + t.column :author_type, :string + t.column :deleted_at, :datetime + + t.timestamps + + t.index :updated_at + t.index 'name', + name: 'motor_alerts_name_unique_index', + unique: true, + where: 'deleted_at IS NULL' + end + + create_table :motor_alert_locks do |t| + t.references :alert, null: false, foreign_key: { to_table: :motor_alerts } + t.column :lock_timestamp, :string, null: false + + t.timestamps + + t.index %i[alert_id lock_timestamp], unique: true + end + + create_table :motor_tags do |t| + t.column :name, :string, null: false + + t.timestamps + + t.index 'name', + name: 'motor_tags_name_unique_index', + unique: true + end + + create_table :motor_taggable_tags do |t| + t.references :tag, null: false, foreign_key: { to_table: :motor_tags }, index: true + t.column :taggable_id, :bigint, null: false + t.column :taggable_type, :string, null: false + + t.index %i[taggable_id taggable_type tag_id], + name: 'motor_polymorphic_association_tag_index', + unique: true + end + + create_table :motor_audits do |t| + t.column :auditable_id, :string + t.column :auditable_type, :string + t.column :associated_id, :string + t.column :associated_type, :string + t.column :user_id, :bigint + t.column :user_type, :string + t.column :username, :string + t.column :action, :string + t.column :audited_changes, :text + t.column :version, :bigint, default: 0 + t.column :comment, :text + t.column :remote_address, :string + t.column :request_uuid, :string + t.column :created_at, :datetime + end + + create_table :motor_api_configs do |t| + t.column :name, :string, null: false + t.column :url, :string, null: false + t.column :preferences, :text, null: false + t.column :credentials, :text, null: false + t.column :description, :text + t.column :deleted_at, :datetime + + t.timestamps + + t.index 'name', + name: 'motor_api_configs_name_unique_index', + unique: true, + where: 'deleted_at IS NULL' + end + + create_table :motor_notes do |t| + t.column :body, :text + t.column :author_id, :bigint + t.column :author_type, :string + t.column :record_id, :string, null: false + t.column :record_type, :string, null: false + t.column :deleted_at, :datetime + + t.timestamps + + t.index %i[record_id record_type], + name: 'motor_notes_record_id_record_type_index' + + t.index %i[author_id author_type], + name: 'motor_notes_author_id_author_type_index' + end + + create_table :motor_note_tags do |t| + t.column :name, :string, null: false + + t.timestamps + + t.index 'name', + name: 'motor_note_tags_name_unique_index', + unique: true + end + + create_table :motor_note_tag_tags do |t| + t.references :tag, null: false, foreign_key: { to_table: :motor_note_tags }, index: true + t.references :note, null: false, foreign_key: { to_table: :motor_notes }, index: false + + t.index %i[note_id tag_id], + name: 'motor_note_tags_note_id_tag_id_index', + unique: true + end + + create_table :motor_reminders do |t| + t.column :author_id, :bigint, null: false + t.column :author_type, :string, null: false + t.column :recipient_id, :bigint, null: false + t.column :recipient_type, :string, null: false + t.column :record_id, :string + t.column :record_type, :string + t.column :scheduled_at, :datetime, null: false, index: true + + t.timestamps + + t.index %i[author_id author_type], + name: 'motor_reminders_author_id_author_type_index' + + t.index %i[recipient_id recipient_type], + name: 'motor_reminders_recipient_id_recipient_type_index' + + t.index %i[record_id record_type], + name: 'motor_reminders_record_id_record_type_index' + end + + create_table :motor_notifications do |t| + t.column :title, :string, null: false + t.column :description, :text + t.column :recipient_id, :bigint, null: false + t.column :recipient_type, :string, null: false + t.column :record_id, :string + t.column :record_type, :string + t.column :status, :string, null: false + + t.timestamps + + t.index %i[recipient_id recipient_type], + name: 'motor_notifications_recipient_id_recipient_type_index' + + t.index %i[record_id record_type], + name: 'motor_notifications_record_id_record_type_index' + end + + add_index :motor_audits, %i[auditable_type auditable_id version], name: 'motor_auditable_index' + add_index :motor_audits, %i[associated_type associated_id], name: 'motor_auditable_associated_index' + add_index :motor_audits, %i[user_id user_type], name: 'motor_auditable_user_index' + add_index :motor_audits, :request_uuid + add_index :motor_audits, :created_at + + model = Class.new(ApplicationRecord) + + model.table_name = 'motor_configs' + + model.create!(key: 'header.links', value: [{ + name: '⭐ Star on GitHub', + path: 'https://github.com/motor-admin/motor-admin-rails' + }].to_json) + + model.table_name = 'motor_api_configs' + + model.create!(name: 'origin', url: '/', preferences: {}, credentials: {}) + end + + def self.down + drop_table :motor_audits + drop_table :motor_alert_locks + drop_table :motor_alerts + drop_table :motor_forms + drop_table :motor_taggable_tags + drop_table :motor_tags + drop_table :motor_resources + drop_table :motor_configs + drop_table :motor_queries + drop_table :motor_dashboards + drop_table :motor_api_configs + drop_table :motor_note_tag_tags + drop_table :motor_note_tags + drop_table :motor_notes + drop_table :motor_notifications + drop_table :motor_reminders + end +end diff --git a/db/schema.rb b/db/schema.rb index ef2c36f6..7af128d5 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[7.1].define(version: 2024_09_19_114023) do +ActiveRecord::Schema[7.1].define(version: 2024_10_24_192032) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -184,6 +184,199 @@ t.index ["product_id"], name: "index_line_items_on_product_id" end + create_table "motor_alert_locks", force: :cascade do |t| + t.bigint "alert_id", null: false + t.string "lock_timestamp", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["alert_id", "lock_timestamp"], name: "index_motor_alert_locks_on_alert_id_and_lock_timestamp", unique: true + t.index ["alert_id"], name: "index_motor_alert_locks_on_alert_id" + end + + create_table "motor_alerts", force: :cascade do |t| + t.bigint "query_id", null: false + t.string "name", null: false + t.text "description" + t.text "to_emails", null: false + t.boolean "is_enabled", default: true, null: false + t.text "preferences", null: false + t.bigint "author_id" + t.string "author_type" + t.datetime "deleted_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["name"], name: "motor_alerts_name_unique_index", unique: true, where: "(deleted_at IS NULL)" + t.index ["query_id"], name: "index_motor_alerts_on_query_id" + t.index ["updated_at"], name: "index_motor_alerts_on_updated_at" + end + + create_table "motor_api_configs", force: :cascade do |t| + t.string "name", null: false + t.string "url", null: false + t.text "preferences", null: false + t.text "credentials", null: false + t.text "description" + t.datetime "deleted_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["name"], name: "motor_api_configs_name_unique_index", unique: true, where: "(deleted_at IS NULL)" + end + + create_table "motor_audits", force: :cascade do |t| + t.string "auditable_id" + t.string "auditable_type" + t.string "associated_id" + t.string "associated_type" + t.bigint "user_id" + t.string "user_type" + t.string "username" + t.string "action" + t.text "audited_changes" + t.bigint "version", default: 0 + t.text "comment" + t.string "remote_address" + t.string "request_uuid" + t.datetime "created_at" + t.index ["associated_type", "associated_id"], name: "motor_auditable_associated_index" + t.index ["auditable_type", "auditable_id", "version"], name: "motor_auditable_index" + t.index ["created_at"], name: "index_motor_audits_on_created_at" + t.index ["request_uuid"], name: "index_motor_audits_on_request_uuid" + t.index ["user_id", "user_type"], name: "motor_auditable_user_index" + end + + create_table "motor_configs", force: :cascade do |t| + t.string "key", null: false + t.text "value", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["key"], name: "index_motor_configs_on_key", unique: true + t.index ["updated_at"], name: "index_motor_configs_on_updated_at" + end + + create_table "motor_dashboards", force: :cascade do |t| + t.string "title", null: false + t.text "description" + t.text "preferences", null: false + t.bigint "author_id" + t.string "author_type" + t.datetime "deleted_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["title"], name: "motor_dashboards_title_unique_index", unique: true, where: "(deleted_at IS NULL)" + t.index ["updated_at"], name: "index_motor_dashboards_on_updated_at" + end + + create_table "motor_forms", force: :cascade do |t| + t.string "name", null: false + t.text "description" + t.text "api_path", null: false + t.string "http_method", null: false + t.text "preferences", null: false + t.bigint "author_id" + t.string "author_type" + t.datetime "deleted_at" + t.string "api_config_name", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["name"], name: "motor_forms_name_unique_index", unique: true, where: "(deleted_at IS NULL)" + t.index ["updated_at"], name: "index_motor_forms_on_updated_at" + end + + create_table "motor_note_tag_tags", force: :cascade do |t| + t.bigint "tag_id", null: false + t.bigint "note_id", null: false + t.index ["note_id", "tag_id"], name: "motor_note_tags_note_id_tag_id_index", unique: true + t.index ["tag_id"], name: "index_motor_note_tag_tags_on_tag_id" + end + + create_table "motor_note_tags", force: :cascade do |t| + t.string "name", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["name"], name: "motor_note_tags_name_unique_index", unique: true + end + + create_table "motor_notes", force: :cascade do |t| + t.text "body" + t.bigint "author_id" + t.string "author_type" + t.string "record_id", null: false + t.string "record_type", null: false + t.datetime "deleted_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["author_id", "author_type"], name: "motor_notes_author_id_author_type_index" + t.index ["record_id", "record_type"], name: "motor_notes_record_id_record_type_index" + end + + create_table "motor_notifications", force: :cascade do |t| + t.string "title", null: false + t.text "description" + t.bigint "recipient_id", null: false + t.string "recipient_type", null: false + t.string "record_id" + t.string "record_type" + t.string "status", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["recipient_id", "recipient_type"], name: "motor_notifications_recipient_id_recipient_type_index" + t.index ["record_id", "record_type"], name: "motor_notifications_record_id_record_type_index" + end + + create_table "motor_queries", force: :cascade do |t| + t.string "name", null: false + t.text "description" + t.text "sql_body", null: false + t.text "preferences", null: false + t.bigint "author_id" + t.string "author_type" + t.datetime "deleted_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["name"], name: "motor_queries_name_unique_index", unique: true, where: "(deleted_at IS NULL)" + t.index ["updated_at"], name: "index_motor_queries_on_updated_at" + end + + create_table "motor_reminders", force: :cascade do |t| + t.bigint "author_id", null: false + t.string "author_type", null: false + t.bigint "recipient_id", null: false + t.string "recipient_type", null: false + t.string "record_id" + t.string "record_type" + t.datetime "scheduled_at", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["author_id", "author_type"], name: "motor_reminders_author_id_author_type_index" + t.index ["recipient_id", "recipient_type"], name: "motor_reminders_recipient_id_recipient_type_index" + t.index ["record_id", "record_type"], name: "motor_reminders_record_id_record_type_index" + t.index ["scheduled_at"], name: "index_motor_reminders_on_scheduled_at" + end + + create_table "motor_resources", force: :cascade do |t| + t.string "name", null: false + t.text "preferences", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["name"], name: "index_motor_resources_on_name", unique: true + t.index ["updated_at"], name: "index_motor_resources_on_updated_at" + end + + create_table "motor_taggable_tags", force: :cascade do |t| + t.bigint "tag_id", null: false + t.bigint "taggable_id", null: false + t.string "taggable_type", null: false + t.index ["tag_id"], name: "index_motor_taggable_tags_on_tag_id" + t.index ["taggable_id", "taggable_type", "tag_id"], name: "motor_polymorphic_association_tag_index", unique: true + end + + create_table "motor_tags", force: :cascade do |t| + t.string "name", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["name"], name: "motor_tags_name_unique_index", unique: true + end + create_table "orders", force: :cascade do |t| t.string "order_reference" t.datetime "created_at", null: false @@ -354,6 +547,11 @@ add_foreign_key "line_items", "carts" add_foreign_key "line_items", "orders" add_foreign_key "line_items", "products" + add_foreign_key "motor_alert_locks", "motor_alerts", column: "alert_id" + add_foreign_key "motor_alerts", "motor_queries", column: "query_id" + add_foreign_key "motor_note_tag_tags", "motor_note_tags", column: "tag_id" + add_foreign_key "motor_note_tag_tags", "motor_notes", column: "note_id" + add_foreign_key "motor_taggable_tags", "motor_tags", column: "tag_id" add_foreign_key "orders", "carts" add_foreign_key "orders", "users" add_foreign_key "product_genres", "genres"