Move tenant settings on separate model (#196)

This commit is contained in:
Riccardo Graziosi
2023-02-04 15:43:15 +01:00
committed by GitHub
parent 6c03a0d750
commit d4242dd78e
17 changed files with 135 additions and 43 deletions

View File

@@ -41,6 +41,7 @@ class ApplicationController < ActionController::Base
# Load tenant data
@tenant = Current.tenant_or_raise!
@tenant_setting = TenantSetting.first_or_create
@boards = Board.select(:id, :name).order(order: :asc)
# Setup locale

View File

@@ -70,6 +70,12 @@ class TenantsController < ApplicationController
def tenant_update_params
params
.require(:tenant)
.permit(policy(@tenant).permitted_attributes_for_update)
.permit(
policy(@tenant)
.permitted_attributes_for_update
.concat([{
tenant_setting_attributes: policy(@tenant.tenant_setting).permitted_attributes_for_update
}]) # in order to permit nested attributes for tenant_setting
)
end
end

View File

@@ -3,6 +3,7 @@ import { ThunkAction } from "redux-thunk";
import HttpStatus from "../../constants/http_status";
import buildRequestHeaders from "../../helpers/buildRequestHeaders";
import ITenantSetting from "../../interfaces/ITenantSetting";
import ITenantJSON from "../../interfaces/json/ITenant";
import { State } from "../../reducers/rootReducer";
@@ -47,7 +48,7 @@ const tenantUpdateFailure = (error: string): TenantUpdateFailureAction => ({
interface UpdateTenantParams {
siteName?: string;
siteLogo?: string;
brandDisplaySetting?: string;
tenantSetting?: ITenantSetting;
locale?: string;
authenticityToken: string;
}
@@ -55,7 +56,7 @@ interface UpdateTenantParams {
export const updateTenant = ({
siteName = null,
siteLogo = null,
brandDisplaySetting = null,
tenantSetting = null,
locale = null,
authenticityToken,
}: UpdateTenantParams): ThunkAction<void, State, null, Action<string>> => async (dispatch) => {
@@ -64,15 +65,23 @@ export const updateTenant = ({
const tenant = Object.assign({},
siteName !== null ? { site_name: siteName } : null,
siteLogo !== null ? { site_logo: siteLogo } : null,
brandDisplaySetting !== null ? { brand_display_setting: brandDisplaySetting } : null,
locale !== null ? { locale } : null
);
try {
const body = JSON.stringify({
tenant: {
...tenant,
tenant_setting_attributes: tenantSetting,
},
});
console.log(body)
const res = await fetch(`/tenants/0`, {
method: 'PATCH',
headers: buildRequestHeaders(authenticityToken),
body: JSON.stringify({ tenant }),
body,
});
const json = await res.json();

View File

@@ -7,11 +7,11 @@ import SiteSettingsInfoBox from '../../common/SiteSettingsInfoBox';
import Button from '../../common/Button';
import HttpStatus from '../../../constants/http_status';
import {
TENANT_BRAND_NAME_AND_LOGO,
TENANT_BRAND_NAME_ONLY,
TENANT_BRAND_LOGO_ONLY,
TENANT_BRAND_NONE,
} from '../../../interfaces/ITenant';
TENANT_SETTING_BRAND_DISPLAY_NAME_AND_LOGO,
TENANT_SETTING_BRAND_DISPLAY_NAME_ONLY,
TENANT_SETTING_BRAND_DISPLAY_LOGO_ONLY,
TENANT_SETTING_BRAND_DISPLAY_NONE,
} from '../../../interfaces/ITenantSetting';
import { DangerText } from '../../common/CustomTexts';
import { getLabel, getValidationMessage } from '../../../helpers/formUtils';
@@ -105,16 +105,16 @@ const GeneralSiteSettingsP = ({
id="brandSetting"
className="selectPicker"
>
<option value={TENANT_BRAND_NAME_AND_LOGO}>
<option value={TENANT_SETTING_BRAND_DISPLAY_NAME_AND_LOGO}>
{ I18n.t('site_settings.general.brand_setting_both') }
</option>
<option value={TENANT_BRAND_NAME_ONLY}>
<option value={TENANT_SETTING_BRAND_DISPLAY_NAME_ONLY}>
{ I18n.t('site_settings.general.brand_setting_name') }
</option>
<option value={TENANT_BRAND_LOGO_ONLY}>
<option value={TENANT_SETTING_BRAND_DISPLAY_LOGO_ONLY}>
{ I18n.t('site_settings.general.brand_setting_logo') }
</option>
<option value={TENANT_BRAND_NONE}>
<option value={TENANT_SETTING_BRAND_DISPLAY_NONE}>
{ I18n.t('site_settings.general.brand_setting_none') }
</option>
</select>

View File

@@ -3,6 +3,7 @@ import { connect } from "react-redux";
import GeneralSiteSettingsP from "../components/SiteSettings/General/GeneralSiteSettingsP";
import { updateTenant } from "../actions/Tenant/updateTenant";
import { State } from "../reducers/rootReducer";
import { TenantSettingBrandDisplay } from "../interfaces/ITenantSetting";
const mapStateToProps = (state: State) => ({
areUpdating: state.siteSettings.general.areUpdating,
@@ -13,14 +14,14 @@ const mapDispatchToProps = (dispatch: any) => ({
updateTenant(
siteName: string,
siteLogo: string,
brandDisplaySetting: string,
brandDisplaySetting: TenantSettingBrandDisplay,
locale: string,
authenticityToken: string
): Promise<any> {
return dispatch(updateTenant({
siteName,
siteLogo,
brandDisplaySetting,
tenantSetting: { brand_display: brandDisplaySetting },
locale,
authenticityToken,
}));

View File

@@ -1,20 +1,7 @@
// Brand display setting
export const TENANT_BRAND_NAME_AND_LOGO = 'name_and_logo';
export const TENANT_BRAND_NAME_ONLY = 'name_only';
export const TENANT_BRAND_LOGO_ONLY = 'logo_only';
export const TENANT_BRAND_NONE = 'no_name_no_logo';
export type TenantBrandDisplaySetting =
typeof TENANT_BRAND_NAME_AND_LOGO |
typeof TENANT_BRAND_NAME_ONLY |
typeof TENANT_BRAND_LOGO_ONLY |
typeof TENANT_BRAND_NONE;
interface ITenant {
id: number;
siteName: string;
siteLogo: string;
brandDisplaySetting: TenantBrandDisplaySetting;
locale: string;
}

View File

@@ -0,0 +1,17 @@
// Brand display setting
export const TENANT_SETTING_BRAND_DISPLAY_NAME_AND_LOGO = 'name_and_logo';
export const TENANT_SETTING_BRAND_DISPLAY_NAME_ONLY = 'name_only';
export const TENANT_SETTING_BRAND_DISPLAY_LOGO_ONLY = 'logo_only';
export const TENANT_SETTING_BRAND_DISPLAY_NONE = 'no_name_no_logo';
export type TenantSettingBrandDisplay =
typeof TENANT_SETTING_BRAND_DISPLAY_NAME_AND_LOGO |
typeof TENANT_SETTING_BRAND_DISPLAY_NAME_ONLY |
typeof TENANT_SETTING_BRAND_DISPLAY_LOGO_ONLY |
typeof TENANT_SETTING_BRAND_DISPLAY_NONE;
interface ITenantSetting {
brand_display?: TenantSettingBrandDisplay;
}
export default ITenantSetting;

View File

@@ -1,17 +1,11 @@
class Tenant < ApplicationRecord
has_one :tenant_setting
has_many :boards
has_many :o_auths
has_many :post_statuses
has_many :posts
has_many :users
enum brand_display_setting: [
:name_and_logo,
:name_only,
:logo_only,
:no_name_no_logo
]
enum status: [:active, :pending, :blocked]
after_initialize :set_default_status, if: :new_record?
@@ -19,6 +13,8 @@ class Tenant < ApplicationRecord
validates :site_name, presence: true
validates :subdomain, presence: true, uniqueness: true
accepts_nested_attributes_for :tenant_setting, update_only: true
def set_default_status
self.status ||= :pending
end

View File

@@ -0,0 +1,12 @@
class TenantSetting < ApplicationRecord
include TenantOwnable
belongs_to :tenant
enum brand_display: [
:name_and_logo,
:name_only,
:logo_only,
:no_name_no_logo
]
end

View File

@@ -5,7 +5,7 @@ class TenantPolicy < ApplicationPolicy
def permitted_attributes_for_update
if user.admin?
[:site_name, :site_logo, :brand_display_setting, :locale]
[:site_name, :site_logo, :locale]
else
[]
end

View File

@@ -0,0 +1,13 @@
class TenantSettingPolicy < ApplicationPolicy
def permitted_attributes_for_update
if user.admin?
[:brand_display]
else
[]
end
end
def update?
user.admin? and user.tenant_id == record.id
end
end

View File

@@ -5,11 +5,11 @@
app_name = content_tag :span, @tenant.site_name
logo = image_tag(@tenant.site_logo ? @tenant.site_logo : "", class: 'logo')
if @tenant.brand_display_setting == "name_and_logo"
if @tenant_setting.brand_display == "name_and_logo"
logo + app_name
elsif @tenant.brand_display_setting == "name_only"
elsif @tenant_setting.brand_display == "name_only"
app_name
elsif @tenant.brand_display_setting == "logo_only"
elsif @tenant_setting.brand_display == "logo_only"
logo
end
end

View File

@@ -8,7 +8,7 @@
originForm: {
siteName: @tenant.site_name,
siteLogo: @tenant.site_logo,
brandDisplaySetting: @tenant.brand_display_setting,
brandDisplaySetting: @tenant_setting.brand_display,
locale: @tenant.locale
},
authenticityToken: form_authenticity_token