misc bug fixes
parent
9d8ffe46ee
commit
2bcb249e7a
|
@ -23,7 +23,7 @@ class GlobalConfig < ApplicationRecord
|
||||||
{
|
{
|
||||||
"NODE_ENV" => Rails.env || "development",
|
"NODE_ENV" => Rails.env || "development",
|
||||||
"LONG_REVISION" => LONG_REVISION,
|
"LONG_REVISION" => LONG_REVISION,
|
||||||
"SHORT_REVISION" => LONG_REVISION.first(7),
|
"SHORT_REVISION" => LONG_REVISION.first(8),
|
||||||
}.map do |(key, value)|
|
}.map do |(key, value)|
|
||||||
self.find_or_create_by(key: key).update_attributes(key: key, value: value)
|
self.find_or_create_by(key: key).update_attributes(key: key, value: value)
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
# A human
|
# A human
|
||||||
class User < ApplicationRecord
|
class User < ApplicationRecord
|
||||||
class AlreadyVerified < StandardError; end
|
class AlreadyVerified < StandardError; end
|
||||||
|
# TODO: use GlobalConfig instead of ENV
|
||||||
ENFORCE_TOS = ENV.fetch("TOS_URL") { false }
|
ENFORCE_TOS = ENV.fetch("TOS_URL") { false }
|
||||||
SKIP_EMAIL_VALIDATION = ENV.fetch("NO_EMAILS") { false }
|
SKIP_EMAIL_VALIDATION = ENV.fetch("NO_EMAILS") { false }
|
||||||
validates :email, uniqueness: true
|
validates :email, uniqueness: true
|
||||||
|
|
|
@ -58,8 +58,8 @@ namespace :coverage do
|
||||||
|
|
||||||
puts "=" * 37
|
puts "=" * 37
|
||||||
puts "COVERAGE RESULTS"
|
puts "COVERAGE RESULTS"
|
||||||
puts "This build: #{build_percent.round(8)}% #{CURRENT_COMMIT[0,7]}"
|
puts "This build: #{build_percent.round(8)}% #{CURRENT_COMMIT[0,8]}"
|
||||||
puts "Staging build: #{staging_percent.round(8)}% #{latest_commit_staging[0,7]}"
|
puts "Staging build: #{staging_percent.round(8)}% #{latest_commit_staging[0,8]}"
|
||||||
puts "=" * 37
|
puts "=" * 37
|
||||||
puts "Difference: #{diff.round(8)}%"
|
puts "Difference: #{diff.round(8)}%"
|
||||||
puts "Pass?: #{pass ? "yes" : "no"}"
|
puts "Pass?: #{pass ? "yes" : "no"}"
|
||||||
|
|
|
@ -94,6 +94,18 @@ var HelperNamespace = (function () {
|
||||||
console.dir(getAllTags());
|
console.dir(getAllTags());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** For debugging. Replace all translations with a debug string. */
|
||||||
|
function replaceWithDebugString(key, debugString, debugStringOption) {
|
||||||
|
const debugChar = debugString[0];
|
||||||
|
switch (debugStringOption) {
|
||||||
|
case 'r': return debugString; // replace with: string as provided
|
||||||
|
case 's': return debugChar; // single character
|
||||||
|
case 'n': return key.replace(/\S/g, debugChar); // maintain whitespace
|
||||||
|
case 'l': return debugChar.repeat(key.length) // replace whitespace
|
||||||
|
default: return key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Label a section of tags with a comment before the first tag in the section.
|
* Label a section of tags with a comment before the first tag in the section.
|
||||||
*/
|
*/
|
||||||
|
@ -189,6 +201,7 @@ var HelperNamespace = (function () {
|
||||||
|
|
||||||
// For debugging
|
// For debugging
|
||||||
const debug = process.argv[3];
|
const debug = process.argv[3];
|
||||||
|
const debugOption = process.argv[4];
|
||||||
|
|
||||||
// merge new tags with existing translation
|
// merge new tags with existing translation
|
||||||
var result = {};
|
var result = {};
|
||||||
|
@ -198,14 +211,18 @@ var HelperNamespace = (function () {
|
||||||
// all current tags in English
|
// all current tags in English
|
||||||
Object.keys(jsonCurrentTagData).sort(localeSort).map(function (key) {
|
Object.keys(jsonCurrentTagData).sort(localeSort).map(function (key) {
|
||||||
result[key] = jsonCurrentTagData[key];
|
result[key] = jsonCurrentTagData[key];
|
||||||
if (debug) { result[key] = debug[0].repeat(key.length) }
|
if (debug) {
|
||||||
|
result[key] = replaceWithDebugString(key, debug, debugOption);
|
||||||
|
}
|
||||||
})
|
})
|
||||||
for (var key in ordered) {
|
for (var key in ordered) {
|
||||||
// replace current tag with an existing translation
|
// replace current tag with an existing translation
|
||||||
if (result.hasOwnProperty(key)) {
|
if (result.hasOwnProperty(key)) {
|
||||||
delete result[key];
|
delete result[key];
|
||||||
result[key] = ordered[key];
|
result[key] = ordered[key];
|
||||||
if (debug) { result[key] = debug[0].repeat(key.length) }
|
if (debug) {
|
||||||
|
result[key] = replaceWithDebugString(key, debug, debugOption);
|
||||||
|
}
|
||||||
existing++;
|
existing++;
|
||||||
if (key !== result[key]) { translated++; }
|
if (key !== result[key]) { translated++; }
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,6 +126,7 @@
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
height: 2rem;
|
height: 2rem;
|
||||||
|
padding: 0.2rem;
|
||||||
}
|
}
|
||||||
.right-button {
|
.right-button {
|
||||||
float: right;
|
float: right;
|
||||||
|
|
|
@ -41,6 +41,8 @@ input:not([role="combobox"]) {
|
||||||
|
|
||||||
.week-row {
|
.week-row {
|
||||||
height: 30.5px;
|
height: 30.5px;
|
||||||
|
width: 108%;
|
||||||
|
margin-left: -1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
|
|
|
@ -111,6 +111,11 @@ nav {
|
||||||
label {
|
label {
|
||||||
color: $white;
|
color: $white;
|
||||||
}
|
}
|
||||||
|
p {
|
||||||
|
display: inline;
|
||||||
|
color: $gray;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.bp3-overlay-content {
|
.bp3-overlay-content {
|
||||||
|
|
|
@ -5,7 +5,9 @@
|
||||||
}
|
}
|
||||||
.week-grid-meta-buttons {
|
.week-grid-meta-buttons {
|
||||||
margin-top: 1rem;
|
margin-top: 1rem;
|
||||||
|
text-align: right;
|
||||||
button {
|
button {
|
||||||
|
float: none;
|
||||||
margin-left: 1rem;
|
margin-left: 1rem;
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,9 +74,8 @@
|
||||||
margin-left: 1rem;
|
margin-left: 1rem;
|
||||||
margin-bottom: 0.5rem;
|
margin-bottom: 0.5rem;
|
||||||
}
|
}
|
||||||
}
|
img {
|
||||||
|
width: 55%;
|
||||||
img {
|
margin-bottom: 2rem;
|
||||||
width: 55%;
|
}
|
||||||
margin-bottom: 2rem;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,17 +18,21 @@ describe("executableType", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("OFSearch()", () => {
|
describe("OFSearch()", () => {
|
||||||
|
const START = expect.objectContaining({
|
||||||
|
type: Actions.OF_SEARCH_RESULTS_START
|
||||||
|
});
|
||||||
|
const NO = expect.objectContaining({ type: Actions.OF_SEARCH_RESULTS_NO });
|
||||||
|
|
||||||
it("searches: no image", async () => {
|
it("searches: no image", async () => {
|
||||||
mockPromise = Promise.resolve({ data: { data: [{ attributes: {} }] } });
|
mockPromise = Promise.resolve({ data: { data: [{ attributes: {} }] } });
|
||||||
const dispatch = jest.fn();
|
const dispatch = jest.fn();
|
||||||
await OFSearch("mint")(dispatch);
|
await OFSearch("mint")(dispatch);
|
||||||
|
expect(dispatch).toHaveBeenCalledWith(START);
|
||||||
await expect(dispatch).toHaveBeenCalledWith({
|
await expect(dispatch).toHaveBeenCalledWith({
|
||||||
type: Actions.OF_SEARCH_RESULTS_OK, payload: [
|
type: Actions.OF_SEARCH_RESULTS_OK, payload: [
|
||||||
{ crop: {}, image: "/app-resources/img/generic-plant.svg" }]
|
{ crop: {}, image: "/app-resources/img/generic-plant.svg" }]
|
||||||
});
|
});
|
||||||
await expect(dispatch).not.toHaveBeenCalledWith(expect.objectContaining({
|
await expect(dispatch).not.toHaveBeenCalledWith(NO);
|
||||||
type: Actions.OF_SEARCH_RESULTS_NO
|
|
||||||
}));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("searches: image", async () => {
|
it("searches: image", async () => {
|
||||||
|
@ -43,24 +47,22 @@ describe("OFSearch()", () => {
|
||||||
});
|
});
|
||||||
const dispatch = jest.fn();
|
const dispatch = jest.fn();
|
||||||
await OFSearch("mint")(dispatch);
|
await OFSearch("mint")(dispatch);
|
||||||
|
expect(dispatch).toHaveBeenCalledWith(START);
|
||||||
await expect(dispatch).toHaveBeenCalledWith({
|
await expect(dispatch).toHaveBeenCalledWith({
|
||||||
type: Actions.OF_SEARCH_RESULTS_OK, payload: [
|
type: Actions.OF_SEARCH_RESULTS_OK, payload: [
|
||||||
{ crop: {}, image: "thumbnail_url" }]
|
{ crop: {}, image: "thumbnail_url" }]
|
||||||
});
|
});
|
||||||
await expect(dispatch).not.toHaveBeenCalledWith(expect.objectContaining({
|
await expect(dispatch).not.toHaveBeenCalledWith(NO);
|
||||||
type: Actions.OF_SEARCH_RESULTS_NO
|
|
||||||
}));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("fails search", async () => {
|
it("fails search", async () => {
|
||||||
mockPromise = Promise.reject();
|
mockPromise = Promise.reject();
|
||||||
const dispatch = jest.fn();
|
const dispatch = jest.fn();
|
||||||
await OFSearch("mint")(dispatch);
|
await OFSearch("mint")(dispatch);
|
||||||
|
expect(dispatch).toHaveBeenCalledWith(START);
|
||||||
await expect(dispatch).not.toHaveBeenCalledWith(expect.objectContaining({
|
await expect(dispatch).not.toHaveBeenCalledWith(expect.objectContaining({
|
||||||
type: Actions.OF_SEARCH_RESULTS_OK
|
type: Actions.OF_SEARCH_RESULTS_OK
|
||||||
}));
|
}));
|
||||||
await expect(dispatch).toHaveBeenCalledWith({
|
await expect(dispatch).toHaveBeenCalledWith(NO);
|
||||||
type: Actions.OF_SEARCH_RESULTS_NO, payload: undefined
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -27,7 +27,6 @@ import {
|
||||||
fakeCropLiveSearchResult
|
fakeCropLiveSearchResult
|
||||||
} from "../../../__test_support__/fake_crop_search_result";
|
} from "../../../__test_support__/fake_crop_search_result";
|
||||||
import { unselectPlant } from "../../actions";
|
import { unselectPlant } from "../../actions";
|
||||||
import { Actions } from "../../../constants";
|
|
||||||
|
|
||||||
describe("<CropInfo />", () => {
|
describe("<CropInfo />", () => {
|
||||||
const fakeProps = (): CropInfoProps => {
|
const fakeProps = (): CropInfoProps => {
|
||||||
|
@ -118,8 +117,5 @@ describe("searchForCurrentCrop()", () => {
|
||||||
searchForCurrentCrop(fakeOFSearch)(dispatch);
|
searchForCurrentCrop(fakeOFSearch)(dispatch);
|
||||||
expect(fakeOFSearch).toHaveBeenCalledWith("mint");
|
expect(fakeOFSearch).toHaveBeenCalledWith("mint");
|
||||||
expect(unselectPlant).toHaveBeenCalled();
|
expect(unselectPlant).toHaveBeenCalled();
|
||||||
expect(dispatch).toHaveBeenCalledWith(expect.objectContaining({
|
|
||||||
type: Actions.OF_SEARCH_RESULTS_START
|
|
||||||
}));
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -55,6 +55,10 @@ export class CropCatalog extends React.Component<CropCatalogProps, {}> {
|
||||||
this.validSearchTerm;
|
this.validSearchTerm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this.props.openfarmSearch(this.props.cropSearchQuery)(this.props.dispatch);
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return <DesignerPanel panelName={"crop-catalog"} panelColor={"green"}>
|
return <DesignerPanel panelName={"crop-catalog"} panelColor={"green"}>
|
||||||
<DesignerPanelHeader
|
<DesignerPanelHeader
|
||||||
|
|
|
@ -209,12 +209,15 @@ export function mapStateToProps(props: Everything): CropInfoProps {
|
||||||
/** Get OpenFarm crop search results for crop info page contents. */
|
/** Get OpenFarm crop search results for crop info page contents. */
|
||||||
export const searchForCurrentCrop = (openfarmSearch: OpenfarmSearch) =>
|
export const searchForCurrentCrop = (openfarmSearch: OpenfarmSearch) =>
|
||||||
(dispatch: Function) => {
|
(dispatch: Function) => {
|
||||||
dispatch({ type: Actions.OF_SEARCH_RESULTS_START, payload: true });
|
|
||||||
const crop = getPathArray()[5];
|
const crop = getPathArray()[5];
|
||||||
openfarmSearch(crop)(dispatch);
|
openfarmSearch(crop)(dispatch);
|
||||||
unselectPlant(dispatch)();
|
unselectPlant(dispatch)();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Clear the current crop search results. */
|
||||||
|
const clearCropSearchResults = (dispatch: Function) => () =>
|
||||||
|
dispatch({ type: Actions.OF_SEARCH_RESULTS_OK, payload: [] });
|
||||||
|
|
||||||
@connect(mapStateToProps)
|
@connect(mapStateToProps)
|
||||||
export class CropInfo extends React.Component<CropInfoProps, {}> {
|
export class CropInfo extends React.Component<CropInfoProps, {}> {
|
||||||
|
|
||||||
|
@ -233,6 +236,7 @@ export class CropInfo extends React.Component<CropInfoProps, {}> {
|
||||||
panelColor={"green"}
|
panelColor={"green"}
|
||||||
title={result.crop.name}
|
title={result.crop.name}
|
||||||
backTo={basePath}
|
backTo={basePath}
|
||||||
|
onBack={clearCropSearchResults(this.props.dispatch)}
|
||||||
style={{ background: backgroundURL }}
|
style={{ background: backgroundURL }}
|
||||||
description={result.crop.description}>
|
description={result.crop.description}>
|
||||||
<AddToMapButton basePath={basePath} crop={crop} />
|
<AddToMapButton basePath={basePath} crop={crop} />
|
||||||
|
|
|
@ -17,6 +17,7 @@ interface IdURL {
|
||||||
const FALLBACK: OpenFarm.Included[] = [];
|
const FALLBACK: OpenFarm.Included[] = [];
|
||||||
export let OFSearch = (searchTerm: string) =>
|
export let OFSearch = (searchTerm: string) =>
|
||||||
(dispatch: Function) => {
|
(dispatch: Function) => {
|
||||||
|
dispatch({ type: Actions.OF_SEARCH_RESULTS_START, payload: undefined });
|
||||||
openFarmSearchQuery(searchTerm)
|
openFarmSearchQuery(searchTerm)
|
||||||
.then(resp => {
|
.then(resp => {
|
||||||
const images: { [key: string]: string } = {};
|
const images: { [key: string]: string } = {};
|
||||||
|
|
|
@ -42,9 +42,9 @@ describe("<SyncButton/>", function () {
|
||||||
it("defaults to `disconnected` and `red` when uncertain", () => {
|
it("defaults to `disconnected` and `red` when uncertain", () => {
|
||||||
const p = fakeProps();
|
const p = fakeProps();
|
||||||
// tslint:disable-next-line:no-any
|
// tslint:disable-next-line:no-any
|
||||||
p.bot.hardware.informational_settings.sync_status = "mistake" as any;
|
p.bot.hardware.informational_settings.sync_status = "new" as any;
|
||||||
const result = shallow(<SyncButton {...p} />);
|
const result = shallow(<SyncButton {...p} />);
|
||||||
expect(result.text()).toContain("DISCONNECTED");
|
expect(result.text()).toContain("new");
|
||||||
expect(result.hasClass("red")).toBeTruthy();
|
expect(result.hasClass("red")).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ import { t } from "i18next";
|
||||||
import { AccountMenuProps } from "./interfaces";
|
import { AccountMenuProps } from "./interfaces";
|
||||||
import { docLink } from "../ui/doc_link";
|
import { docLink } from "../ui/doc_link";
|
||||||
import { Link } from "../link";
|
import { Link } from "../link";
|
||||||
|
import { shortRevision } from "../util";
|
||||||
|
|
||||||
export const AdditionalMenu = (props: AccountMenuProps) => {
|
export const AdditionalMenu = (props: AccountMenuProps) => {
|
||||||
return <div className="nav-additional-menu">
|
return <div className="nav-additional-menu">
|
||||||
|
@ -34,7 +35,7 @@ export const AdditionalMenu = (props: AccountMenuProps) => {
|
||||||
<a
|
<a
|
||||||
href="https://github.com/FarmBot/Farmbot-Web-App"
|
href="https://github.com/FarmBot/Farmbot-Web-App"
|
||||||
target="_blank">
|
target="_blank">
|
||||||
{(globalConfig.SHORT_REVISION || "NONE").slice(0, 7)}
|
{shortRevision().slice(0, 7)}<p>{shortRevision().slice(7, 8)}</p>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>;
|
</div>;
|
||||||
|
|
|
@ -14,7 +14,7 @@ const COLOR_MAPPING: Record<SyncStatus, string> = {
|
||||||
"unknown": "red"
|
"unknown": "red"
|
||||||
};
|
};
|
||||||
|
|
||||||
const TEXT_MAPPING: Record<SyncStatus, string> = {
|
const TEXT_MAPPING: () => Record<SyncStatus, string> = () => ({
|
||||||
"synced": t("SYNCED"),
|
"synced": t("SYNCED"),
|
||||||
"sync_now": t("SYNC NOW"),
|
"sync_now": t("SYNC NOW"),
|
||||||
"syncing": t("SYNCING"),
|
"syncing": t("SYNCING"),
|
||||||
|
@ -22,7 +22,7 @@ const TEXT_MAPPING: Record<SyncStatus, string> = {
|
||||||
"booting": t("BOOTING"),
|
"booting": t("BOOTING"),
|
||||||
"unknown": t("DISCONNECTED"),
|
"unknown": t("DISCONNECTED"),
|
||||||
"maintenance": t("MAINTENANCE DOWNTIME")
|
"maintenance": t("MAINTENANCE DOWNTIME")
|
||||||
};
|
});
|
||||||
|
|
||||||
/** Animation during syncing action */
|
/** Animation during syncing action */
|
||||||
const spinner = <span className="btn-spinner sync" />;
|
const spinner = <span className="btn-spinner sync" />;
|
||||||
|
@ -30,15 +30,16 @@ const spinner = <span className="btn-spinner sync" />;
|
||||||
export function SyncButton({ user, bot, dispatch, consistent }: NavButtonProps) {
|
export function SyncButton({ user, bot, dispatch, consistent }: NavButtonProps) {
|
||||||
|
|
||||||
if (!user) {
|
if (!user) {
|
||||||
return <span></span>;
|
return <span />;
|
||||||
}
|
}
|
||||||
let { sync_status } = bot.hardware.informational_settings;
|
const { sync_status } = bot.hardware.informational_settings;
|
||||||
sync_status = sync_status || "unknown";
|
const syncStatus = sync_status || "unknown";
|
||||||
const color = !consistent && sync_status === "sync_now"
|
const normalColor = COLOR_MAPPING[syncStatus] || "red";
|
||||||
|
const color = (!consistent && (syncStatus === "sync_now"))
|
||||||
? "gray"
|
? "gray"
|
||||||
: (COLOR_MAPPING[sync_status] || "red");
|
: normalColor;
|
||||||
const text = TEXT_MAPPING[sync_status] || t("DISCONNECTED");
|
const text = TEXT_MAPPING()[syncStatus] || syncStatus.replace("_", " ");
|
||||||
const spinnerEl = (sync_status === "syncing") ? spinner : "";
|
const spinnerEl = (syncStatus === "syncing") ? spinner : "";
|
||||||
|
|
||||||
return <button
|
return <button
|
||||||
className={`nav-sync ${color} fb-button`}
|
className={`nav-sync ${color} fb-button`}
|
||||||
|
|
|
@ -21,26 +21,30 @@ export function WeekGrid({ weeks, dispatch }: WeekGridProps) {
|
||||||
<Row>
|
<Row>
|
||||||
<Col xs={12}>
|
<Col xs={12}>
|
||||||
<div className="week-grid-meta-buttons">
|
<div className="week-grid-meta-buttons">
|
||||||
<button
|
<div>
|
||||||
className="green widget-control fb-button"
|
<button
|
||||||
onClick={() => dispatch(pushWeek())}>
|
className="green widget-control fb-button"
|
||||||
<i className="fa fa-plus" /> {t("Week")}
|
onClick={() => dispatch(pushWeek())}>
|
||||||
</button>
|
<i className="fa fa-plus" /> {t("Week")}
|
||||||
<button
|
</button>
|
||||||
className="red widget-control fb-button"
|
<button
|
||||||
onClick={() => dispatch(popWeek())}>
|
className="red widget-control fb-button"
|
||||||
<i className="fa fa-minus" /> {t("Week")}
|
onClick={() => dispatch(popWeek())}>
|
||||||
</button>
|
<i className="fa fa-minus" /> {t("Week")}
|
||||||
<button
|
</button>
|
||||||
className="gray widget-control fb-button"
|
</div>
|
||||||
onClick={() => dispatch(deselectDays())}>
|
<div>
|
||||||
{t("Deselect all")}
|
<button
|
||||||
</button>
|
className="gray widget-control fb-button"
|
||||||
<button
|
onClick={() => dispatch(deselectDays())}>
|
||||||
className="gray widget-control fb-button"
|
{t("Deselect all")}
|
||||||
onClick={() => dispatch(selectDays())}>
|
</button>
|
||||||
{t("Select all")}
|
<button
|
||||||
</button>
|
className="gray widget-control fb-button"
|
||||||
|
onClick={() => dispatch(selectDays())}>
|
||||||
|
{t("Select all")}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
|
|
|
@ -12,7 +12,7 @@ interface CenterProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function CenterPanel(props: CenterProps) {
|
export function CenterPanel(props: CenterProps) {
|
||||||
return <Col sm={props.width || 6}>
|
return <Col sm={props.width || 6} lg={6}>
|
||||||
<div className={props.className}>
|
<div className={props.className}>
|
||||||
<h3>
|
<h3>
|
||||||
<i>{t(props.title)}</i>
|
<i>{t(props.title)}</i>
|
||||||
|
|
|
@ -12,7 +12,7 @@ interface RightPanelProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function RightPanel(props: RightPanelProps) {
|
export function RightPanel(props: RightPanelProps) {
|
||||||
return <Col sm={props.width || 3}>
|
return <Col sm={props.width || 3} lg={3}>
|
||||||
{props.show &&
|
{props.show &&
|
||||||
<div className={props.className}>
|
<div className={props.className}>
|
||||||
<h3>
|
<h3>
|
||||||
|
|
Loading…
Reference in New Issue