From ce269f056f6507fc4a75f5b3aa91fabc1a64f4ac Mon Sep 17 00:00:00 2001 From: "Jesse C. Fisher" Date: Fri, 8 Dec 2023 17:35:46 +0000 Subject: [PATCH] Add start to Token creation feature --- app/controllers/canisters_controller.rb | 2 +- app/controllers/tokens_controller.rb | 21 +++++++-- app/models/token.rb | 2 +- app/policies/canister_policy.rb | 20 ++++++++ app/policies/token_policy.rb | 20 +++++--- app/views/layouts/_navigation_links.html.erb | 1 + .../tokens/_existing_token_form.html.haml | 8 ++++ app/views/tokens/_form.html.haml | 8 ++-- app/views/tokens/add_existing.html.haml | 5 ++ app/views/tokens/index.html.haml | 47 +++++++++++++++++-- app/views/tokens/new.html.haml | 3 +- app/views/tokens/show.html.haml | 23 +++++++-- config/routes.rb | 2 + .../20231208165729_add_ownable_id_to_token.rb | 5 ++ db/schema.rb | 3 +- 15 files changed, 144 insertions(+), 26 deletions(-) create mode 100644 app/views/tokens/_existing_token_form.html.haml create mode 100644 app/views/tokens/add_existing.html.haml create mode 100644 db/migrate/20231208165729_add_ownable_id_to_token.rb diff --git a/app/controllers/canisters_controller.rb b/app/controllers/canisters_controller.rb index fe0e3313..6cef9cb2 100644 --- a/app/controllers/canisters_controller.rb +++ b/app/controllers/canisters_controller.rb @@ -3,7 +3,7 @@ class CanistersController < ApplicationController # GET /canisters or /canisters.json def index - @canisters = authorize Canister.all + authorize @canisters = policy_scope(Canister) end # GET /canisters/1 or /canisters/1.json diff --git a/app/controllers/tokens_controller.rb b/app/controllers/tokens_controller.rb index 6ac3cc34..507007c2 100644 --- a/app/controllers/tokens_controller.rb +++ b/app/controllers/tokens_controller.rb @@ -1,9 +1,10 @@ class TokensController < ApplicationController - before_action :set_token, only: %i[ show edit update destroy refresh ] + before_action :set_token, only: %i[ show edit update destroy refresh launch] # GET /tokens or /tokens.json def index authorize @tokens = Token.all + @mytokens = Token.where(ownable_id: current_user.soft_token) end # GET /tokens/1 or /tokens/1.json @@ -13,6 +14,10 @@ class TokensController < ApplicationController # GET /tokens/new def new + authorize @token = Token.new(ownable_id: current_user.soft_token) + end + + def add_existing authorize @token = Token.new end @@ -21,6 +26,11 @@ class TokensController < ApplicationController authorize @token end + def launch + authorize @token + redirect_to @token, notice: "Launch function coming soon!" + end + def refresh authorize @token # if call icrc1_metadata #icrc1 @@ -74,13 +84,13 @@ class TokensController < ApplicationController # POST /tokens or /tokens.json def create authorize @token = Token.new(token_params) - + @token.canister_id = nil if @token.canister_id.blank? respond_to do |format| if @token.save - format.html { redirect_to refresh_token_url(@token), notice: "Token was successfully created." } + format.html { redirect_to (request.referrer.split("/")[-1].match("add_existing") ? refresh_token_url(@token) : @token), notice: "Token was successfully created." } format.json { render :show, status: :created, location: @token } else - format.html { render :new, status: :unprocessable_entity } + format.html { render (request.referrer.split("/")[-1].match("add_existing") ? :add_existing : :new), status: :unprocessable_entity } format.json { render json: @token.errors, status: :unprocessable_entity } end end @@ -89,6 +99,7 @@ class TokensController < ApplicationController # PATCH/PUT /tokens/1 or /tokens/1.json def update authorize @token + @token.canister_id = nil if @token.canister_id.blank? respond_to do |format| if @token.update(token_params) format.html { redirect_to token_url(@token), notice: "Token was successfully updated." } @@ -119,6 +130,6 @@ class TokensController < ApplicationController # Only allow a list of trusted parameters through. def token_params - params.require(:token).permit(:canister_id, :standard, :symbol, :name, :total_supply, :decimals, :transfer_fee, :logo_url) + params.require(:token).permit(:canister_id, :standard, :symbol, :name, :total_supply, :decimals, :transfer_fee, :logo_url, :ownable_id) end end diff --git a/app/models/token.rb b/app/models/token.rb index 44732e25..5a6a21b4 100644 --- a/app/models/token.rb +++ b/app/models/token.rb @@ -1,6 +1,6 @@ class Token < ActiveRecord::Base enum standard: [:dip20, :icrc1, :unknown] - validates :canister_id, presence: true, uniqueness: true + validates :canister_id, uniqueness: true, allow_nil: true def transfer_fee_to_f if self.transfer_fee.present? diff --git a/app/policies/canister_policy.rb b/app/policies/canister_policy.rb index ac53019a..c0a87057 100644 --- a/app/policies/canister_policy.rb +++ b/app/policies/canister_policy.rb @@ -6,6 +6,26 @@ class CanisterPolicy @model = model end + class Scope + def initialize(user, scope) + @user = user + @scope = scope + end + + def resolve + if user.admin? + scope.all + else + scope.where(user: user) + end + end + + private + + attr_reader :user, :scope + end + + def index? @current_user.admin? || true end diff --git a/app/policies/token_policy.rb b/app/policies/token_policy.rb index 62fb4559..e4ec335a 100644 --- a/app/policies/token_policy.rb +++ b/app/policies/token_policy.rb @@ -34,26 +34,34 @@ class TokenPolicy end def create? - @user.admin? + @user.admin? || true end def new? - @user.admin? + @user.admin? || true + end + + def add_existing? + new? end def edit? - @user.admin? + @user.admin? || @token.ownable_id == @user.soft_token end def update? - @user.admin? + @user.admin? || edit? end def destroy? - @user.admin? + @user.admin? || @token.ownable_id == @user.soft_token end def refresh? - true + @token.canister_id.present? + end + + def launch? + @user.admin? || true end end diff --git a/app/views/layouts/_navigation_links.html.erb b/app/views/layouts/_navigation_links.html.erb index ecbc14bf..60602bf6 100644 --- a/app/views/layouts/_navigation_links.html.erb +++ b/app/views/layouts/_navigation_links.html.erb @@ -7,6 +7,7 @@
  • <%= link_to 'Tokens', tokens_path %>
  • <%= link_to 'Profiles', profiles_path %>
  • <%= link_to 'Projects', projects_path %>
  • +
  • <%= link_to 'Canisters', canisters_path %>
  • <%= link_to 'Doodads', doodads_path, data: { turbo: false } %>
  • <% if policy(:bot).index? %>
  • <%= link_to 'Bots', bots_path %>
  • diff --git a/app/views/tokens/_existing_token_form.html.haml b/app/views/tokens/_existing_token_form.html.haml new file mode 100644 index 00000000..fd58f14e --- /dev/null +++ b/app/views/tokens/_existing_token_form.html.haml @@ -0,0 +1,8 @@ += simple_form_for(@token) do |f| + = f.error_notification + + .form-inputs + = f.input :canister_id + + .form-actions + = f.button :submit, "Add Token" diff --git a/app/views/tokens/_form.html.haml b/app/views/tokens/_form.html.haml index 2ad851d8..367eb945 100644 --- a/app/views/tokens/_form.html.haml +++ b/app/views/tokens/_form.html.haml @@ -2,8 +2,9 @@ = f.error_notification .form-inputs - = f.input :canister_id - = f.input :standard + -# = f.input :canister_id + = f.select(:standard, Token.standards.keys.map {|standard| [standard.titleize,standard]}) + = f.hidden_field :ownable_id = f.input :symbol = f.input :name = f.input :total_supply @@ -11,5 +12,4 @@ = f.input :transfer_fee = f.input :logo_url - .form-actions - = f.button :submit, "Add Token" + = f.button :submit diff --git a/app/views/tokens/add_existing.html.haml b/app/views/tokens/add_existing.html.haml new file mode 100644 index 00000000..b2396023 --- /dev/null +++ b/app/views/tokens/add_existing.html.haml @@ -0,0 +1,5 @@ +%h1 Add existing token + += render 'existing_token_form' + += link_to 'Back', tokens_path diff --git a/app/views/tokens/index.html.haml b/app/views/tokens/index.html.haml index e6167069..1d9d70a9 100644 --- a/app/views/tokens/index.html.haml +++ b/app/views/tokens/index.html.haml @@ -1,9 +1,50 @@ +- if @mytokens.present? + .contain + %h1 My Tokens + + .table-container + .contain + %table.token-index + %thead + %tr + %th Logo + %th Symbol + %th Name + %th Canister + %th Standard + %th Total supply + %th Decimals + %th Transfer fee + - if policy(Token).new? + %th + %th + %th + + %tbody + - @mytokens.each do |token| + %tr + %td + = link_to token do + %img.token-logo{src: token.logo_url} + %td= link_to token.symbol, token + %td= token.name + %td= token.canister_id ? token.canister_id : "Prelaunch" + %td= token.standard + %td= token.total_supply + %td= token.decimals + %td= token.transfer_fee_to_f + - if policy(token).update? + %td= link_to 'Show', token + %td= link_to 'Edit', edit_token_path(token) + %td= link_to 'Destroy', token, method: :delete, data: { confirm: 'Are you sure?' } + .contain %h1 Listing tokens %div{style: "align-self: start;"} - if policy(Token).new? - = link_to 'Add Token', new_token_path + = link_to 'Add Existing Token', add_existing_new_token_path + = link_to 'Create New Token', new_token_path + "?create" .table-container .contain @@ -18,7 +59,7 @@ %th Total supply %th Decimals %th Transfer fee - - if policy(@tokens).update? + - if policy(Token).new? %th %th %th @@ -31,7 +72,7 @@ %img.token-logo{src: token.logo_url} %td= link_to token.symbol, token %td= token.name - %td= token.canister_id + %td= token.canister_id ? token.canister_id : "Prelaunch" %td= token.standard %td= token.total_supply %td= token.decimals diff --git a/app/views/tokens/new.html.haml b/app/views/tokens/new.html.haml index c5b566a1..5d2dfdf2 100644 --- a/app/views/tokens/new.html.haml +++ b/app/views/tokens/new.html.haml @@ -1,4 +1,5 @@ -%h1 Add token +.contain + %h1 Create new token = render 'form' diff --git a/app/views/tokens/show.html.haml b/app/views/tokens/show.html.haml index 54bdbee1..e7bc7da9 100644 --- a/app/views/tokens/show.html.haml +++ b/app/views/tokens/show.html.haml @@ -1,17 +1,29 @@ .contain %h1 = @token.name + Token - if policy(@token).edit? = link_to 'Edit', edit_token_path(@token) + - if policy(@token).destroy? = link_to 'Delete', @token, method: :delete, data: { confirm: 'Are you sure?' } - = link_to "Refresh Data", refresh_token_path(@token) + - if policy(@token).launch? + = button_to "Launch", launch_token_path(@token), method: :get + %span on IC mainnet + + - if policy(@token).refresh? + = link_to "Refresh Data", refresh_token_path(@token) .token-show - %p - %b Canister: - = @token.canister_id + - if @token.canister_id + %p + %b Canister: + = @token.canister_id + - else + %p + %b Status: + Prelaunch %p %b Logo: - if @token.logo_url.present? @@ -39,4 +51,7 @@ %p %b Holders: = @token.holder_number + %p + %b Owned by: + = @token.ownable_id diff --git a/config/routes.rb b/config/routes.rb index 24c6aa36..06aec63f 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -20,8 +20,10 @@ Rails.application.routes.draw do end end resources :tokens do + get 'add_existing', on: :new member do get 'refresh' + get 'launch' end end resources :projects diff --git a/db/migrate/20231208165729_add_ownable_id_to_token.rb b/db/migrate/20231208165729_add_ownable_id_to_token.rb new file mode 100644 index 00000000..b039536f --- /dev/null +++ b/db/migrate/20231208165729_add_ownable_id_to_token.rb @@ -0,0 +1,5 @@ +class AddOwnableIdToToken < ActiveRecord::Migration[7.1] + def change + add_column :tokens, :ownable_id, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index c814df3c..b31a27f8 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: 2023_12_08_104330) do +ActiveRecord::Schema[7.1].define(version: 2023_12_08_165729) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -251,6 +251,7 @@ ActiveRecord::Schema[7.1].define(version: 2023_12_08_104330) do t.datetime "updated_at", null: false t.string "logo_url" t.integer "holder_number" + t.string "ownable_id" t.index ["canister_id"], name: "index_tokens_on_canister_id", unique: true end