enable deletion of site logo

This commit is contained in:
riggraz
2025-01-22 11:52:01 +01:00
parent a712c97882
commit 61948f40fe
5 changed files with 70 additions and 9 deletions

View File

@@ -12,6 +12,27 @@
.siteLogoPreview {
@extend .d-block, .my-2;
height: 50px;
position: relative;
display: inline-block;
width: fit-content; /* Container matches the image size */
height: fit-content; /* Adjusts height to match the image */
}
.siteLogoPreview .siteLogoPreviewImg {
display: block;
height: 50px; /* Fixed height for the image */
width: auto; /* Maintain the aspect ratio */
}
.siteLogoPreview.siteLogoPreviewShouldDelete {
border: 2px solid red;
.siteLogoPreviewImg {
filter: grayscale(100%);
}
}
.siteLogoActions {
@extend .d-flex;
}
}

View File

@@ -96,8 +96,10 @@ class TenantsController < ApplicationController
# to avoid unique constraint violation
params[:tenant][:custom_domain] = nil if params[:tenant][:custom_domain].blank?
if params[:tenant][:should_delete_site_logo] == "true"
@tenant.site_logo.purge if @tenant.site_logo.attached?
elsif params[:tenant][:site_logo].present?
# If site_logo is provided, remove the old one if it exists and attach the new one
if params[:tenant][:site_logo].present?
@tenant.site_logo.purge if @tenant.site_logo.attached?
@tenant.site_logo.attach(params[:tenant][:site_logo])
end
@@ -138,7 +140,8 @@ class TenantsController < ApplicationController
policy(@tenant)
.permitted_attributes_for_update
.concat([{
tenant_setting_attributes: policy(@tenant.tenant_setting).permitted_attributes_for_update
tenant_setting_attributes: policy(@tenant.tenant_setting).permitted_attributes_for_update,
additional_params: [:should_delete_site_logo]
}]) # in order to permit nested attributes for tenant_setting
)
end

View File

@@ -48,6 +48,7 @@ const tenantUpdateFailure = (error: string): TenantUpdateFailureAction => ({
interface UpdateTenantParams {
siteName?: string;
siteLogo?: File;
shouldDeleteSiteLogo?: boolean;
oldSiteLogo?: string;
tenantSetting?: ITenantSetting;
locale?: string;
@@ -58,6 +59,7 @@ interface UpdateTenantParams {
export const updateTenant = ({
siteName = null,
siteLogo = null,
shouldDeleteSiteLogo = null,
oldSiteLogo = null,
tenantSetting = null,
locale = null,
@@ -73,6 +75,8 @@ export const updateTenant = ({
body.append('tenant[site_name]', siteName);
if (siteLogo)
body.append('tenant[site_logo]', siteLogo);
if (shouldDeleteSiteLogo)
body.append('tenant[should_delete_site_logo]', shouldDeleteSiteLogo.toString());
if (oldSiteLogo)
body.append('tenant[old_site_logo]', oldSiteLogo);
if (locale)

View File

@@ -21,12 +21,12 @@ import { DangerText, SmallMutedText } from '../../common/CustomTexts';
import { getLabel, getValidationMessage } from '../../../helpers/formUtils';
import IBoardJSON from '../../../interfaces/json/IBoard';
import ActionLink from '../../common/ActionLink';
import { CancelIcon, EditIcon, LearnMoreIcon } from '../../common/Icons';
import { CancelIcon, DeleteIcon, EditIcon, LearnMoreIcon } from '../../common/Icons';
import Dropzone from '../../common/Dropzone';
export interface ISiteSettingsGeneralForm {
siteName: string;
siteLogo: File; // TODO: Change to File type
siteLogo: File;
oldSiteLogo: string;
brandDisplaySetting: string;
locale: string;
@@ -59,6 +59,7 @@ interface Props {
updateTenant(
siteName: string,
siteLogo: File,
shouldDeleteSiteLogo: boolean,
oldSiteLogo: string,
brandDisplaySetting: string,
locale: string,
@@ -97,6 +98,8 @@ const GeneralSiteSettingsP = ({
formState: { isDirty, isSubmitSuccessful, errors },
watch,
control,
setValue,
getValues,
} = useForm<ISiteSettingsGeneralForm>({
defaultValues: {
siteName: originForm.siteName,
@@ -126,7 +129,8 @@ const GeneralSiteSettingsP = ({
updateTenant(
data.siteName,
'siteLogo' in data ? data.siteLogo[0] : null,
'siteLogo' in data && data.siteLogo ? data.siteLogo[0] : null,
shouldDeleteSiteLogo,
data.oldSiteLogo,
data.brandDisplaySetting,
data.locale,
@@ -176,6 +180,7 @@ const GeneralSiteSettingsP = ({
// Site logo
const [siteLogoFile, setSiteLogoFile] = React.useState<any>([]);
const [showSiteLogoDropzone, setShowSiteLogoDropzone] = React.useState([null, undefined, ''].includes(siteLogoUrl));
const [shouldDeleteSiteLogo, setShouldDeleteSiteLogo] = React.useState(false);
return (
<>
@@ -232,10 +237,16 @@ const GeneralSiteSettingsP = ({
<div className="formGroup col-6">
<label htmlFor="siteLogo">{ getLabel('tenant', 'site_logo') }</label>
{ siteLogoUrl && <img src={siteLogoUrl} alt={`${originForm.siteName} logo`} className="siteLogoPreview" /> }
{
siteLogoUrl &&
<div className={`siteLogoPreview${shouldDeleteSiteLogo ? ' siteLogoPreviewShouldDelete' : ''}`}>
<img src={siteLogoUrl} alt={`${originForm.siteName} logo`} className="siteLogoPreviewImg" />
</div>
}
<div className="siteLogoActions">
{
(siteLogoUrl && !shouldDeleteSiteLogo) &&
(showSiteLogoDropzone ?
<ActionLink
onClick={() => setShowSiteLogoDropzone(false)}
@@ -252,6 +263,26 @@ const GeneralSiteSettingsP = ({
</ActionLink>)
}
{
(siteLogoUrl && !showSiteLogoDropzone) &&
(shouldDeleteSiteLogo ?
<ActionLink
onClick={() => setShouldDeleteSiteLogo(false)}
icon={<CancelIcon />}
>
{I18n.t('common.buttons.cancel')}
</ActionLink>
:
<ActionLink
onClick={() => { setShouldDeleteSiteLogo(true); setValue('siteLogo', getValues('siteLogo'), { shouldDirty: true }) }}
icon={<DeleteIcon />}
>
{I18n.t('common.buttons.delete')}
</ActionLink>
)
}
</div>
{
showSiteLogoDropzone &&
<Controller

View File

@@ -19,6 +19,7 @@ const mapDispatchToProps = (dispatch: any) => ({
updateTenant(
siteName: string,
siteLogo: File,
shouldDeleteSiteLogo: boolean,
oldSiteLogo: string,
brandDisplaySetting: TenantSettingBrandDisplay,
locale: string,
@@ -41,6 +42,7 @@ const mapDispatchToProps = (dispatch: any) => ({
return dispatch(updateTenant({
siteName,
siteLogo,
shouldDeleteSiteLogo,
oldSiteLogo,
tenantSetting: {
brand_display: brandDisplaySetting,