mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-12-16 05:42:13 +08:00
Merge branch 'features/september-release' into ma_SCI_9013
This commit is contained in:
commit
e1416e3efd
39 changed files with 477 additions and 57 deletions
|
|
@ -51,9 +51,6 @@ body.navigator-collapsed {
|
|||
.sci--layout-navigation-top {
|
||||
grid-area: top;
|
||||
height: var(--top-navigation-height);
|
||||
position: sticky;
|
||||
position: -webkit-sticky;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
z-index: 610;
|
||||
}
|
||||
|
|
@ -69,13 +66,14 @@ body.navigator-collapsed {
|
|||
}
|
||||
|
||||
.sci--layout-navigation-navigator {
|
||||
--navigator-top-margin: 0px;
|
||||
background-color: var(--sn-white);
|
||||
grid-area: navigator;
|
||||
height: calc(100vh - var(--top-navigation-height) - var(--breadcrumbs-navigation-height) - 1rem);
|
||||
height: calc(100vh - var(--navbar-height) - 1rem - var(--navigator-top-margin));
|
||||
position: sticky;
|
||||
position: -webkit-sticky;
|
||||
top: calc(var(--top-navigation-height) + var(--breadcrumbs-navigation-height));
|
||||
transition: .4s $timing-function-sharp;
|
||||
top: 1rem;
|
||||
transition: width .4s $timing-function-sharp;
|
||||
width: var(--navigator-navigation-width);
|
||||
z-index: 550;
|
||||
}
|
||||
|
|
@ -84,9 +82,6 @@ body.navigator-collapsed {
|
|||
background-color: var(--sn-white);
|
||||
grid-area: breadcrumbs;
|
||||
height: var(--breadcrumbs-navigation-height);
|
||||
position: sticky;
|
||||
position: -webkit-sticky;
|
||||
top: var(--top-navigation-height);
|
||||
transition: .4s $timing-function-sharp;
|
||||
width: 100%;
|
||||
z-index: 600;
|
||||
|
|
@ -104,6 +99,8 @@ body.navigator-collapsed {
|
|||
}
|
||||
|
||||
&[data-grey-background="true"] {
|
||||
background-color: var(--sn-super-light-grey);
|
||||
|
||||
.sci--layout-content,
|
||||
.sci--layout-navigation-breadcrumbs,
|
||||
.sci--layout-navigation-navigator {
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
background-color: inherit;
|
||||
position: sticky;
|
||||
position: -webkit-sticky;
|
||||
top: var(--navbar-height);
|
||||
top: 0;
|
||||
z-index: 250;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,10 @@ module ResultElements
|
|||
before_action :load_result_and_my_module
|
||||
before_action :check_manage_permissions
|
||||
|
||||
def move_targets
|
||||
render json: { targets: @my_module.results.where.not(id: @result.id).map{ |i| [i.id, i.name] } }
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def load_result_and_my_module
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
module ResultElements
|
||||
class TablesController < BaseController
|
||||
before_action :load_table, only: %i(update destroy duplicate)
|
||||
before_action :load_table, only: %i(update destroy duplicate move)
|
||||
|
||||
def create
|
||||
predefined_table_dimensions = create_table_params[:tableDimensions].map(&:to_i)
|
||||
|
|
@ -57,6 +57,19 @@ module ResultElements
|
|||
head :unprocessable_entity
|
||||
end
|
||||
|
||||
def move
|
||||
target = @my_module.results.find_by(id: params[:target_id])
|
||||
result_table = @table.result_table
|
||||
ActiveRecord::Base.transaction do
|
||||
result_table.update!(result: target)
|
||||
result_table.result_orderable_element.update!(result: target, position: target.result_orderable_elements.size)
|
||||
@result.normalize_elements_position
|
||||
render json: @table, serializer: ResultTableSerializer, user: current_user
|
||||
rescue ActiveRecord::RecordInvalid
|
||||
render json: result_table.errors, status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
if @table.destroy
|
||||
#log_step_activity(:table_deleted, { table_name: @table.name })
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ module ResultElements
|
|||
include InputSanitizeHelper
|
||||
include Rails.application.routes.url_helpers
|
||||
|
||||
before_action :load_result_text, only: %i(update destroy duplicate)
|
||||
before_action :load_result_text, only: %i(update destroy duplicate move)
|
||||
|
||||
def create
|
||||
result_text = @result.result_texts.build
|
||||
|
|
@ -36,6 +36,18 @@ module ResultElements
|
|||
render json: @result_text.errors, status: :unprocessable_entity
|
||||
end
|
||||
|
||||
def move
|
||||
target = @my_module.results.find_by(id: params[:target_id])
|
||||
ActiveRecord::Base.transaction do
|
||||
@result_text.update!(result: target)
|
||||
@result_text.result_orderable_element.update!(result: target, position: target.result_orderable_elements.size)
|
||||
@result.normalize_elements_position
|
||||
render json: @result_text, serializer: ResultTextSerializer, user: current_user
|
||||
rescue ActiveRecord::RecordInvalid
|
||||
render json: @result_text.errors, status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
if @result_text.destroy
|
||||
log_step_activity(:text_deleted, { text_name: @result_text.name })
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ResultsController < ApplicationController
|
||||
skip_before_action :verify_authenticity_token, only: %i(create update destroy)
|
||||
|
||||
before_action :load_my_module
|
||||
before_action :load_vars, only: %i(destroy elements assets upload_attachment update_view_state update_asset_view_mode update)
|
||||
before_action :check_destroy_permissions, only: :destroy
|
||||
|
|
|
|||
|
|
@ -5,6 +5,11 @@ module StepElements
|
|||
before_action :load_step_and_protocol
|
||||
before_action :check_manage_permissions
|
||||
|
||||
|
||||
def move_targets
|
||||
render json: { targets: @protocol.steps.order(:position).where.not(id: @step.id).map{|i| [i.id, i.name] } }
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def load_step_and_protocol
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ module StepElements
|
|||
class ChecklistsController < BaseController
|
||||
include ApplicationHelper
|
||||
include StepsActions
|
||||
before_action :load_checklist, only: %i(update destroy duplicate)
|
||||
before_action :load_checklist, only: %i(update destroy duplicate move)
|
||||
def create
|
||||
checklist = @step.checklists.build(
|
||||
name: t('protocols.steps.checklist.default_name', position: @step.checklists.length + 1)
|
||||
|
|
@ -32,6 +32,18 @@ module StepElements
|
|||
head :unprocessable_entity
|
||||
end
|
||||
|
||||
def move
|
||||
target = @protocol.steps.find_by(id: params[:target_id])
|
||||
ActiveRecord::Base.transaction do
|
||||
@checklist.update!(step: target)
|
||||
@checklist.step_orderable_element.update!(step: target, position: target.step_orderable_elements.size)
|
||||
@step.normalize_elements_position
|
||||
render json: @checklist, serializer: ChecklistSerializer, user: current_user
|
||||
rescue ActiveRecord::RecordInvalid
|
||||
render json: @checklist.errors, status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
if @checklist.destroy
|
||||
log_step_activity(:checklist_deleted, { checklist_name: @checklist.name })
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
module StepElements
|
||||
class TablesController < BaseController
|
||||
before_action :load_table, only: %i(update destroy duplicate)
|
||||
before_action :load_table, only: %i(update destroy duplicate move)
|
||||
|
||||
def create
|
||||
predefined_table_dimensions = create_table_params[:tableDimensions].map(&:to_i)
|
||||
|
|
@ -57,6 +57,19 @@ module StepElements
|
|||
head :unprocessable_entity
|
||||
end
|
||||
|
||||
def move
|
||||
target = @protocol.steps.find_by(id: params[:target_id])
|
||||
step_table = @table.step_table
|
||||
ActiveRecord::Base.transaction do
|
||||
step_table.update!(step: target)
|
||||
step_table.step_orderable_element.update!(step: target, position: target.step_orderable_elements.size)
|
||||
@step.normalize_elements_position
|
||||
render json: @table, serializer: TableSerializer, user: current_user
|
||||
rescue ActiveRecord::RecordInvalid
|
||||
render json: step_table.errors, status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
if @table.destroy
|
||||
log_step_activity(:table_deleted, { table_name: @table.name })
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ module StepElements
|
|||
include ApplicationHelper
|
||||
include StepsActions
|
||||
|
||||
before_action :load_step_text, only: %i(update destroy duplicate)
|
||||
before_action :load_step_text, only: %i(update destroy duplicate move)
|
||||
|
||||
def create
|
||||
step_text = @step.step_texts.build
|
||||
|
|
@ -34,6 +34,18 @@ module StepElements
|
|||
render json: @step_text.errors, status: :unprocessable_entity
|
||||
end
|
||||
|
||||
def move
|
||||
target = @protocol.steps.find_by(id: params[:target_id])
|
||||
ActiveRecord::Base.transaction do
|
||||
@step_text.update!(step: target)
|
||||
@step_text.step_orderable_element.update!(step: target, position: target.step_orderable_elements.size)
|
||||
@step.normalize_elements_position
|
||||
render json: @step_text, serializer: StepTextSerializer, user: current_user
|
||||
rescue ActiveRecord::RecordInvalid
|
||||
render json: @step_text.errors, status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
if @step_text.destroy
|
||||
log_step_activity(:text_deleted, { text_name: @step_text.name })
|
||||
|
|
|
|||
|
|
@ -37,6 +37,24 @@ $(document).on('click', '.btn', function() {
|
|||
$(this).blur();
|
||||
});
|
||||
|
||||
$(document).on('turbolinks:load', () => {
|
||||
$(window).on('scroll', () => {
|
||||
const navbarHeight = 116;
|
||||
let scrollPosition = $(window).scrollTop();
|
||||
if (scrollPosition > navbarHeight) {
|
||||
scrollPosition = navbarHeight;
|
||||
}
|
||||
$('.sci--layout').css(
|
||||
'--navbar-height',
|
||||
`calc(var(--top-navigation-height) + var(--breadcrumbs-navigation-height) - ${scrollPosition}px)`
|
||||
);
|
||||
$('.sci--layout-navigation-navigator').css(
|
||||
'--navigator-top-margin',
|
||||
((scrollPosition / navbarHeight) * 16) + 'px'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
// Needed to support Turbolinks redirect_to responses as unsafe-inline is blocked by the CSP
|
||||
$.ajaxSetup({
|
||||
converters: {
|
||||
|
|
|
|||
22
app/javascript/packs/custom_axios.js
Normal file
22
app/javascript/packs/custom_axios.js
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
import axios from "axios";
|
||||
|
||||
const instance = axios.create({
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Accept: "application/json",
|
||||
},
|
||||
});
|
||||
|
||||
instance.interceptors.request.use(
|
||||
function (config) {
|
||||
const csrfToken = document.querySelector('[name=csrf-token]').content;
|
||||
config.headers["X-CSRF-Token"] = csrfToken;
|
||||
|
||||
return config;
|
||||
},
|
||||
function (error) {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
export default instance;
|
||||
|
|
@ -3,7 +3,9 @@
|
|||
import TurbolinksAdapter from 'vue-turbolinks';
|
||||
import Vue from 'vue/dist/vue.esm';
|
||||
import ProtocolContainer from '../../vue/protocol/container.vue';
|
||||
import PerfectScrollbar from 'vue2-perfect-scrollbar';
|
||||
|
||||
Vue.use(PerfectScrollbar);
|
||||
Vue.use(TurbolinksAdapter);
|
||||
Vue.prototype.i18n = window.I18n;
|
||||
Vue.prototype.inlineEditing = window.inlineEditing;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
import TurbolinksAdapter from 'vue-turbolinks';
|
||||
import Vue from 'vue/dist/vue.esm';
|
||||
import Results from '../../vue/results/results.vue';
|
||||
import PerfectScrollbar from 'vue2-perfect-scrollbar';
|
||||
|
||||
Vue.use(PerfectScrollbar);
|
||||
Vue.use(TurbolinksAdapter);
|
||||
Vue.prototype.i18n = window.I18n;
|
||||
Vue.prototype.ActiveStoragePreviews = window.ActiveStoragePreviews;
|
||||
|
|
|
|||
|
|
@ -129,10 +129,13 @@
|
|||
:step.sync="steps[index]"
|
||||
@reorder="startStepReorder"
|
||||
:inRepository="inRepository"
|
||||
:stepToReload="stepToReload"
|
||||
@step:delete="updateStepsPosition"
|
||||
@step:update="updateStep"
|
||||
@stepUpdated="refreshProtocolStatus"
|
||||
@step:insert="updateStepsPosition"
|
||||
@step:elements:loaded="stepToReload = null"
|
||||
@step:move_element="reloadStep"
|
||||
:reorderStepUrl="steps.length > 1 ? urls.reorder_steps_url : null"
|
||||
:assignableMyModuleId="protocol.attributes.assignable_my_module_id"
|
||||
/>
|
||||
|
|
@ -200,7 +203,8 @@
|
|||
},
|
||||
steps: [],
|
||||
reordering: false,
|
||||
publishing: false
|
||||
publishing: false,
|
||||
stepToReload: null,
|
||||
}
|
||||
},
|
||||
created() {
|
||||
|
|
@ -215,6 +219,9 @@
|
|||
});
|
||||
},
|
||||
methods: {
|
||||
reloadStep(step) {
|
||||
this.stepToReload = step;
|
||||
},
|
||||
collapseSteps() {
|
||||
$('.step-container .collapse').collapse('hide')
|
||||
},
|
||||
|
|
|
|||
|
|
@ -175,6 +175,7 @@
|
|||
@update="updateElement"
|
||||
@reorder="openReorderModal"
|
||||
@component:insert="insertElement"
|
||||
@moved="moveElement"
|
||||
/>
|
||||
</template>
|
||||
<Attachments v-if="attachments.length"
|
||||
|
|
@ -243,7 +244,11 @@
|
|||
assignableMyModuleId: {
|
||||
type: Number,
|
||||
required: false
|
||||
}
|
||||
},
|
||||
stepToReload: {
|
||||
type: Number,
|
||||
required: false
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
|
@ -284,6 +289,13 @@
|
|||
this.loadAttachments();
|
||||
this.loadElements();
|
||||
},
|
||||
watch: {
|
||||
stepToReload() {
|
||||
if (this.stepToReload == this.step.id) {
|
||||
this.loadElements();
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
$(this.$refs.comments).data('closeCallback', this.closeCommentsSidebar);
|
||||
$(this.$refs.comments).data('openCallback', this.closeCommentsSidebar);
|
||||
|
|
@ -335,6 +347,7 @@
|
|||
loadElements() {
|
||||
$.get(this.urls.elements_url, (result) => {
|
||||
this.elements = result.data
|
||||
this.$emit('step:elements:loaded');
|
||||
});
|
||||
},
|
||||
showStorageUsage() {
|
||||
|
|
@ -522,6 +535,17 @@
|
|||
})
|
||||
this.elements.push(element);
|
||||
},
|
||||
moveElement(position, target_id) {
|
||||
this.elements.splice(position, 1)
|
||||
let unorderedElements = this.elements.map( e => {
|
||||
if (e.attributes.position >= position) {
|
||||
e.attributes.position -= 1;
|
||||
}
|
||||
return e;
|
||||
})
|
||||
this.$emit('stepUpdated')
|
||||
this.$emit('step:move_element', target_id)
|
||||
},
|
||||
duplicateStep() {
|
||||
$.post(this.urls.duplicate_step_url, (result) => {
|
||||
this.$emit('step:insert', result.data);
|
||||
|
|
|
|||
|
|
@ -138,6 +138,7 @@
|
|||
@update="updateElement"
|
||||
@reorder="openReorderModal"
|
||||
@component:insert="insertElement"
|
||||
@moved="moveElement"
|
||||
/>
|
||||
</template>
|
||||
<Attachments v-if="attachments.length"
|
||||
|
|
@ -156,7 +157,7 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import axios from 'axios';
|
||||
import axios from '../../packs/custom_axios.js';
|
||||
import ReorderableItemsModal from '../shared/reorderable_items_modal.vue';
|
||||
import ResultTable from '../shared/content/table.vue';
|
||||
import ResultText from '../shared/content/text.vue';
|
||||
|
|
@ -170,7 +171,8 @@
|
|||
export default {
|
||||
name: 'Results',
|
||||
props: {
|
||||
result: { type: Object, required: true }
|
||||
result: { type: Object, required: true },
|
||||
resultToReload: { type: Number, required: false }
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
|
@ -198,6 +200,13 @@
|
|||
Attachments,
|
||||
InlineEdit
|
||||
},
|
||||
watch: {
|
||||
resultToReload() {
|
||||
if (this.resultToReload == this.result.id) {
|
||||
this.loadElements();
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
reorderableElements() {
|
||||
return this.orderedElements.map((e) => { return { id: e.id, attributes: e.attributes.orderable } })
|
||||
|
|
@ -294,6 +303,7 @@
|
|||
loadElements() {
|
||||
$.get(this.urls.elements_url, (result) => {
|
||||
this.elements = result.data
|
||||
this.$emit('result:elements:loaded');
|
||||
});
|
||||
},
|
||||
loadAttachments() {
|
||||
|
|
@ -340,6 +350,17 @@
|
|||
},
|
||||
duplicateResult() {
|
||||
|
||||
},
|
||||
moveElement(position, target_id) {
|
||||
this.elements.splice(position, 1)
|
||||
let unorderedElements = this.elements.map( e => {
|
||||
if (e.attributes.position >= position) {
|
||||
e.attributes.position -= 1;
|
||||
}
|
||||
return e;
|
||||
})
|
||||
this.$emit('resultUpdated')
|
||||
this.$emit('result:move_element', target_id)
|
||||
},
|
||||
updateName(name) {
|
||||
axios.patch(this.urls.update_url, { result: { name: name } }, (_) => {
|
||||
|
|
|
|||
|
|
@ -9,13 +9,18 @@
|
|||
class="mb-3"
|
||||
/>
|
||||
<div class="results-list">
|
||||
<Result v-for="result in results" :key="result.id" :result="result" />
|
||||
<Result v-for="result in results" :key="result.id"
|
||||
:result="result"
|
||||
:resultToReload="resultToReload"
|
||||
@result:elements:loaded="resultToReload = null"
|
||||
@result:move_element="reloadResult"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import axios from 'axios';
|
||||
import axios from '../../packs/custom_axios.js';
|
||||
import ResultsToolbar from './results_toolbar.vue';
|
||||
import Result from './result.vue';
|
||||
|
||||
|
|
@ -29,13 +34,17 @@
|
|||
return {
|
||||
results: [],
|
||||
sort: 'created_at_desc',
|
||||
filters: {}
|
||||
filters: {},
|
||||
resultToReload: null
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.loadResults();
|
||||
},
|
||||
methods: {
|
||||
reloadResult(result) {
|
||||
this.resultToReload = result;
|
||||
},
|
||||
loadResults() {
|
||||
axios.get(
|
||||
`${this.url}`,
|
||||
|
|
|
|||
|
|
@ -29,6 +29,9 @@
|
|||
<button v-if="element.attributes.orderable.urls.duplicate_url" class="btn icon-btn btn-light btn-sm" tabindex="0" @click="duplicateElement">
|
||||
<i class="sn-icon sn-icon-duplicate"></i>
|
||||
</button>
|
||||
<button v-if="element.attributes.orderable.urls.move_targets_url" class="btn btn-light btn-sm" tabindex="0" @click="showMoveModal">
|
||||
Move
|
||||
</button>
|
||||
<button v-if="element.attributes.orderable.urls.delete_url" class="btn icon-btn btn-light btn-sm" @click="showDeleteModal" tabindex="0">
|
||||
<i class="sn-icon sn-icon-delete"></i>
|
||||
</button>
|
||||
|
|
@ -76,21 +79,27 @@
|
|||
{{ i18n.t("protocols.steps.checklist.empty_checklist") }}
|
||||
</div>
|
||||
<deleteElementModal v-if="confirmingDelete" @confirm="deleteElement" @cancel="closeDeleteModal"/>
|
||||
<moveElementModal v-if="movingElement"
|
||||
:parent_type="element.attributes.orderable.parent_type"
|
||||
:targets_url="element.attributes.orderable.urls.move_targets_url"
|
||||
@confirm="moveElement($event)" @cancel="closeMoveModal"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DeleteMixin from './mixins/delete.js'
|
||||
import MoveMixin from './mixins/move.js'
|
||||
import DuplicateMixin from './mixins/duplicate.js'
|
||||
import deleteElementModal from './modal/delete.vue'
|
||||
import InlineEdit from '../inline_edit.vue'
|
||||
import ChecklistItem from './checklistItem.vue'
|
||||
import Draggable from 'vuedraggable'
|
||||
import moveElementModal from './modal/move.vue'
|
||||
|
||||
export default {
|
||||
name: 'Checklist',
|
||||
components: { deleteElementModal, InlineEdit, ChecklistItem, Draggable },
|
||||
mixins: [DeleteMixin, DuplicateMixin],
|
||||
components: { deleteElementModal, InlineEdit, ChecklistItem, Draggable, moveElementModal },
|
||||
mixins: [DeleteMixin, DuplicateMixin, MoveMixin],
|
||||
props: {
|
||||
element: {
|
||||
type: Object,
|
||||
|
|
|
|||
25
app/javascript/vue/shared/content/mixins/move.js
Normal file
25
app/javascript/vue/shared/content/mixins/move.js
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
import axios from '../../../../packs/custom_axios.js';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
movingElement: false
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
showMoveModal(event) {
|
||||
event.stopPropagation();
|
||||
this.movingElement = true;
|
||||
},
|
||||
closeMoveModal() {
|
||||
this.movingElement = false;
|
||||
},
|
||||
moveElement(target_id) {
|
||||
axios.post(this.element.attributes.orderable.urls.move_url, { target_id: target_id }).
|
||||
then(() => {
|
||||
this.movingElement = false;
|
||||
this.$emit('moved', this.element.attributes.position, target_id);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
83
app/javascript/vue/shared/content/modal/move.vue
Normal file
83
app/javascript/vue/shared/content/modal/move.vue
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
<template>
|
||||
<div ref="modal" @keydown.esc="cancel" class="modal" id="modalDestroyProtocolContent" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog" role="document">
|
||||
<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" id="modal-destroy-team-label">
|
||||
{{ i18n.t(`protocols.steps.modals.move_element.${parent_type}.title`) }}
|
||||
</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<label>
|
||||
{{ i18n.t(`protocols.steps.modals.move_element.${parent_type}.targets_label`) }}
|
||||
</label>
|
||||
<div class="w-full">
|
||||
<Select
|
||||
:value="target"
|
||||
:options="targets"
|
||||
v-bind:disabled="false"
|
||||
@change="setTarget"
|
||||
></Select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-secondary" @click="cancel">{{ i18n.t('general.cancel') }}</button>
|
||||
<button class="btn btn-primary" @click="confirm">{{ i18n.t('general.save')}}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import axios from '../../../../packs/custom_axios.js';
|
||||
import Select from "../../select.vue";
|
||||
|
||||
export default {
|
||||
name: 'moveElementModal',
|
||||
props: {
|
||||
parent_type: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
targets_url: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
target: null,
|
||||
targets: []
|
||||
}
|
||||
},
|
||||
components: {
|
||||
Select
|
||||
},
|
||||
mounted() {
|
||||
$(this.$refs.modal).modal('show');
|
||||
$(this.$refs.modal).on('hidden.bs.modal', () => {
|
||||
this.$emit('cancel');
|
||||
});
|
||||
this.fetchTargets();
|
||||
},
|
||||
methods: {
|
||||
setTarget(target) {
|
||||
this.target = target;
|
||||
},
|
||||
fetchTargets() {
|
||||
axios.get(this.targets_url)
|
||||
.then(response => {
|
||||
this.targets = response.data.targets;
|
||||
})
|
||||
},
|
||||
confirm() {
|
||||
$(this.$refs.modal).modal('hide');
|
||||
this.$emit('confirm', this.target);
|
||||
},
|
||||
cancel() {
|
||||
$(this.$refs.modal).modal('hide');
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
@ -28,6 +28,9 @@
|
|||
<button v-if="element.attributes.orderable.urls.duplicate_url" class="btn icon-btn btn-light" tabindex="0" @click="duplicateElement">
|
||||
<i class="sn-icon sn-icon-duplicate"></i>
|
||||
</button>
|
||||
<button v-if="element.attributes.orderable.urls.move_targets_url" class="btn btn-light btn-sm" tabindex="0" @click="showMoveModal">
|
||||
Move
|
||||
</button>
|
||||
<button v-if="element.attributes.orderable.urls.delete_url" class="btn icon-btn btn-light" @click="showDeleteModal" tabindex="0">
|
||||
<i class="sn-icon sn-icon-delete"></i>
|
||||
</button>
|
||||
|
|
@ -59,20 +62,26 @@
|
|||
</div>
|
||||
<deleteElementModal v-if="confirmingDelete" @confirm="deleteElement" @cancel="closeDeleteModal"/>
|
||||
<tableNameModal v-if="nameModalOpen" :element="element" @update="updateEmptyName" @cancel="nameModalOpen = false" />
|
||||
<moveElementModal v-if="movingElement"
|
||||
:parent_type="element.attributes.orderable.parent_type"
|
||||
:targets_url="element.attributes.orderable.urls.move_targets_url"
|
||||
@confirm="moveElement($event)" @cancel="closeMoveModal"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DeleteMixin from './mixins/delete.js'
|
||||
import MoveMixin from './mixins/move.js'
|
||||
import DuplicateMixin from './mixins/duplicate.js'
|
||||
import deleteElementModal from './modal/delete.vue'
|
||||
import InlineEdit from '../inline_edit.vue'
|
||||
import TableNameModal from './modal/table_name.vue'
|
||||
import moveElementModal from './modal/move.vue'
|
||||
|
||||
export default {
|
||||
name: 'ContentTable',
|
||||
components: { deleteElementModal, InlineEdit, TableNameModal },
|
||||
mixins: [DeleteMixin, DuplicateMixin],
|
||||
components: { deleteElementModal, InlineEdit, TableNameModal, moveElementModal },
|
||||
mixins: [DeleteMixin, DuplicateMixin, MoveMixin],
|
||||
props: {
|
||||
element: {
|
||||
type: Object,
|
||||
|
|
|
|||
|
|
@ -15,6 +15,9 @@
|
|||
<button v-if="element.attributes.orderable.urls.duplicate_url" class="btn icon-btn btn-light btn-sm" tabindex="0" @click="duplicateElement">
|
||||
<i class="sn-icon sn-icon-duplicate"></i>
|
||||
</button>
|
||||
<button v-if="element.attributes.orderable.urls.move_targets_url" class="btn btn-light btn-sm" tabindex="0" @click="showMoveModal">
|
||||
Move
|
||||
</button>
|
||||
<button v-if="element.attributes.orderable.urls.delete_url" class="btn icon-btn btn-light btn-sm" @click="showDeleteModal" tabindex="0">
|
||||
<i class="sn-icon sn-icon-delete"></i>
|
||||
</button>
|
||||
|
|
@ -41,19 +44,25 @@
|
|||
{{ i18n.t("protocols.steps.text.empty_text") }}
|
||||
</div>
|
||||
<deleteElementModal v-if="confirmingDelete" @confirm="deleteElement($event)" @cancel="closeDeleteModal"/>
|
||||
<moveElementModal v-if="movingElement"
|
||||
:parent_type="element.attributes.orderable.parent_type"
|
||||
:targets_url="element.attributes.orderable.urls.move_targets_url"
|
||||
@confirm="moveElement($event)" @cancel="closeMoveModal"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DeleteMixin from './mixins/delete.js'
|
||||
import MoveMixin from './mixins/move.js'
|
||||
import DuplicateMixin from './mixins/duplicate.js'
|
||||
import deleteElementModal from './modal/delete.vue'
|
||||
import moveElementModal from './modal/move.vue'
|
||||
import Tinymce from '../tinymce.vue'
|
||||
|
||||
export default {
|
||||
name: 'TextContent',
|
||||
components: { deleteElementModal, Tinymce },
|
||||
mixins: [DeleteMixin, DuplicateMixin],
|
||||
components: { deleteElementModal, Tinymce, moveElementModal },
|
||||
mixins: [DeleteMixin, DuplicateMixin, MoveMixin],
|
||||
props: {
|
||||
element: {
|
||||
type: Object,
|
||||
|
|
|
|||
|
|
@ -61,7 +61,8 @@ class MyModuleRepositoryRow < ApplicationRecord
|
|||
user: last_modified_by || assigned_by,
|
||||
amount: delta,
|
||||
balance: stock_value.amount,
|
||||
comment: comment
|
||||
comment: comment,
|
||||
unit: stock_value.repository_stock_unit_item&.data
|
||||
)
|
||||
stock_value.save!
|
||||
save!
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class RepositoryLedgerRecord < ApplicationRecord
|
||||
auto_strip_attributes :comment
|
||||
|
||||
belongs_to :repository_stock_value, optional: true
|
||||
belongs_to :reference, polymorphic: true
|
||||
belongs_to :user
|
||||
|
|
|
|||
|
|
@ -24,7 +24,8 @@ class RepositoryStockValue < ApplicationRecord
|
|||
amount: amount,
|
||||
balance: amount,
|
||||
reference: repository_cell.repository_column.repository,
|
||||
comment: comment)
|
||||
comment: comment,
|
||||
unit: repository_stock_unit_item&.data)
|
||||
end
|
||||
|
||||
SORTABLE_COLUMN_NAME = 'repository_stock_values.amount'
|
||||
|
|
@ -111,16 +112,18 @@ class RepositoryStockValue < ApplicationRecord
|
|||
.repository_stock_unit_items
|
||||
.find(new_data[:unit_item_id])
|
||||
self.last_modified_by = user
|
||||
delta = new_data[:amount].to_d - amount.to_d
|
||||
new_amount = new_data[:amount].to_d
|
||||
delta = new_amount - amount.to_d
|
||||
self.comment = new_data[:comment].presence
|
||||
repository_ledger_records.create!(
|
||||
user: last_modified_by,
|
||||
amount: delta,
|
||||
balance: amount,
|
||||
balance: new_amount,
|
||||
reference: repository_cell.repository_column.repository,
|
||||
comment: comment
|
||||
comment: comment,
|
||||
unit: repository_stock_unit_item&.data
|
||||
)
|
||||
self.amount = BigDecimal(new_data[:amount].to_s)
|
||||
self.amount = new_amount
|
||||
save!
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -111,4 +111,10 @@ class Result < ApplicationRecord
|
|||
def comments
|
||||
result_comments
|
||||
end
|
||||
|
||||
def normalize_elements_position
|
||||
result_orderable_elements.order(:position).each_with_index do |element, index|
|
||||
element.update!(position: index) unless element.position == index
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -180,6 +180,12 @@ class Step < ApplicationRecord
|
|||
end
|
||||
end
|
||||
|
||||
def normalize_elements_position
|
||||
step_orderable_elements.order(:position).each_with_index do |element, index|
|
||||
element.update!(position: index) unless element.position == index
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def touch_protocol
|
||||
|
|
|
|||
|
|
@ -23,13 +23,7 @@ class StepOrderableElement < ApplicationRecord
|
|||
def decrement_following_elements_positions
|
||||
step.with_lock do
|
||||
yield
|
||||
step.step_orderable_elements
|
||||
.where('position > ?', position)
|
||||
.order(position: :asc).each do |step_orderable_element|
|
||||
# find_each ignore any ordering
|
||||
step_orderable_element.position -= 1
|
||||
step_orderable_element.save!
|
||||
end
|
||||
step.normalize_elements_position
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -6,12 +6,16 @@ class ChecklistSerializer < ActiveModel::Serializer
|
|||
include ApplicationHelper
|
||||
include ActionView::Helpers::TextHelper
|
||||
|
||||
attributes :id, :name, :urls, :icon, :sa_name, :checklist_items
|
||||
attributes :id, :name, :urls, :icon, :sa_name, :checklist_items, :parent_type
|
||||
|
||||
def icon
|
||||
'fa-list-ul'
|
||||
end
|
||||
|
||||
def parent_type
|
||||
:step
|
||||
end
|
||||
|
||||
def checklist_items
|
||||
object.checklist_items.map do |item|
|
||||
ChecklistItemSerializer.new(item, scope: { user: scope[:user] || @instance_options[:user] }).as_json
|
||||
|
|
@ -34,7 +38,9 @@ class ChecklistSerializer < ActiveModel::Serializer
|
|||
delete_url: step_checklist_path(object.step, object),
|
||||
update_url: step_checklist_path(object.step, object),
|
||||
reorder_url: reorder_step_checklist_checklist_items_path(object.step, object),
|
||||
create_item_url: step_checklist_checklist_items_path(object.step, object)
|
||||
create_item_url: step_checklist_checklist_items_path(object.step, object),
|
||||
move_targets_url: move_targets_step_checklist_path(object.step, object),
|
||||
move_url: move_step_checklist_path(object.step, object)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ class ResultTableSerializer < ActiveModel::Serializer
|
|||
include Canaid::Helpers::PermissionsHelper
|
||||
include Rails.application.routes.url_helpers
|
||||
|
||||
attributes :name, :contents, :urls, :icon, :metadata
|
||||
attributes :name, :contents, :urls, :icon, :metadata, :parent_type
|
||||
|
||||
def contents
|
||||
object.contents_utf_8
|
||||
|
|
@ -14,20 +14,23 @@ class ResultTableSerializer < ActiveModel::Serializer
|
|||
'fa-table'
|
||||
end
|
||||
|
||||
def parent_type
|
||||
:result
|
||||
end
|
||||
|
||||
def urls
|
||||
return if object.destroyed?
|
||||
|
||||
object.reload unless object.result
|
||||
|
||||
p object.result
|
||||
p scope[:user] || @instance_options[:user]
|
||||
p can_manage_result?(scope[:user] || @instance_options[:user], object.result)
|
||||
return {} unless can_manage_result?(scope[:user] || @instance_options[:user], object.result)
|
||||
|
||||
{
|
||||
duplicate_url: duplicate_my_module_result_table_path(object.result.my_module, object.result, object),
|
||||
delete_url: my_module_result_table_path(object.result.my_module, object.result, object),
|
||||
update_url: my_module_result_table_path(object.result.my_module, object.result, object)
|
||||
update_url: my_module_result_table_path(object.result.my_module, object.result, object),
|
||||
move_targets_url: move_targets_my_module_result_table_path(object.result.my_module, object.result, object),
|
||||
move_url: move_my_module_result_table_path(object.result.my_module, object.result, object)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ class ResultTextSerializer < ActiveModel::Serializer
|
|||
include ApplicationHelper
|
||||
include ActionView::Helpers::TextHelper
|
||||
|
||||
attributes :id, :text, :urls, :text_view, :icon, :placeholder, :name
|
||||
attributes :id, :text, :urls, :text_view, :icon, :placeholder, :name, :parent_type
|
||||
|
||||
def updated_at
|
||||
object.updated_at.to_i
|
||||
|
|
@ -16,6 +16,10 @@ class ResultTextSerializer < ActiveModel::Serializer
|
|||
I18n.t('protocols.steps.text.placeholder')
|
||||
end
|
||||
|
||||
def parent_type
|
||||
:result
|
||||
end
|
||||
|
||||
def text_view
|
||||
@user = scope[:user]
|
||||
custom_auto_link(object.tinymce_render('text'),
|
||||
|
|
@ -40,7 +44,9 @@ class ResultTextSerializer < ActiveModel::Serializer
|
|||
{
|
||||
duplicate_url: duplicate_my_module_result_text_path(result.my_module, result, object),
|
||||
delete_url: my_module_result_text_path(result.my_module, result, object),
|
||||
update_url: my_module_result_text_path(result.my_module, result, object)
|
||||
update_url: my_module_result_text_path(result.my_module, result, object),
|
||||
move_targets_url: move_targets_my_module_result_text_path(result.my_module, result, object),
|
||||
move_url: move_my_module_result_text_path(result.my_module, result, object)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -6,12 +6,16 @@ class StepTextSerializer < ActiveModel::Serializer
|
|||
include ApplicationHelper
|
||||
include ActionView::Helpers::TextHelper
|
||||
|
||||
attributes :id, :text, :urls, :text_view, :updated_at, :icon, :name, :placeholder
|
||||
attributes :id, :text, :urls, :text_view, :updated_at, :icon, :name, :placeholder, :parent_type
|
||||
|
||||
def updated_at
|
||||
object.updated_at.to_i
|
||||
end
|
||||
|
||||
def parent_type
|
||||
:step
|
||||
end
|
||||
|
||||
def placeholder
|
||||
I18n.t('protocols.steps.text.placeholder')
|
||||
end
|
||||
|
|
@ -38,7 +42,9 @@ class StepTextSerializer < ActiveModel::Serializer
|
|||
{
|
||||
duplicate_url: duplicate_step_text_path(object.step, object),
|
||||
delete_url: step_text_path(object.step, object),
|
||||
update_url: step_text_path(object.step, object)
|
||||
update_url: step_text_path(object.step, object),
|
||||
move_url: move_step_text_path(object.step, object),
|
||||
move_targets_url: move_targets_step_text_path(object.step, object)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ class TableSerializer < ActiveModel::Serializer
|
|||
include Canaid::Helpers::PermissionsHelper
|
||||
include Rails.application.routes.url_helpers
|
||||
|
||||
attributes :name, :contents, :urls, :icon, :metadata
|
||||
attributes :name, :contents, :urls, :icon, :metadata, :parent_type
|
||||
|
||||
def contents
|
||||
object.contents_utf_8
|
||||
|
|
@ -14,6 +14,10 @@ class TableSerializer < ActiveModel::Serializer
|
|||
'fa-table'
|
||||
end
|
||||
|
||||
def parent_type
|
||||
:step
|
||||
end
|
||||
|
||||
def urls
|
||||
return if object.destroyed?
|
||||
|
||||
|
|
@ -24,7 +28,9 @@ class TableSerializer < ActiveModel::Serializer
|
|||
{
|
||||
duplicate_url: duplicate_step_table_path(object.step, object),
|
||||
delete_url: step_table_path(object.step, object),
|
||||
update_url: step_table_path(object.step, object)
|
||||
update_url: step_table_path(object.step, object),
|
||||
move_targets_url: move_targets_step_table_path(object.step, object),
|
||||
move_url: move_step_table_path(object.step, object)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -3107,6 +3107,13 @@ en:
|
|||
description_1: 'You’re about to delete a content block from your protocol. It might contain data you don’t want to lose. You won’t be able to get it back.'
|
||||
description_2: 'Are you sure you want to delete it?'
|
||||
confirm: 'Delete forever'
|
||||
move_element:
|
||||
step:
|
||||
title: Move to different step
|
||||
targets_label: Select step
|
||||
result:
|
||||
title: Move to different result
|
||||
targets_label: Select result
|
||||
delete_step:
|
||||
title: 'Delete step'
|
||||
description_1: 'You’re about to delete a whole step from your protocol. It might contain data you don’t want to lose. You won’t be able to get it back.'
|
||||
|
|
|
|||
|
|
@ -542,11 +542,15 @@ Rails.application.routes.draw do
|
|||
|
||||
resources :tables, controller: 'result_elements/tables', only: %i(create destroy update) do
|
||||
member do
|
||||
get :move_targets
|
||||
post :move
|
||||
post :duplicate
|
||||
end
|
||||
end
|
||||
resources :texts, controller: 'result_elements/texts', only: %i(create destroy update) do
|
||||
member do
|
||||
get :move_targets
|
||||
post :move
|
||||
post :duplicate
|
||||
end
|
||||
end
|
||||
|
|
@ -562,16 +566,22 @@ Rails.application.routes.draw do
|
|||
only: %i(create index update destroy)
|
||||
resources :tables, controller: 'step_elements/tables', only: %i(create destroy update) do
|
||||
member do
|
||||
get :move_targets
|
||||
post :move
|
||||
post :duplicate
|
||||
end
|
||||
end
|
||||
resources :texts, controller: 'step_elements/texts', only: %i(create destroy update) do
|
||||
member do
|
||||
get :move_targets
|
||||
post :move
|
||||
post :duplicate
|
||||
end
|
||||
end
|
||||
resources :checklists, controller: 'step_elements/checklists', only: %i(create destroy update) do
|
||||
member do
|
||||
get :move_targets
|
||||
post :move
|
||||
post :duplicate
|
||||
end
|
||||
resources :checklist_items, controller: 'step_elements/checklist_items', only: %i(create update destroy) do
|
||||
|
|
|
|||
|
|
@ -0,0 +1,35 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class UpdateRepositoryLedgerRecords < ActiveRecord::Migration[7.0]
|
||||
def up
|
||||
add_column :repository_ledger_records, :unit, :string
|
||||
|
||||
execute('
|
||||
UPDATE repository_ledger_records
|
||||
SET balance = repository_ledger_records.balance + repository_ledger_records.amount
|
||||
FROM (
|
||||
SELECT *, ROW_NUMBER() OVER(PARTITION BY repository_stock_value_id ORDER BY created_at) AS row_number
|
||||
FROM repository_ledger_records
|
||||
WHERE reference_type = \'RepositoryBase\'
|
||||
) with_row_numbers
|
||||
WHERE repository_ledger_records.id = with_row_numbers.id AND with_row_numbers.row_number != 1;
|
||||
|
||||
UPDATE repository_ledger_records SET comment = NULL WHERE comment = \'\';
|
||||
')
|
||||
end
|
||||
|
||||
def down
|
||||
execute('
|
||||
UPDATE repository_ledger_records
|
||||
SET balance = repository_ledger_records.balance - repository_ledger_records.amount
|
||||
FROM (
|
||||
SELECT *, ROW_NUMBER() OVER(PARTITION BY repository_stock_value_id ORDER BY created_at) AS row_number
|
||||
FROM repository_ledger_records
|
||||
WHERE reference_type = \'RepositoryBase\'
|
||||
) with_row_numbers
|
||||
WHERE repository_ledger_records.id = with_row_numbers.id AND with_row_numbers.row_number != 1;
|
||||
')
|
||||
|
||||
remove_column :repository_ledger_records, :unit
|
||||
end
|
||||
end
|
||||
25
db/schema.rb
25
db/schema.rb
|
|
@ -10,7 +10,7 @@
|
|||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema[7.0].define(version: 2023_08_11_115859) do
|
||||
ActiveRecord::Schema[7.0].define(version: 2023_08_18_072619) do
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "btree_gist"
|
||||
enable_extension "pg_trgm"
|
||||
|
|
@ -116,6 +116,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_08_11_115859) do
|
|||
t.bigint "last_modified_by_id"
|
||||
t.integer "position"
|
||||
t.index "trim_html_tags((text)::text) gin_trgm_ops", name: "index_checklist_items_on_text", using: :gin
|
||||
t.index ["checklist_id", "position"], name: "index_checklist_items_on_checklist_id_and_position", unique: true
|
||||
t.index ["checklist_id"], name: "index_checklist_items_on_checklist_id"
|
||||
t.index ["created_by_id"], name: "index_checklist_items_on_created_by_id"
|
||||
t.index ["last_modified_by_id"], name: "index_checklist_items_on_last_modified_by_id"
|
||||
|
|
@ -735,6 +736,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_08_11_115859) do
|
|||
t.text "comment"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.string "unit"
|
||||
t.index ["reference_type", "reference_id"], name: "index_repository_ledger_records_on_reference"
|
||||
t.index ["repository_stock_value_id"], name: "index_repository_ledger_records_on_repository_stock_value_id"
|
||||
t.index ["user_id"], name: "index_repository_ledger_records_on_user_id"
|
||||
|
|
@ -956,6 +958,23 @@ ActiveRecord::Schema[7.0].define(version: 2023_08_11_115859) do
|
|||
t.index ["type"], name: "index_settings_on_type", unique: true
|
||||
end
|
||||
|
||||
create_table "shareable_links", force: :cascade do |t|
|
||||
t.string "uuid"
|
||||
t.string "description"
|
||||
t.string "shareable_type"
|
||||
t.bigint "shareable_id"
|
||||
t.bigint "team_id"
|
||||
t.bigint "created_by_id"
|
||||
t.bigint "last_modified_by_id"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["created_by_id"], name: "index_shareable_links_on_created_by_id"
|
||||
t.index ["last_modified_by_id"], name: "index_shareable_links_on_last_modified_by_id"
|
||||
t.index ["shareable_type", "shareable_id"], name: "index_shareable_links_on_shareable"
|
||||
t.index ["team_id"], name: "index_shareable_links_on_team_id"
|
||||
t.index ["uuid"], name: "index_shareable_links_on_uuid"
|
||||
end
|
||||
|
||||
create_table "step_assets", force: :cascade do |t|
|
||||
t.bigint "step_id", null: false
|
||||
t.bigint "asset_id", null: false
|
||||
|
|
@ -1060,6 +1079,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_08_11_115859) do
|
|||
t.bigint "last_modified_by_id"
|
||||
t.string "description"
|
||||
t.bigint "space_taken", default: 1048576, null: false
|
||||
t.boolean "shareable_links_enabled", default: false, null: false
|
||||
t.index ["created_by_id"], name: "index_teams_on_created_by_id"
|
||||
t.index ["last_modified_by_id"], name: "index_teams_on_last_modified_by_id"
|
||||
t.index ["name"], name: "index_teams_on_name"
|
||||
|
|
@ -1420,6 +1440,9 @@ ActiveRecord::Schema[7.0].define(version: 2023_08_11_115859) do
|
|||
add_foreign_key "results", "users", column: "archived_by_id"
|
||||
add_foreign_key "results", "users", column: "last_modified_by_id"
|
||||
add_foreign_key "results", "users", column: "restored_by_id"
|
||||
add_foreign_key "shareable_links", "teams"
|
||||
add_foreign_key "shareable_links", "users", column: "created_by_id"
|
||||
add_foreign_key "shareable_links", "users", column: "last_modified_by_id"
|
||||
add_foreign_key "step_assets", "assets"
|
||||
add_foreign_key "step_assets", "steps"
|
||||
add_foreign_key "step_orderable_elements", "steps"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue