Merge pull request #2254 from mlorb/ml-sci-4029

Add numeric repository column type [SCI-4029]
This commit is contained in:
mlorb 2019-12-10 14:19:46 +01:00 committed by GitHub
commit 55b9a82ff0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 266 additions and 22 deletions

View file

@ -0,0 +1,13 @@
/* eslint-disable no-unused-vars */
var RepositoryNumberColumnType = (function() {
return {
init: () => {},
checkValidation: () => {
return true;
},
loadParams: () => {
var decimals = $('#decimals').val();
return { metadata: { decimals: decimals } };
}
};
}());

View file

@ -9,7 +9,8 @@ var RepositoryColumns = (function() {
RepositoryDateValue: 'RepositoryDateColumnType',
RepositoryDateTimeValue: 'RepositoryDateTimeColumnType',
RepositoryTimeValue: 'RepositoryDateTimeColumnType',
RepositoryChecklistValue: 'RepositoryChecklistColumnType'
RepositoryChecklistValue: 'RepositoryChecklistColumnType',
RepositoryNumberValue: 'RepositoryNumberColumnType'
};
function initColumnTypeSelector() {

View file

@ -0,0 +1,54 @@
# frozen_string_literal: true
module RepositoryColumns
class NumberColumnsController < BaseColumnsController
include InputSanitizeHelper
before_action :load_column, only: %i(update destroy)
before_action :check_create_permissions, only: :create
before_action :check_manage_permissions, only: %i(update destroy)
def create
service = RepositoryColumns::CreateColumnService
.call(user: current_user, repository: @repository, team: current_team,
column_type: Extends::REPOSITORY_DATA_TYPES[:RepositoryNumberValue],
params: repository_column_params)
if service.succeed?
render json: service.column, status: :created, creating: true
else
render json: service.errors, status: :unprocessable_entity
end
end
def update
service = RepositoryColumns::UpdateColumnService
.call(user: current_user,
team: current_team,
column: @repository_column,
params: repository_column_params)
if service.succeed?
render json: service.column, status: :ok, editing: true
else
render json: service.errors, status: :unprocessable_entity
end
end
def destroy
service = RepositoryColumns::DeleteColumnService
.call(user: current_user, team: current_team, column: @repository_column)
if service.succeed?
render json: {}, status: :ok
else
render json: service.errors, status: :unprocessable_entity
end
end
private
def repository_column_params
params.require(:repository_column).permit(:name, metadata: [:decimals])
end
end
end

View file

@ -14,6 +14,12 @@ class RepositoryCell < ApplicationRecord
.where(repository_cells: { value_type: 'RepositoryTextValue' })
end),
optional: true, foreign_key: :value_id
belongs_to :repository_number_value,
(lambda do
includes(:repository_cell)
.where(repository_cells: { value_type: 'RepositoryNumberValue' })
end),
optional: true, foreign_key: :value_id, inverse_of: :repository_cell
belongs_to :repository_date_time_value,
(lambda do
includes(:repository_cell)

View file

@ -0,0 +1,19 @@
# frozen_string_literal: true
class RepositoryNumberValue < ApplicationRecord
belongs_to :created_by, foreign_key: :created_by_id, class_name: 'User',
inverse_of: :created_repository_number_values
belongs_to :last_modified_by, foreign_key: :last_modified_by_id, class_name: 'User',
inverse_of: :modified_repository_number_values
has_one :repository_cell, as: :value, dependent: :destroy, inverse_of: :value
accepts_nested_attributes_for :repository_cell
validates :repository_cell, :data, presence: true
SORTABLE_COLUMN_NAME = 'repository_number_values.data'
SORTABLE_VALUE_INCLUDE = :repository_number_value
def formatted
data
end
end

View file

@ -264,6 +264,16 @@ class User < ApplicationRecord
foreign_key: 'last_modified_by_id',
inverse_of: :last_modified_by,
dependent: :nullify
has_many :created_repository_number_values,
class_name: 'RepositoryNumberValue',
foreign_key: 'created_by_id',
inverse_of: :created_by,
dependent: :nullify
has_many :modified_repository_number_values,
class_name: 'RepositoryNumberValue',
foreign_key: 'last_modified_by_id',
inverse_of: :last_modified_by,
dependent: :nullify
has_many :user_notifications, inverse_of: :user
has_many :notifications, through: :user_notifications

View file

@ -0,0 +1,11 @@
# frozen_string_literal: true
module RepositoryDatatable
class RepositoryNumberValueSerializer < ActiveModel::Serializer
attributes :value, :value_type
def value
object.repository_number_value.data
end
end
end

View file

@ -37,6 +37,12 @@
<%= 'selected' if @repository_column.repository_text_value? %> >
<%= t('libraries.manange_modal_column.select.repository_text_value') %>
</option>
<option data-create-url="<%= repository_repository_columns_number_columns_path(@repository) %>"
data-edit-url="<%= repository_repository_columns_number_column_path(@repository, @repository_column) unless @repository_column.new_record? %>"
value="RepositoryNumberValue"
<%= 'selected' if @repository_column.repository_number_value? %> >
<%= t('libraries.manange_modal_column.select.repository_number_value') %>
</option>
<option data-create-url="<%= repository_repository_columns_asset_columns_path(@repository) %>"
data-edit-url="<%= repository_repository_columns_asset_column_path(@repository, @repository_column) unless @repository_column.new_record? %>"
value="RepositoryAssetValue"
@ -52,6 +58,12 @@
<%= 'selected' if @repository_column.repository_list_value? %> >
<%= t('libraries.manange_modal_column.select.repository_list_value') %>
</option>
<option data-create-url="<%= repository_repository_columns_checklist_columns_path(@repository) %>"
data-edit-url="<%= repository_repository_columns_checklist_column_path(@repository, @repository_column) unless @repository_column.new_record? %>"
value="RepositoryChecklistValue"
<%= 'selected' if @repository_column.repository_checklist_value? %> >
<%= t('libraries.manange_modal_column.select.repository_checklist_value') %>
</option>
<option data-create-url="<%= repository_repository_columns_status_columns_path(@repository) %>"
data-edit-url="<%= repository_repository_columns_status_column_path(@repository, @repository_column) unless @repository_column.new_record? %>"
value="RepositoryStatusValue"
@ -61,36 +73,29 @@
<option data-delimiter=true></option>
<option data-create-url="<%= repository_repository_columns_date_time_columns_path(@repository) %>"
data-edit-url="<%= repository_repository_columns_date_time_column_path(@repository, @repository_column) unless @repository_column.new_record? %>"
value="RepositoryDateTimeValue"
<%= 'selected' if @repository_column.repository_date_time_value? || @repository_column.repository_date_time_range_value? %> >
<%= t('libraries.manange_modal_column.select.repository_date_time_value') %>
</option>
<option data-create-url="<%= repository_repository_columns_date_time_columns_path(@repository) %>"
data-edit-url="<%= repository_repository_columns_date_time_column_path(@repository, @repository_column) unless @repository_column.new_record? %>"
value="RepositoryDateValue"
<%= 'selected' if @repository_column.repository_date_value? || @repository_column.repository_date_range_value? %> >
<%= t('libraries.manange_modal_column.select.repository_date_value') %>
</option>
<option data-create-url="<%= repository_repository_columns_date_time_columns_path(@repository) %>"
data-edit-url="<%= repository_repository_columns_date_time_column_path(@repository, @repository_column) unless @repository_column.new_record? %>"
value="RepositoryTimeValue"
<%= 'selected' if @repository_column.repository_time_value? || @repository_column.repository_time_range_value? %> >
<%= t('libraries.manange_modal_column.select.repository_time_value') %>
<option data-create-url="<%= repository_repository_columns_date_time_columns_path(@repository) %>"
data-edit-url="<%= repository_repository_columns_date_time_column_path(@repository, @repository_column) unless @repository_column.new_record? %>"
value="RepositoryDateTimeValue"
<%= 'selected' if @repository_column.repository_date_time_value? || @repository_column.repository_date_time_range_value? %> >
<%= t('libraries.manange_modal_column.select.repository_date_time_value') %>
</option>
<option data-create-url="<%= repository_repository_columns_checklist_columns_path(@repository) %>"
data-edit-url="<%= repository_repository_columns_checklist_column_path(@repository, @repository_column) unless @repository_column.new_record? %>"
value="RepositoryChecklistValue"
<%= 'selected' if @repository_column.repository_checklist_value? %> >
<%= t('libraries.manange_modal_column.select.repository_checklist_value') %>
</option>
</select>
</div>
</div>
<hr/>
<% columns = ['text', 'asset', 'list', 'status', 'date', 'time', 'datetime', 'checklist'] %>
<% columns = ['text', 'number', 'asset', 'list', 'status', 'date', 'time', 'datetime', 'checklist'] %>
<% columns.each do |column| %>
<span style="display: none" class="column-type <%= column %>-column-type" data-column-type="Repository<%= column.capitalize %>Value">
<%= render partial: "repository_columns/manage_column_partials/#{column}.html.erb", locals: {column: @repository_column} %>

View file

@ -0,0 +1,11 @@
<% selected_decimals = column.metadata['decimals'] || '0' %>
<div class="form-group">
<label class="control-label col-sm-3" for="repository-column-data-type">
<%= t('libraries.manange_modal_column.number_type.decimals_label') %>
</label>
<div class="col-sm-3">
<%= number_field_tag('decimals', selected_decimals, in: 0...Constants::REPOSITORY_NUMBER_TYPE_MAX_DECIMALS,
class: 'form-control') %>
</div>
</div>

View file

@ -976,6 +976,7 @@ class Constants
EXPORTABLE_ZIP_EXPIRATION_DAYS = 7
REPOSITORY_LIST_ITEMS_PER_COLUMN = 500
REPOSITORY_NUMBER_TYPE_MAX_DECIMALS = 11
REPOSITORY_LIST_ITEMS_DELIMITERS_MAP = {
return: "\n",

View file

@ -52,7 +52,8 @@ class Extends
RepositoryDateTimeRangeValue: 7,
RepositoryTimeRangeValue: 8,
RepositoryDateRangeValue: 9,
RepositoryChecklistValue: 10 }
RepositoryChecklistValue: 10,
RepositoryNumberValue: 11 }
# Data types which can be imported to repository,
# name should match record in REPOSITORY_DATA_TYPES

View file

@ -1136,6 +1136,7 @@ en:
dropdown_item_descirption: "Dropdown items should be separated by comma."
select:
repository_text_value: "Text"
repository_number_value: "Number"
repository_date_value: "Date"
repository_time_value: "Time"
repository_date_time_value: "Date & Time"
@ -1149,6 +1150,8 @@ en:
edit:
title: "Edit %{name} Column"
button: "Update column"
number_type:
decimals_label: "Decimal digits"
list_type:
delimiter_label: "Delimiter"
dropdown_items_label: "Dropdown items"

View file

@ -580,12 +580,11 @@ Rails.application.routes.draw do
end
namespace :repository_columns do
resources :text_columns, only: %i(create update destroy)
resources :number_columns, only: %i(create update destroy)
resources :list_columns, only: %i(create update destroy)
resources :asset_columns, only: %i(create update destroy)
resources :date_columns, only: %i(create update destroy)
resources :status_columns, only: %i(create update destroy)
resources :list_columns, only: %i(create update destroy)
resources :asset_columns, only: %i(create update destroy)
resources :date_time_columns, only: %i(create update destroy)
resources :checklist_columns, only: %i(create update destroy)
end

View file

@ -0,0 +1,13 @@
# frozen_string_literal: true
class CreateRepositoryNumberValue < ActiveRecord::Migration[6.0]
def change
create_table :repository_number_values do |t|
t.decimal :data, index: true
t.references :last_modified_by, index: true, foreign_key: { to_table: :users }
t.references :created_by, index: true, foreign_key: { to_table: :users }
t.timestamps
end
end
end

View file

@ -0,0 +1,7 @@
# frozen_string_literal: true
class AddMetadataToRepositoryColumn < ActiveRecord::Migration[6.0]
def change
add_column :repository_columns, :metadata, :jsonb, default: {}, null: false
end
end

View file

@ -1257,7 +1257,8 @@ CREATE TABLE public.repository_columns (
data_type integer NOT NULL,
created_at timestamp without time zone,
updated_at timestamp without time zone,
delimiter character varying
delimiter character varying,
metadata jsonb DEFAULT '{}'::jsonb NOT NULL
);
@ -1417,6 +1418,39 @@ CREATE SEQUENCE public.repository_list_values_id_seq
ALTER SEQUENCE public.repository_list_values_id_seq OWNED BY public.repository_list_values.id;
--
-- Name: repository_number_values; Type: TABLE; Schema: public; Owner: -
--
CREATE TABLE public.repository_number_values (
id bigint NOT NULL,
data numeric,
last_modified_by_id bigint,
created_by_id bigint,
created_at timestamp(6) without time zone NOT NULL,
updated_at timestamp(6) without time zone NOT NULL
);
--
-- Name: repository_number_values_id_seq; Type: SEQUENCE; Schema: public; Owner: -
--
CREATE SEQUENCE public.repository_number_values_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
--
-- Name: repository_number_values_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
--
ALTER SEQUENCE public.repository_number_values_id_seq OWNED BY public.repository_number_values.id;
--
-- Name: repository_rows; Type: TABLE; Schema: public; Owner: -
--
@ -2988,6 +3022,13 @@ ALTER TABLE ONLY public.repository_list_items ALTER COLUMN id SET DEFAULT nextva
ALTER TABLE ONLY public.repository_list_values ALTER COLUMN id SET DEFAULT nextval('public.repository_list_values_id_seq'::regclass);
--
-- Name: repository_number_values id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY public.repository_number_values ALTER COLUMN id SET DEFAULT nextval('public.repository_number_values_id_seq'::regclass);
--
-- Name: repository_rows id; Type: DEFAULT; Schema: public; Owner: -
--
@ -3557,6 +3598,14 @@ ALTER TABLE ONLY public.repository_list_values
ADD CONSTRAINT repository_list_values_pkey PRIMARY KEY (id);
--
-- Name: repository_number_values repository_number_values_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public.repository_number_values
ADD CONSTRAINT repository_number_values_pkey PRIMARY KEY (id);
--
-- Name: repository_rows repository_rows_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
@ -4822,6 +4871,27 @@ CREATE INDEX index_repository_list_values_on_last_modified_by_id ON public.repos
CREATE INDEX index_repository_list_values_on_repository_list_item_id ON public.repository_list_values USING btree (repository_list_item_id);
--
-- Name: index_repository_number_values_on_created_by_id; Type: INDEX; Schema: public; Owner: -
--
CREATE INDEX index_repository_number_values_on_created_by_id ON public.repository_number_values USING btree (created_by_id);
--
-- Name: index_repository_number_values_on_data; Type: INDEX; Schema: public; Owner: -
--
CREATE INDEX index_repository_number_values_on_data ON public.repository_number_values USING btree (data);
--
-- Name: index_repository_number_values_on_last_modified_by_id; Type: INDEX; Schema: public; Owner: -
--
CREATE INDEX index_repository_number_values_on_last_modified_by_id ON public.repository_number_values USING btree (last_modified_by_id);
--
-- Name: index_repository_rows_on_name; Type: INDEX; Schema: public; Owner: -
--
@ -5879,6 +5949,14 @@ ALTER TABLE ONLY public.step_assets
ADD CONSTRAINT fk_rails_38ebde94cb FOREIGN KEY (step_id) REFERENCES public.steps(id);
--
-- Name: repository_number_values fk_rails_3df53c9b27; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public.repository_number_values
ADD CONSTRAINT fk_rails_3df53c9b27 FOREIGN KEY (created_by_id) REFERENCES public.users(id);
--
-- Name: projects fk_rails_47aee20018; Type: FK CONSTRAINT; Schema: public; Owner: -
--
@ -6223,6 +6301,14 @@ ALTER TABLE ONLY public.reports
ADD CONSTRAINT fk_rails_8e98747719 FOREIGN KEY (last_modified_by_id) REFERENCES public.users(id);
--
-- Name: repository_number_values fk_rails_8f8a2f87f1; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public.repository_number_values
ADD CONSTRAINT fk_rails_8f8a2f87f1 FOREIGN KEY (last_modified_by_id) REFERENCES public.users(id);
--
-- Name: repository_list_values fk_rails_903285a9b0; Type: FK CONSTRAINT; Schema: public; Owner: -
--
@ -7030,6 +7116,10 @@ INSERT INTO "schema_migrations" (version) VALUES
('20191009146101'),
('20191105143702'),
('20191115143747'),
('20191204112549'),
('20191205133447'),
('20191205133522');
('20191206105058');
('20191205133522'),
('20191206105058'),
('20191210103004');