Skip to content

Commit

Permalink
Fixes #36872 - Banner to show foreman instance
Browse files Browse the repository at this point in the history
  • Loading branch information
MariaAga committed Oct 30, 2023
1 parent 2ae0516 commit e8f999a
Show file tree
Hide file tree
Showing 11 changed files with 132 additions and 68 deletions.
1 change: 1 addition & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@
"nonpersistent",
"noopener",
"noreferrer",
"nowrap",
"num",
"numpad",
"operatingsystem",
Expand Down
17 changes: 14 additions & 3 deletions app/assets/stylesheets/base.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,26 @@ html {
}

#rails-app-content {
--header-height: 70px;
position: absolute;
top: 70px;
top: var(--header-height);
left: 0;
right: 0;
bottom: 0;
overflow: auto;
height: calc(100% - 70px);
height: calc(100% - var(--header-height));
margin-left: 250px;
&.user-banner-present {
--banner-height: calc(
2 * var(--pf-global--spacer--xs) +
(var(--pf-global--LineHeight--md) * var(--pf-global--FontSize--sm))
); // banner height is line height and a small padding
top: calc(
var(--header-height) + var(--banner-height)
);

height: calc(100% - var(--header-height) - var(--banner-height));
}
.rails-table-toolbar {
padding-bottom: 0;
display: flex;
Expand All @@ -24,7 +36,6 @@ html {
grid-template-columns: unset;
grid-template-areas: unset;
}

}

body {
Expand Down
3 changes: 2 additions & 1 deletion app/helpers/layout_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ def layout_data
user: fetch_user, brand: 'foreman',
root: main_app.root_path,
locations: fetch_locations, orgs: fetch_organizations,
instance_title: Setting[:instance_title]
instance_title: Setting[:instance_title],
instance_color: Setting[:instance_color]
}
end

Expand Down
7 changes: 6 additions & 1 deletion app/registries/foreman/settings/general.rb
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,14 @@
collection: timezones)
setting('instance_title',
type: :string,
description: N_("The instance title is shown on the top navigation bar (requires a page reload)."),
description: N_("The instance title is shown under the header in a banner (requires a page reload)."),
default: nil,
full_name: N_('Instance title'))
setting('instance_color',
type: :string,
description: N_("Hex value (Example: #000000) for color for the instance title banner. Will only be used if an instance title is defined. (requires a page reload)."),
default: '#000000',
full_name: N_('Instance color'))
setting('audits_period',
type: :integer,
description: N_('Duration in days to preserve audits for. Leave empty to disable the audits cleanup.'),
Expand Down
2 changes: 1 addition & 1 deletion app/views/layouts/base.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
<% end %>
<div
id="rails-app-content"
class="pf-c-page"
class="pf-c-page <%= Foreman.settings.find('instance_title') ? 'user-banner-present' : '' %>"
>

<%= yield(:content) %>
Expand Down
59 changes: 38 additions & 21 deletions webpack/assets/javascripts/react_app/components/Layout/Layout.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import React from 'react';

import { Page, PageSidebar } from '@patternfly/react-core';
import { Page, PageSidebar, Flex, FlexItem } from '@patternfly/react-core';
import { layoutPropTypes, layoutDefaultProps } from './LayoutHelper';
import { InstanceBanner } from './components/InstanceBanner';
import Header from './components/Toolbar/Header';
import Navigation from './Navigation';
import './layout.scss';
Expand Down Expand Up @@ -29,28 +30,44 @@ const Layout = ({
};
return (
<>
<Page
mainContainerId="foreman-main-container"
header={
<Header data={data} onNavToggle={onNavToggle} isLoading={isLoading} />
}
id="foreman-page"
sidebar={
<PageSidebar
isNavOpen={!isCollapsed}
nav={
<Navigation
items={items}
navigate={navigate}
navigationActiveItem={navigationActiveItem}
setNavigationActiveItem={setNavigationActiveItem}
<Flex
direction={{ default: 'column' }}
flexWrap={{ default: 'nowrap' }}
spaceItems={{ default: 'spaceItemsNone' }}
style={{ height: '100%' }}
>
<FlexItem>
<InstanceBanner data={data} />
</FlexItem>
<FlexItem grow={{ default: 'grow' }} style={{ minHeight: 0 }}>
<Page
mainContainerId="foreman-main-container"
header={
<Header
data={data}
onNavToggle={onNavToggle}
isLoading={isLoading}
/>
}
/>
}
>
{children}
</Page>
id="foreman-page"
sidebar={
<PageSidebar
isNavOpen={!isCollapsed}
nav={
<Navigation
items={items}
navigate={navigate}
navigationActiveItem={navigationActiveItem}
setNavigationActiveItem={setNavigationActiveItem}
/>
}
/>
}
>
{children}
</Page>
</FlexItem>
</Flex>
</>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,6 @@ describe('Layout', () => {
});
expect(screen.getByText('All Hosts')).toBeVisible();
expect(screen.getByText('Dashboard')).toBeVisible();
expect(screen.getByText('Production')).toBeVisible();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Banner } from '@patternfly/react-core';

const getContrastColor = backgroundColor => {
const hexToRgb = hex => {
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result
? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16),
}
: null;
};
backgroundColor = hexToRgb(backgroundColor);
// Calculate the relative luminance of the background color
const luminance =
(0.2126 * backgroundColor.r +
0.7152 * backgroundColor.g +
0.0722 * backgroundColor.b) /
255;

// Choose black or white text based on the relative luminance
return luminance > 0.5 ? 'black' : 'white';
};
const validateHexColor = instanceColor => {
// Check if the string is a valid hex color code
if (/^#([0-9A-Fa-f]{3}){1,2}$/.test(instanceColor)) {
return instanceColor;
}
return '#000000';
};

export const InstanceBanner = ({ data }) => {
if (!data || !data.instance_title) {
return null;
}
const instance = data.instance_title;
const instanceColor = validateHexColor(data.instance_color);
return (
instance && (
<Banner
isSticky
style={{ '--pf-c-banner--BackgroundColor': instanceColor }}
className="instance-banner"
>
<div
style={{
color: getContrastColor(instanceColor),
}}
>
{instance}
</div>
</Banner>
)
);
};

InstanceBanner.propTypes = {
data: PropTypes.shape({
instance_title: PropTypes.string,
instance_color: PropTypes.string,
}),
};

InstanceBanner.defaultProps = {
data: {},
};
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import {
organizationPropType,
userPropType,
} from '../../LayoutHelper';
import InstanceTitleViewer from './InstanceTitleViewer';
import './HeaderToolbar.scss';

const HeaderToolbar = ({
Expand All @@ -26,7 +25,6 @@ const HeaderToolbar = ({
notification_url: notificationUrl,
user,
stop_impersonation_url: stopImpersonationUrl,
instance_title: instanceTitle,
isLoading,
}) => (
<Toolbar ouiaId="data-toolbar" id="data-toolbar" isFullHeight isStatic>
Expand All @@ -39,9 +37,6 @@ const HeaderToolbar = ({
/>
</ToolbarGroup>
<ToolbarGroup alignment={{ default: 'alignRight' }}>
<ToolbarItem>
<InstanceTitleViewer title={instanceTitle} />
</ToolbarItem>
<ToolbarItem className="notifications_container">
<NotificationContainer data={{ url: notificationUrl }} />
</ToolbarItem>
Expand All @@ -60,7 +55,6 @@ const HeaderToolbar = ({
);
HeaderToolbar.propTypes = {
stop_impersonation_url: PropTypes.string.isRequired,
instance_title: PropTypes.string,
locations: locationPropType.isRequired,
orgs: organizationPropType.isRequired,
notification_url: PropTypes.string.isRequired,
Expand All @@ -69,7 +63,6 @@ HeaderToolbar.propTypes = {
};

HeaderToolbar.defaultProps = {
instance_title: null,
user: {},
isLoading: layoutDefaultProps.isLoading,
};
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,6 @@ exports[`HeaderToolbar rendering render HeaderToolbar 1`] = `
}
}
>
<ToolbarItem>
<InstanceTitleViewer
title="Production"
/>
</ToolbarItem>
<ToolbarItem
className="notifications_container"
>
Expand Down

0 comments on commit e8f999a

Please sign in to comment.