diff --git a/app/controllers/storage_locations_controller.rb b/app/controllers/storage_locations_controller.rb index bea2d3b60..a6af1aecc 100644 --- a/app/controllers/storage_locations_controller.rb +++ b/app/controllers/storage_locations_controller.rb @@ -4,10 +4,17 @@ class StorageLocationsController < ApplicationController before_action :load_storage_location, only: %i(update destroy) before_action :check_read_permissions, only: :index before_action :check_manage_permissions, except: :index + before_action :set_breadcrumbs_items, only: :index def index - storage_locations = Lists::StorageLocationsService.new(current_team, storage_location_params).call - render json: storage_locations, each_serializer: Lists::StorageLocationSerializer + respond_to do |format| + format.html + format.json do + storage_locations = Lists::StorageLocationsService.new(current_team, params).call + render json: storage_locations, each_serializer: Lists::StorageLocationSerializer, + user: current_user, meta: pagination_dict(storage_locations) + end + end end def update @@ -43,6 +50,12 @@ class StorageLocationsController < ApplicationController end end + def actions_toolbar + render json: { + actions: [] # TODO: Add actions + } + end + private def storage_location_params @@ -62,4 +75,37 @@ class StorageLocationsController < ApplicationController def check_manage_permissions render_403 unless true end + + def set_breadcrumbs_items + @breadcrumbs_items = [] + + @breadcrumbs_items.push({ + label: t('breadcrumbs.inventories') + }) + + @breadcrumbs_items.push({ + label: t('breadcrumbs.locations'), + url: storage_locations_path + }) + + storage_locations = [] + if params[:parent_id] + location = StorageLocation.where(team: current_team).find_by(id: params[:parent_id]) + if location + storage_locations.unshift(breadcrumbs_item(location)) + while location.parent + location = location.parent + storage_locations.unshift(breadcrumbs_item(location)) + end + end + end + @breadcrumbs_items += storage_locations + end + + def breadcrumbs_item(location) + { + label: location.name, + url: storage_locations_path(parent_id: location.id) + } + end end diff --git a/app/helpers/left_menu_bar_helper.rb b/app/helpers/left_menu_bar_helper.rb index f8a77be75..b6a2d22d2 100644 --- a/app/helpers/left_menu_bar_helper.rb +++ b/app/helpers/left_menu_bar_helper.rb @@ -19,8 +19,16 @@ module LeftMenuBarHelper url: repositories_path, name: t('left_menu_bar.repositories'), icon: 'sn-icon-inventory', - active: repositories_are_selected?, - submenu: [] + active: repositories_are_selected? || storage_locations_are_selected?, + submenu: [{ + url: repositories_path, + name: t('left_menu_bar.items'), + active: repositories_are_selected? + }, { + url: storage_locations_path, + name: t('left_menu_bar.locations'), + active: storage_locations_are_selected? + }] }, { url: "#", name: t('left_menu_bar.templates'), @@ -63,6 +71,10 @@ module LeftMenuBarHelper controller_name == 'repositories' end + def storage_locations_are_selected? + controller_name == 'storage_locations' + end + def protocols_are_selected? controller_name == 'protocols' end diff --git a/app/javascript/packs/vue/storage_locations_table.js b/app/javascript/packs/vue/storage_locations_table.js new file mode 100644 index 000000000..e83db7824 --- /dev/null +++ b/app/javascript/packs/vue/storage_locations_table.js @@ -0,0 +1,10 @@ +import { createApp } from 'vue/dist/vue.esm-bundler.js'; +import PerfectScrollbar from 'vue3-perfect-scrollbar'; +import StorageLocations from '../../vue/storage_locations/table.vue'; +import { mountWithTurbolinks } from './helpers/turbolinks.js'; + +const app = createApp(); +app.component('StorageLocations', StorageLocations); +app.config.globalProperties.i18n = window.I18n; +app.use(PerfectScrollbar); +mountWithTurbolinks(app, '#storageLocationsTable'); diff --git a/app/javascript/vue/storage_locations/table.vue b/app/javascript/vue/storage_locations/table.vue new file mode 100644 index 000000000..53991400e --- /dev/null +++ b/app/javascript/vue/storage_locations/table.vue @@ -0,0 +1,143 @@ + + + diff --git a/app/permissions/team.rb b/app/permissions/team.rb index 0507a53c4..7b69fe2e7 100644 --- a/app/permissions/team.rb +++ b/app/permissions/team.rb @@ -43,6 +43,10 @@ Canaid::Permissions.register_for(Team) do within_limits && team.permission_granted?(user, TeamPermissions::INVENTORIES_CREATE) end + can :create_storage_locations do |user, team| + true # TODO: Add permission check + end + can :create_reports do |user, team| team.permission_granted?(user, TeamPermissions::REPORTS_CREATE) end diff --git a/app/serializers/lists/storage_location_serializer.rb b/app/serializers/lists/storage_location_serializer.rb index 10eb48f57..ff69c971b 100644 --- a/app/serializers/lists/storage_location_serializer.rb +++ b/app/serializers/lists/storage_location_serializer.rb @@ -2,7 +2,9 @@ module Lists class StorageLocationSerializer < ActiveModel::Serializer - attributes :id, :code, :name, :container, :description, :owned_by, :created_by, :created_on + include Rails.application.routes.url_helpers + + attributes :id, :code, :name, :container, :description, :owned_by, :created_by, :created_on, :urls def owned_by object.team.name @@ -15,5 +17,11 @@ module Lists def created_on I18n.l(object.created_at, format: :full) end + + def urls + { + show: storage_locations_path(parent_id: object.id), + } + end end end diff --git a/app/views/storage_locations/index.html.erb b/app/views/storage_locations/index.html.erb new file mode 100644 index 000000000..44b755642 --- /dev/null +++ b/app/views/storage_locations/index.html.erb @@ -0,0 +1,23 @@ +<% provide(:head_title, t("storage_locations.index.head_title")) %> +<% provide(:container_class, "no-second-nav-container") %> + +<% if current_team %> +
+
+
+

<%= t('storage_locations.index.head_title') %>

+
+
+
+
+ +
+
+
+ + <%= javascript_include_tag 'vue_storage_locations_table' %> +<% end %> diff --git a/config/locales/en.yml b/config/locales/en.yml index ec905ed98..5409ac5ff 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -343,6 +343,8 @@ en: templates: "Templates" protocol: "Protocol" label: "Label" + items: "Items" + locations: "Locations" reports: "Reports" settings: "Settings" activities: "Activities" @@ -2663,6 +2665,21 @@ en: repository_ledger_records: errors: my_module_references_missing: 'Task references are not set' + storage_locations: + index: + head_title: "Locations" + new_location: "New location" + new_box: "New box" + table: + name: "Location name" + id: "ID" + sub_locations: "Sub-locations" + items: "Items" + free_spaces: "Free spaces" + shared: "Shared" + owned_by: "Owned by" + created_on: "Created on" + description: "Description" libraries: manange_modal_column_index: title: "Manage columns" @@ -4302,6 +4319,7 @@ en: labels: "Label" teams: "All Teams" addons: "Add-ons" + locations: "Locations" label_printer: "Label printer" fluics_printer: "Fluics printer" diff --git a/config/routes.rb b/config/routes.rb index 4e081d8b3..ad233e0a6 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -808,6 +808,9 @@ Rails.application.routes.draw do resources :connected_devices, controller: 'users/connected_devices', only: %i(destroy) resources :storage_locations, only: %i(index create destroy update) do + collection do + get :actions_toolbar + end resources :storage_location_repository_rows, only: %i(index create destroy update) end diff --git a/config/webpack/webpack.config.js b/config/webpack/webpack.config.js index 623270ff4..b8800b1b8 100644 --- a/config/webpack/webpack.config.js +++ b/config/webpack/webpack.config.js @@ -65,7 +65,8 @@ const entryList = { vue_legacy_tags_modal: './app/javascript/packs/vue/legacy/tags_modal.js', vue_legacy_access_modal: './app/javascript/packs/vue/legacy/access_modal.js', vue_legacy_repository_menu_dropdown: './app/javascript/packs/vue/legacy/repository_menu_dropdown.js', - vue_dashboard_new_task: './app/javascript/packs/vue/dashboard_new_task.js' + vue_dashboard_new_task: './app/javascript/packs/vue/dashboard_new_task.js', + vue_storage_locations_table: './app/javascript/packs/vue/storage_locations_table.js' }; // Engine pack loading based on https://github.com/rails/webpacker/issues/348#issuecomment-635480949