mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-09-27 15:36:39 +08:00
Merge pull request #8258 from andrej-scinote/aj_SCI_11558
Create new item from task [SCI-11558]
This commit is contained in:
commit
b25ebf4324
10 changed files with 202 additions and 13 deletions
|
@ -82,9 +82,27 @@ class RepositoryRowsController < ApplicationController
|
|||
record_annotation_notification(repository_row, repository_cell)
|
||||
end
|
||||
|
||||
if update_params[:my_module_id].present?
|
||||
my_module = MyModule.viewable_by_user(current_user, current_team).find_by(id: update_params[:my_module_id])
|
||||
|
||||
return render_403 unless my_module.present? && can_read_my_module?(my_module)
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
service_assign = RepositoryRows::MyModuleAssignUnassignService.call(
|
||||
my_module: my_module,
|
||||
repository: @repository,
|
||||
user: current_user,
|
||||
params: { rows_to_assign: [repository_row.id] }
|
||||
)
|
||||
|
||||
render json: service_assign.errors, status: :bad_request unless service_assign.succeed?
|
||||
end
|
||||
end
|
||||
|
||||
render json: { id: service.repository_row.id, flash: t('repositories.create.success_flash',
|
||||
record: escape_input(repository_row.name),
|
||||
repository: escape_input(@repository.name)) },
|
||||
repository: escape_input(@repository.name)),
|
||||
repository_row_url: repository_repository_row_path(@repository, repository_row) },
|
||||
status: :ok
|
||||
else
|
||||
render json: service.errors, status: :bad_request
|
||||
|
@ -480,7 +498,7 @@ class RepositoryRowsController < ApplicationController
|
|||
end
|
||||
|
||||
def update_params
|
||||
params.permit(repository_row: :name, repository_cells: {}).to_h
|
||||
params.permit(:my_module_id, :is_output, repository_row: :name, repository_cells: {}).to_h
|
||||
end
|
||||
|
||||
def log_activity(type_of, repository_row, message_items = {})
|
||||
|
|
|
@ -108,7 +108,7 @@ module RepositoryDatatableHelper
|
|||
repository_rows.map do |record|
|
||||
row = {
|
||||
DT_RowId: record.id,
|
||||
DT_RowAttr: { 'data-state': row_style(record) },
|
||||
DT_RowAttr: { 'data-state': simple_row_style(record, my_module) },
|
||||
'0': escape_input(record.name),
|
||||
recordInfoUrl: Rails.application.routes.url_helpers.repository_repository_row_path(record.repository, record),
|
||||
rowRemindersUrl:
|
||||
|
@ -305,6 +305,14 @@ module RepositoryDatatableHelper
|
|||
''
|
||||
end
|
||||
|
||||
def simple_row_style(row, my_module)
|
||||
style = []
|
||||
style << I18n.t('general.archived') if row.archived
|
||||
style << I18n.t('general.output') if row.output? && row.my_module.id == my_module&.id
|
||||
|
||||
style
|
||||
end
|
||||
|
||||
def stock_consumption_permitted?(repository, my_module)
|
||||
return false unless repository.is_a?(Repository) && current_user
|
||||
|
||||
|
|
|
@ -6,7 +6,10 @@
|
|||
{{ i18n.t('my_modules.assigned_items.title') }}
|
||||
<span class="text-sn-grey-500 font-normal text-base">[{{ totalRows }}]</span>
|
||||
</h2>
|
||||
<div class="ml-auto">
|
||||
<div class="flex gap-6 ml-auto">
|
||||
<button class="btn btn-secondary" @click="openCreateItemModal=true">
|
||||
{{ i18n.t('my_modules.assigned_items.create_item') }}
|
||||
</button>
|
||||
<!-- Next block just for legacy support, JQuery not good works with Teleport -->
|
||||
<div class="hidden repository-assign"
|
||||
v-for="repository in availableRepositories"
|
||||
|
@ -20,8 +23,9 @@
|
|||
<!-- End of block -->
|
||||
<GeneralDropdown position="right" @open="loadAvailableRepositories">
|
||||
<template v-slot:field>
|
||||
<button class="btn btn-light">
|
||||
<button class="btn btn-secondary">
|
||||
{{ i18n.t('my_modules.assigned_items.assign_from') }}
|
||||
<span class="sn-icon sn-icon-down"></span>
|
||||
</button>
|
||||
</template>
|
||||
<template v-slot:flyout>
|
||||
|
@ -52,6 +56,15 @@
|
|||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Teleport to="body">
|
||||
<CreateItemModal
|
||||
v-if="openCreateItemModal"
|
||||
:repositoriesUrl="repositoriesUrl"
|
||||
:myModuleId="myModuleId"
|
||||
@tableReloaded="newCreatedRow"
|
||||
@close="openCreateItemModal = false"/>
|
||||
</Teleport>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -59,16 +72,20 @@
|
|||
import axios from '../../packs/custom_axios.js';
|
||||
import GeneralDropdown from '../shared/general_dropdown.vue';
|
||||
import AssignedRepository from './assigned_items/repository.vue';
|
||||
import CreateItemModal from './assigned_items/modals/new_item.vue';
|
||||
|
||||
export default {
|
||||
name: 'AssignedItems',
|
||||
props: {
|
||||
avaialableRepositoriesUrl: String,
|
||||
assignedRepositoriesUrl: String
|
||||
assignedRepositoriesUrl: String,
|
||||
repositoriesUrl: String,
|
||||
myModuleId: String
|
||||
},
|
||||
components: {
|
||||
GeneralDropdown,
|
||||
AssignedRepository
|
||||
AssignedRepository,
|
||||
CreateItemModal
|
||||
},
|
||||
created() {
|
||||
this.loadAssingedRepositories();
|
||||
|
@ -83,7 +100,8 @@ export default {
|
|||
availableRepositories: [],
|
||||
assignedRepositories: [],
|
||||
loadingAvailableRepositories: false,
|
||||
sectionOpened: false
|
||||
sectionOpened: false,
|
||||
openCreateItemModal: false
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
|
@ -111,6 +129,10 @@ export default {
|
|||
this.assignedRepositories = response.data.data;
|
||||
});
|
||||
},
|
||||
newCreatedRow(repositoryRowSidebarUrl) {
|
||||
this.loadAssingedRepositories();
|
||||
window.repositoryItemSidebarComponent.toggleShowHideSidebar(repositoryRowSidebarUrl, this.myModuleId, null);
|
||||
},
|
||||
openAssignModal(repositoryId) {
|
||||
const [repository] = this.$refs[`repository_${repositoryId}`];
|
||||
repository.click();
|
||||
|
|
112
app/javascript/vue/my_module/assigned_items/modals/new_item.vue
Normal file
112
app/javascript/vue/my_module/assigned_items/modals/new_item.vue
Normal file
|
@ -0,0 +1,112 @@
|
|||
<template>
|
||||
<div ref="modal" class="modal" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog" role="document">
|
||||
<form @submit.prevent="submit">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<i class="sn-icon sn-icon-close"></i>
|
||||
</button>
|
||||
<h4 class="modal-title truncate !block" >
|
||||
{{ i18n.t('my_modules.assigned_items.create_modal.modal_title') }}
|
||||
</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p class="mb-6">{{ i18n.t('my_modules.assigned_items.create_modal.description') }}</p>
|
||||
<div class="mb-6">
|
||||
<label class="sci-label">
|
||||
{{ i18n.t('my_modules.assigned_items.create_modal.inventory_label') }}
|
||||
</label>
|
||||
<SelectDropdown :optionsUrl="repositoriesUrl" @change="changeRepository" :searchable="true" />
|
||||
</div>
|
||||
<div class="mb-6">
|
||||
<label class="sci-label">
|
||||
{{ i18n.t('my_modules.assigned_items.create_modal.inventory_item_name') }}
|
||||
</label>
|
||||
<div class="sci-input-container-v2">
|
||||
<input
|
||||
type="text"
|
||||
v-model="inventoryItemName"
|
||||
:placeholder="i18n.t('my_modules.assigned_items.create_modal.inventory_item_name')"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-2.5">
|
||||
<span class="sci-checkbox-container">
|
||||
<input type="checkbox"
|
||||
class="sci-checkbox"
|
||||
v-model="outputMarked" />
|
||||
<span class="sci-checkbox-label"></span>
|
||||
</span>
|
||||
{{ i18n.t('my_modules.assigned_items.create_modal.checkbox_label') }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">{{ i18n.t('general.cancel') }}</button>
|
||||
<button class="btn btn-primary" :disabled="submitting || !validObject" type="submit">
|
||||
{{ i18n.t('my_modules.assigned_items.create_modal.create_item') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import axios from '../../../../packs/custom_axios.js';
|
||||
import SelectDropdown from '../../../shared/select_dropdown.vue';
|
||||
import modalMixin from '../../../shared/modal_mixin.js';
|
||||
import {
|
||||
repository_repository_rows_path
|
||||
} from '../../../../routes.js';
|
||||
|
||||
export default {
|
||||
name: 'CreateItemModal',
|
||||
props: {
|
||||
repositoriesUrl: String,
|
||||
myModuleId: String
|
||||
},
|
||||
mixins: [modalMixin],
|
||||
components: {
|
||||
SelectDropdown
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
selectedRepository: null,
|
||||
inventoryItemName: '',
|
||||
outputMarked: false,
|
||||
submitting: false
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
validObject() {
|
||||
return this.selectedRepository && this.inventoryItemName;
|
||||
}
|
||||
},
|
||||
created() {
|
||||
},
|
||||
mounted() {
|
||||
},
|
||||
methods: {
|
||||
changeRepository(repository) {
|
||||
this.selectedRepository = repository;
|
||||
},
|
||||
submit() {
|
||||
this.submitting = true;
|
||||
axios.post(repository_repository_rows_path(this.selectedRepository), {
|
||||
repository_row: { name: this.inventoryItemName },
|
||||
my_module_id: this.myModuleId,
|
||||
is_output: this.outputMarked
|
||||
}).then((data) => {
|
||||
this.$emit('tableReloaded', data.data.repository_row_url);
|
||||
this.submitting = false;
|
||||
this.close();
|
||||
}).catch(() => {
|
||||
this.submitting = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
|
@ -10,14 +10,16 @@
|
|||
<ul v-html="reminders" class="list-none pl-0"></ul>
|
||||
</template>
|
||||
</GeneralDropdown>
|
||||
<a class="hover:no-underline flex items-center gap-1 record-info-link"
|
||||
<a class="hover:no-underline record-info-link truncate block"
|
||||
:title="params.data[0]"
|
||||
:href="params.data.recordInfoUrl"
|
||||
>
|
||||
<span class="truncate">
|
||||
{{ params.data[0] }}
|
||||
</span>
|
||||
{{ params.data[0] }}
|
||||
</a>
|
||||
|
||||
<span v-for="state in params.data.DT_RowAttr['data-state']" class="text-sn-grey bg-sn-light-grey text-xs px-1.5 py-1 ">
|
||||
{{ state }}
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ class RepositoryRow < ApplicationRecord
|
|||
class_name: 'User',
|
||||
inverse_of: :restored_repository_rows,
|
||||
optional: true
|
||||
belongs_to :my_module, optional: true
|
||||
has_many :repository_cells, -> { order(:id) }, inverse_of: :repository_row, dependent: :destroy
|
||||
|
||||
{
|
||||
|
@ -238,4 +239,8 @@ class RepositoryRow < ApplicationRecord
|
|||
def archived_branch?
|
||||
archived?
|
||||
end
|
||||
|
||||
def output?
|
||||
my_module_id.present?
|
||||
end
|
||||
end
|
||||
|
|
|
@ -6,12 +6,13 @@ module RepositoryRows
|
|||
|
||||
attr_reader :repository, :params, :errors, :repository_row
|
||||
|
||||
def initialize(repository:, user:, params:)
|
||||
def initialize(repository:, user:, params:, my_module: nil)
|
||||
@repository = repository
|
||||
@user = user
|
||||
@params = params
|
||||
@errors = {}
|
||||
@repository_row = nil
|
||||
@my_module = my_module
|
||||
end
|
||||
|
||||
def call
|
||||
|
@ -20,7 +21,9 @@ module RepositoryRows
|
|||
ActiveRecord::Base.transaction do
|
||||
@repository_row = @repository.repository_rows.new(params[:repository_row])
|
||||
@repository_row.last_modified_by = @user
|
||||
@repository_row.my_module = @my_module
|
||||
@repository_row.created_by = @user
|
||||
@repository_row.my_module_id = params[:my_module_id] if params[:my_module_id] && params[:is_output]
|
||||
@repository_row.save!
|
||||
|
||||
params[:repository_cells]&.each do |column_id, value|
|
||||
|
|
|
@ -84,6 +84,8 @@
|
|||
ref="assignedItems"
|
||||
avaialable-repositories-url="<%= my_module_repositories_dropdown_list_path(@my_module) %>"
|
||||
assigned-repositories-url="<%= my_module_repositories_list_path(@my_module) %>"
|
||||
repositories-url="<%= list_team_repositories_path(current_team) %>"
|
||||
my-module-id="<%= @my_module.id%>"
|
||||
/>
|
||||
</div>
|
||||
<!-- Assigned items -->
|
||||
|
|
|
@ -1326,6 +1326,15 @@ en:
|
|||
assigned_items:
|
||||
title: "Assigned items"
|
||||
assign_from: "Assign from"
|
||||
create_item: "Create item"
|
||||
create_modal:
|
||||
modal_title: 'Create a new item'
|
||||
description: 'Choose an inventory and name the new item'
|
||||
inventory_label: 'Inventory'
|
||||
inventory_placeholder: 'Select inventory'
|
||||
inventory_item_name: 'Item name'
|
||||
create_item: 'Create item'
|
||||
checkbox_label: 'Mark as output'
|
||||
direct_assign:
|
||||
success: "Successfully assigned an item to the task."
|
||||
protocol:
|
||||
|
@ -4435,6 +4444,7 @@ en:
|
|||
archive: "Archive"
|
||||
assign: "Assign"
|
||||
options_selected: 'options selected'
|
||||
output: 'Output'
|
||||
# In order to use the strings 'yes' and 'no' as keys, you need to wrap them with quotes
|
||||
'yes': "Yes"
|
||||
'no': "No"
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddMyModuleToRepositoryRow < ActiveRecord::Migration[7.0]
|
||||
def change
|
||||
add_reference :repository_rows, :my_module, null: true, foreign_key: true
|
||||
end
|
||||
end
|
Loading…
Add table
Reference in a new issue