Skip to content

Commit

Permalink
Merge branch 'dev' for release 5.5.5
Browse files Browse the repository at this point in the history
  • Loading branch information
gnepud committed Nov 22, 2022
2 parents 48d8b5d + 2a4d50e commit 7140939
Show file tree
Hide file tree
Showing 33 changed files with 746 additions and 261 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# Changelog Fab-manager

## v5.5.5 2022 November 22

- Soft destroy of spaces and machines
- Fix a bug: in upgrade script, the error "the input device is not a TTY" is thrown when migrating the database
- Fix a bug: broken display of machines pages
- Fix a bug: some automated tests were randomly failing because ElasticSearch was not synced
- Fix a bug: payment related objects are not synced on Stripe when enabling the online payment module
- Fix a bug: unable set a main image of product and remove an image of product

## v5.5.4 2022 November 17

- Fix a bug: unable to download an existing export of the statistics
Expand Down
8 changes: 7 additions & 1 deletion app/controllers/api/machines_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ def index

def show
@machine = Machine.includes(:machine_files, :projects).friendly.find(params[:id])

head :not_found if @machine.deleted_at
end

def create
Expand All @@ -35,7 +37,11 @@ def update

def destroy
authorize @machine
@machine.destroy
if @machine.destroyable?
@machine.destroy
else
@machine.soft_destroy!
end
head :no_content
end

Expand Down
10 changes: 8 additions & 2 deletions app/controllers/api/spaces_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ class API::SpacesController < API::ApiController
respond_to :json

def index
@spaces = Space.includes(:space_image)
@spaces = Space.includes(:space_image).where(deleted_at: nil)
end

def show
@space = Space.includes(:space_files, :projects).friendly.find(params[:id])

head :not_found if @space.deleted_at
end

def create
Expand All @@ -36,7 +38,11 @@ def update
def destroy
@space = get_space
authorize @space
@space.destroy
if @space.destroyable?
@space.destroy
else
@space.soft_destroy!
end
head :no_content
end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,12 @@ export const FormImageUpload = <TFieldValues extends FieldValues, TContext exten
attachment_name: f.name
});
setValue(
id as Path<TFieldValues>,
{
attachment_name: f.name,
_destroy: false
} as UnpackNestedValue<FieldPathValue<TFieldValues, Path<TFieldValues>>>
`${id}.attachment_name` as Path<TFieldValues>,
f.name as UnpackNestedValue<FieldPathValue<TFieldValues, Path<TFieldValues>>>
);
setValue(
`${id}._destroy` as Path<TFieldValues>,
false as UnpackNestedValue<FieldPathValue<TFieldValues, Path<TFieldValues>>>
);
if (typeof onFileChange === 'function') {
onFileChange({ attachment_name: f.name });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ import { FieldValues } from 'react-hook-form/dist/types/fields';
import { FormComponent, FormControlledComponent } from '../../models/form-component';
import { AbstractFormItemProps } from './abstract-form-item';
import { UseFormSetValue } from 'react-hook-form/dist/types/form';
import { ArrayPath, FieldArray, useFieldArray } from 'react-hook-form';
import { ArrayPath, FieldArray, Path, useFieldArray, useWatch } from 'react-hook-form';
import { FileType } from '../../models/file';
import { UnpackNestedValue } from 'react-hook-form/dist/types';
import { FieldPathValue } from 'react-hook-form/dist/types/path';

interface FormMultiFileUploadProps<TFieldValues, TContext extends object> extends FormComponent<TFieldValues>, FormControlledComponent<TFieldValues, TContext>, AbstractFormItemProps<TFieldValues> {
setValue: UseFormSetValue<TFieldValues>,
Expand All @@ -20,21 +21,34 @@ interface FormMultiFileUploadProps<TFieldValues, TContext extends object> extend
* This component allows to upload multiple files, in forms managed by react-hook-form.
*/
export const FormMultiFileUpload = <TFieldValues extends FieldValues, TContext extends object>({ id, className, register, control, setValue, formState, addButtonLabel, accept }: FormMultiFileUploadProps<TFieldValues, TContext>) => {
const { fields, append, remove } = useFieldArray({ control, name: id as ArrayPath<TFieldValues> });
const { append } = useFieldArray({ control, name: id as ArrayPath<TFieldValues> });
const output = useWatch({ control, name: id as Path<TFieldValues> });

/**
* Remove an file
*/
const handleRemoveFile = (file: FileType, index: number) => {
return () => {
setValue(
`${id}.${index}._destroy` as Path<TFieldValues>,
true as UnpackNestedValue<FieldPathValue<TFieldValues, Path<TFieldValues>>>
);
};
};

return (
<div className={`form-multi-file-upload ${className || ''}`}>
<div className="list">
{fields.map((field: FileType, index) => (
<FormFileUpload key={field.id}
{output.map((field: FileType, index) => (
<FormFileUpload key={index}
defaultFile={field}
id={`${id}.${index}`}
accept={accept}
register={register}
setValue={setValue}
formState={formState}
className={field._destroy ? 'hidden' : ''}
onFileRemove={() => remove(index)}/>
onFileRemove={() => handleRemoveFile(field, index)}/>
))}
</div>
<FabButton
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ interface FormMultiImageUploadProps<TFieldValues, TContext extends object> exten
* This component allows to upload multiple images, in forms managed by react-hook-form.
*/
export const FormMultiImageUpload = <TFieldValues extends FieldValues, TContext extends object>({ id, className, register, control, setValue, formState, addButtonLabel }: FormMultiImageUploadProps<TFieldValues, TContext>) => {
const { fields, append, remove } = useFieldArray({ control, name: id as ArrayPath<TFieldValues> });
const { append } = useFieldArray({ control, name: id as ArrayPath<TFieldValues> });
const output = useWatch({ control, name: id as Path<TFieldValues> });

/**
Expand All @@ -44,14 +44,10 @@ export const FormMultiImageUpload = <TFieldValues extends FieldValues, TContext
true as UnpackNestedValue<FieldPathValue<TFieldValues, Path<TFieldValues>>>
);
}
if (typeof image.id === 'string') {
remove(index);
} else {
setValue(
`${id}.${index}._destroy` as Path<TFieldValues>,
true as UnpackNestedValue<FieldPathValue<TFieldValues, Path<TFieldValues>>>
);
}
setValue(
`${id}.${index}._destroy` as Path<TFieldValues>,
true as UnpackNestedValue<FieldPathValue<TFieldValues, Path<TFieldValues>>>
);
};
};

Expand All @@ -74,8 +70,8 @@ export const FormMultiImageUpload = <TFieldValues extends FieldValues, TContext
return (
<div className={`form-multi-image-upload ${className || ''}`}>
<div className="list">
{fields.map((field: ImageType, index) => (
<FormImageUpload key={field.id}
{output.map((field: ImageType, index) => (
<FormImageUpload key={index}
defaultImage={field}
id={`${id}.${index}`}
accept="image/*"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,12 @@ const MachineCard: React.FC<MachineCardProps> = ({ user, machine, onShowMachine,
* Return the machine's picture or a placeholder
*/
const machinePicture = (): ReactNode => {
if (!machine.machine_image_attributes) {
if (!machine.machine_image) {
return <div className="machine-picture no-picture" />;
}

return (
<div className="machine-picture" style={{ backgroundImage: `url(${machine.machine_image_attributes.attachment_url}), url('/default-image.png')` }} onClick={handleShowMachine} />
<div className="machine-picture" style={{ backgroundImage: `url(${machine.machine_image}), url('/default-image.png')` }} onClick={handleShowMachine} />
);
};

Expand Down
9 changes: 6 additions & 3 deletions app/frontend/src/javascript/models/machine.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { Reservation } from './reservation';
import { ApiFilter } from './api';
import { FileType } from './file';

export interface MachineIndexFilter extends ApiFilter {
disabled: boolean,
Expand All @@ -13,8 +12,12 @@ export interface Machine {
spec?: string,
disabled: boolean,
slug: string,
machine_image_attributes: FileType,
machine_files_attributes?: Array<FileType>,
machine_image: string,
machine_files_attributes?: Array<{
id: number,
attachment: string,
attachment_url: string
}>,
trainings?: Array<{
id: number,
name: string,
Expand Down
4 changes: 4 additions & 0 deletions app/models/machine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ def destroyable?
reservations.empty?
end

def soft_destroy!
update(deleted_at: DateTime.current)
end

def packs?(user)
prepaid_packs.where(group_id: user.group_id)
.where(disabled: [false, nil])
Expand Down
2 changes: 1 addition & 1 deletion app/models/product.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class Product < ApplicationRecord
accepts_nested_attributes_for :product_files, allow_destroy: true, reject_if: :all_blank

has_many :product_images, as: :viewable, dependent: :destroy
accepts_nested_attributes_for :product_images, allow_destroy: true, reject_if: ->(i) { i[:attachment].blank? }
accepts_nested_attributes_for :product_images, allow_destroy: true, reject_if: ->(i) { i[:attachment].blank? && i[:id].blank? }

has_many :product_stock_movements, dependent: :destroy
accepts_nested_attributes_for :product_stock_movements, allow_destroy: true, reject_if: :all_blank
Expand Down
4 changes: 4 additions & 0 deletions app/models/space.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ def destroyable?
reservations.empty?
end

def soft_destroy!
update(deleted_at: DateTime.current)
end

private

def update_gateway_product
Expand Down
2 changes: 1 addition & 1 deletion app/policies/machine_policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ def update?
end

def destroy?
user.admin? and record.destroyable?
user.admin?
end
end
5 changes: 4 additions & 1 deletion app/policies/space_policy.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# frozen_string_literal: true

# Check the access policies for API::SpacesController
class SpacePolicy < ApplicationPolicy
def create?
user.admin?
Expand All @@ -8,6 +11,6 @@ def update?
end

def destroy?
user.admin? and record.destroyable?
user.admin?
end
end
3 changes: 3 additions & 0 deletions app/services/cart/set_offer_service.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# frozen_string_literal: true

# module definition
module Cart; end

# Provides methods for set offer to item in cart
class Cart::SetOfferService
def call(order, orderable, is_offered)
Expand Down
3 changes: 3 additions & 0 deletions app/services/machine_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ def self.list(filters)
else
Machine.includes(:machine_image, :plans).order(sort_by)
end
# do not include soft destroyed
machines = machines.where(deleted_at: nil)

if filters[:disabled].present?
state = filters[:disabled] == 'false' ? [nil, false] : true
machines = machines.where(disabled: state)
Expand Down
2 changes: 1 addition & 1 deletion app/services/setting_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def notify_privacy_update(setting)

# sync all objects on stripe
def sync_stripe_objects(setting)
return unless setting.name == 'stripe_secret_key'
return unless %w[stripe_secret_key online_payment_module].include?(setting.name)

SyncObjectsOnStripeWorker.perform_async(setting.history_values.last&.invoicing_profile&.user&.id)
end
Expand Down
4 changes: 3 additions & 1 deletion app/views/api/machines/index.json.jbuilder
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# frozen_string_literal: true

json.array!(@machines) do |machine|
json.partial! 'api/machines/machine', machine: machine
json.extract! machine, :id, :name, :slug, :disabled

json.machine_image machine.machine_image.attachment.medium.url if machine.machine_image
end
6 changes: 3 additions & 3 deletions app/views/api/machines/show.json.jbuilder
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# frozen_string_literal: true

json.partial! 'api/machines/machine', machine: @machine
json.extract! @machine, :description, :spec
json.extract! @machine, :id, :name, :description, :spec, :disabled, :slug
json.machine_image @machine.machine_image.attachment.large.url if @machine.machine_image

json.machine_files_attributes @machine.machine_files do |f|
json.id f.id
json.attachment_name f.attachment_identifier
json.attachment f.attachment_identifier
json.attachment_url f.attachment_url
end
json.trainings @machine.trainings.each, :id, :name, :disabled
Expand Down
4 changes: 2 additions & 2 deletions app/views/api/products/_product.json.jbuilder
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ json.extract! product, :id, :name, :slug, :sku, :is_active, :product_category_id
:low_stock_threshold, :machine_ids, :created_at
json.description sanitize(product.description)
json.amount product.amount / 100.0 if product.amount.present?
json.product_files_attributes product.product_files do |f|
json.product_files_attributes product.product_files.order(created_at: :asc) do |f|
json.id f.id
json.attachment_name f.attachment_identifier
json.attachment_url f.attachment_url
end
json.product_images_attributes product.product_images do |f|
json.product_images_attributes product.product_images.order(created_at: :asc) do |f|
json.id f.id
json.attachment_name f.attachment_identifier
json.attachment_url f.attachment_url
Expand Down
Loading

0 comments on commit 7140939

Please sign in to comment.