Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: added feat to add new panel in a section #6999

Open
wants to merge 1 commit into
base: SIG-5642
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export default function DashboardEmptyState(): JSX.Element {
selectedDashboard,
isDashboardLocked,
handleToggleDashboardSlider,
setSelectedRowWidgetId,
} = useDashboard();

const { user } = useAppContext();
Expand All @@ -34,6 +35,7 @@ export default function DashboardEmptyState(): JSX.Element {
const [addPanelPermission] = useComponentPermission(permissions, userRole);

const onEmptyWidgetHandler = useCallback(() => {
setSelectedRowWidgetId(null);
handleToggleDashboardSlider(true);
logEvent('Dashboard Detail: Add new panel clicked', {
dashboardId: selectedDashboard?.uuid,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,8 @@

.menu-content {
.section-1 {
.rename-btn {
.rename-btn,
.new-panel-btn {
display: flex;
align-items: center;
gap: 6px;
Expand All @@ -140,6 +141,10 @@
margin-inline-end: 0px;
}
}

.rename-btn {
padding-bottom: 10px;
}
}

.section-2 {
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/container/GridCardLayout/GridCardLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ function GraphLayout(props: GraphLayoutProps): JSX.Element {
isDashboardLocked,
dashboardQueryRangeCalled,
setDashboardQueryRangeCalled,
setSelectedRowWidgetId,
} = useDashboard();
const { data } = selectedDashboard || {};
const { pathname } = useLocation();
Expand Down Expand Up @@ -173,6 +174,7 @@ function GraphLayout(props: GraphLayoutProps): JSX.Element {

updateDashboardMutation.mutate(updatedDashboard, {
onSuccess: (updatedDashboard) => {
setSelectedRowWidgetId(null);
if (updatedDashboard.payload) {
if (updatedDashboard.payload.data.layout)
setLayouts(sortLayout(updatedDashboard.payload.data.layout));
Expand Down
38 changes: 37 additions & 1 deletion frontend/src/container/GridCardLayout/WidgetRow.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import { Button, Popover } from 'antd';
import { EllipsisIcon, PenLine, X } from 'lucide-react';
import useComponentPermission from 'hooks/useComponentPermission';
import { EllipsisIcon, PenLine, Plus, X } from 'lucide-react';
import { useAppContext } from 'providers/App/App';
import { useDashboard } from 'providers/Dashboard/Dashboard';
import { useState } from 'react';
import { Layout } from 'react-grid-layout';
import { ROLES, USER_ROLES } from 'types/roles';
import { ComponentTypes } from 'utils/permission';

interface WidgetRowHeaderProps {
rowWidgetProperties: {
Expand All @@ -27,6 +32,23 @@ export function WidgetRowHeader(props: WidgetRowHeaderProps): JSX.Element {
id,
} = props;
const [isRowSettingsOpen, setIsRowSettingsOpen] = useState<boolean>(false);

const {
handleToggleDashboardSlider,
selectedDashboard,
isDashboardLocked,
setSelectedRowWidgetId,
} = useDashboard();

const permissions: ComponentTypes[] = ['add_panel'];
const { user } = useAppContext();

const userRole: ROLES | null =
selectedDashboard?.created_by === user?.email
? (USER_ROLES.AUTHOR as ROLES)
: user.role;
const [addPanelPermission] = useComponentPermission(permissions, userRole);

return (
<Popover
open={isRowSettingsOpen}
Expand All @@ -52,6 +74,20 @@ export function WidgetRowHeader(props: WidgetRowHeaderProps): JSX.Element {
Rename
</Button>
</section>
<section className="section-1">
<Button
className="new-panel-btn"
type="text"
disabled={!editWidget && addPanelPermission && !isDashboardLocked}
icon={<Plus size={14} />}
onClick={(): void => {
setSelectedRowWidgetId(id);
handleToggleDashboardSlider(true);
}}
>
New Panel
</Button>
</section>
{!rowWidgetProperties.collapsed && (
<section className="section-2">
<Button
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ function DashboardDescription(props: DashboardDescriptionProps): JSX.Element {
listSortOrder,
setSelectedDashboard,
handleToggleDashboardSlider,
setSelectedRowWidgetId,
handleDashboardLockToggle,
} = useDashboard();

Expand Down Expand Up @@ -157,6 +158,7 @@ function DashboardDescription(props: DashboardDescriptionProps): JSX.Element {
const [addPanelPermission] = useComponentPermission(permissions, userRole);

const onEmptyWidgetHandler = useCallback(() => {
setSelectedRowWidgetId(null);
handleToggleDashboardSlider(true);
logEvent('Dashboard Detail: Add new panel clicked', {
dashboardId: selectedDashboard?.uuid,
Expand Down
45 changes: 40 additions & 5 deletions frontend/src/container/NewWidget/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ import logEvent from 'api/common/logEvent';
import OverlayScrollbar from 'components/OverlayScrollbar/OverlayScrollbar';
import { FeatureKeys } from 'constants/features';
import { QueryParams } from 'constants/query';
import { initialQueriesMap, PANEL_TYPES } from 'constants/queryBuilder';
import {
initialQueriesMap,
PANEL_GROUP_TYPES,
PANEL_TYPES,
} from 'constants/queryBuilder';
import ROUTES from 'constants/routes';
import { DashboardShortcuts } from 'constants/shortcuts/DashboardShortcuts';
import { DEFAULT_BUCKET_COUNT } from 'container/PanelWrapper/constants';
Expand All @@ -20,7 +24,7 @@ import useUrlQuery from 'hooks/useUrlQuery';
import { getDashboardVariables } from 'lib/dashbaordVariables/getDashboardVariables';
import { GetQueryResultsProps } from 'lib/dashboard/getQueryResults';
import history from 'lib/history';
import { defaultTo, isUndefined } from 'lodash-es';
import { defaultTo, isEmpty, isUndefined } from 'lodash-es';
import { Check, X } from 'lucide-react';
import { DashboardWidgetPageParams } from 'pages/DashboardWidget';
import { useAppContext } from 'providers/App/App';
Expand Down Expand Up @@ -59,13 +63,16 @@ import {
getIsQueryModified,
handleQueryChange,
placeWidgetAtBottom,
placeWidgetBetweenRows,
} from './utils';

function NewWidget({ selectedGraph }: NewWidgetProps): JSX.Element {
const {
selectedDashboard,
setSelectedDashboard,
setToScrollWidgetId,
selectedRowWidgetId,
setSelectedRowWidgetId,
} = useDashboard();

const { t } = useTranslation(['dashboard']);
Expand Down Expand Up @@ -367,11 +374,35 @@ function NewWidget({ selectedGraph }: NewWidgetProps): JSX.Element {
const widgetId = query.get('widgetId') || '';
let updatedLayout = selectedDashboard.data.layout || [];

if (isNewDashboard) {
if (isNewDashboard && isEmpty(selectedRowWidgetId)) {
const newLayoutItem = placeWidgetAtBottom(widgetId, updatedLayout);
updatedLayout = [...updatedLayout, newLayoutItem];
}

if (isNewDashboard && selectedRowWidgetId) {
// Find the next row by looking through remaining layout items
const currentIndex = updatedLayout.findIndex(
(e) => e.i === selectedRowWidgetId,
);
const nextRowIndex = updatedLayout.findIndex(
(item, index) =>
index > currentIndex &&
widgets?.find((w) => w.id === item.i)?.panelTypes ===
PANEL_GROUP_TYPES.ROW,
);
const nextRowId = nextRowIndex !== -1 ? updatedLayout[nextRowIndex].i : null;

console.log(nextRowId);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same


const newLayoutItem = placeWidgetBetweenRows(
widgetId,
updatedLayout,
selectedRowWidgetId,
nextRowId,
);
updatedLayout = newLayoutItem;
}

const dashboard: Dashboard = {
...selectedDashboard,
uuid: selectedDashboard.uuid,
Expand Down Expand Up @@ -437,6 +468,7 @@ function NewWidget({ selectedGraph }: NewWidgetProps): JSX.Element {

updateDashboardMutation.mutateAsync(dashboard, {
onSuccess: () => {
setSelectedRowWidgetId(null);
setSelectedDashboard(dashboard);
setToScrollWidgetId(selectedWidget?.id || '');
history.push({
Expand All @@ -449,16 +481,19 @@ function NewWidget({ selectedGraph }: NewWidgetProps): JSX.Element {
selectedDashboard,
query,
isNewDashboard,
preWidgets,
selectedRowWidgetId,
afterWidgets,
selectedWidget,
selectedTime.enum,
graphType,
currentQuery,
afterWidgets,
preWidgets,
updateDashboardMutation,
handleError,
widgets,
setSelectedDashboard,
setToScrollWidgetId,
setSelectedRowWidgetId,
dashboardId,
]);

Expand Down
40 changes: 40 additions & 0 deletions frontend/src/container/NewWidget/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -631,3 +631,43 @@ export const placeWidgetAtBottom = (
h: widgetHeight || 6,
};
};

export const placeWidgetBetweenRows = (
widgetId: string,
layout: Layout[],
_currentRowId: string,
nextRowId?: string | null,
widgetWidth?: number,
widgetHeight?: number,
): Layout[] => {
if (layout.length === 0) {
return [
{
i: widgetId,
x: 0,
y: 0,
w: widgetWidth || 6,
h: widgetHeight || 6,
},
];
}

const nextRowIndex = nextRowId
? layout.findIndex((item) => item.i === nextRowId)
: -1;

// slice the layout from current row to next row
const sectionWidgets =
nextRowIndex === -1 ? layout : layout.slice(0, nextRowIndex);
console.log('sectionWidgets', sectionWidgets, nextRowIndex);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the console log?


const newWidgetLayout = placeWidgetAtBottom(
widgetId,
sectionWidgets,
widgetWidth,
widgetHeight,
);

// add new layout in between the sectionWidgets and the rest of the layout
return [...sectionWidgets, newWidgetLayout, ...layout.slice(nextRowIndex)];
};
10 changes: 10 additions & 0 deletions frontend/src/providers/Dashboard/Dashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ const DashboardContext = createContext<IDashboardContext>({
setVariablesToGetUpdated: () => {},
dashboardQueryRangeCalled: false,
setDashboardQueryRangeCalled: () => {},
selectedRowWidgetId: '',
setSelectedRowWidgetId: () => {},
});

interface Props {
Expand All @@ -87,6 +89,10 @@ export function DashboardProvider({

const [isDashboardLocked, setIsDashboardLocked] = useState<boolean>(false);

const [selectedRowWidgetId, setSelectedRowWidgetId] = useState<string | null>(
null,
);

const [
dashboardQueryRangeCalled,
setDashboardQueryRangeCalled,
Expand Down Expand Up @@ -416,6 +422,8 @@ export function DashboardProvider({
setVariablesToGetUpdated,
dashboardQueryRangeCalled,
setDashboardQueryRangeCalled,
selectedRowWidgetId,
setSelectedRowWidgetId,
}),
// eslint-disable-next-line react-hooks/exhaustive-deps
[
Expand All @@ -435,6 +443,8 @@ export function DashboardProvider({
setVariablesToGetUpdated,
dashboardQueryRangeCalled,
setDashboardQueryRangeCalled,
selectedRowWidgetId,
setSelectedRowWidgetId,
],
);

Expand Down
2 changes: 2 additions & 0 deletions frontend/src/providers/Dashboard/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,6 @@ export interface IDashboardContext {
setVariablesToGetUpdated: React.Dispatch<React.SetStateAction<string[]>>;
dashboardQueryRangeCalled: boolean;
setDashboardQueryRangeCalled: (value: boolean) => void;
selectedRowWidgetId: string | null;
setSelectedRowWidgetId: React.Dispatch<React.SetStateAction<string | null>>;
}
Loading