Skip to content

Commit

Permalink
Merge pull request #9 from Willie-The-Lord/feature/multiple-form
Browse files Browse the repository at this point in the history
[Feature] Implement multiple drilldownform
  • Loading branch information
willie-hung authored Nov 30, 2023
2 parents 891910c + 05855cb commit fc0915f
Show file tree
Hide file tree
Showing 13 changed files with 234 additions and 188 deletions.
1 change: 1 addition & 0 deletions src/plugins/vis_type_drilldown/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@

This drilldown plugin allows users to design their own navigation controls, customized to fit their specific preferences and workflow requirements.
Please refer to [Drilldown functionality for dashboards](https://github.com/opensearch-project/OpenSearch-Dashboards/issues/1308)

5 changes: 2 additions & 3 deletions src/plugins/vis_type_drilldown/opensearch_dashboards.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@
"charts",
"expressions",
"visualizations",
"navigation",
"data",
"visDefaultEditor"
"visDefaultEditor",
"opensearchDashboardsReact"
],
"optionalPlugins": []
}
128 changes: 128 additions & 0 deletions src/plugins/vis_type_drilldown/public/components/card_form.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import React from 'react';
import {
EuiPanel,
EuiTitle,
EuiTextArea,
EuiFlexItem,
EuiFieldText,
EuiAccordion,
EuiFlexGroup,
EuiSuperSelect,
} from '@elastic/eui';
import { Card } from '../types';

interface CardFormProps {
index: number;
card: Card;
updateCard: (index: number, card: Card) => void;
options: any;
valueOfSelected: string;
onChange: () => void;
}

const CardForm = ({
index,
card,
updateCard,
options,
valueOfSelected,
onChange,
}: CardFormProps) => {
return (
<EuiAccordion
id={String(index)}
buttonContent={`Drilldown ${index + 1}`}
paddingSize="s"
initialIsOpen={true}
>
<EuiPanel paddingSize="s">
<EuiFlexGroup direction="column" gutterSize="m" className="eui-fullHeight">
<EuiFlexItem>
<EuiTitle size="xs">
<h2>
<label htmlFor="drilldownVisInput">Card Name</label>
</h2>
</EuiTitle>
</EuiFlexItem>

<EuiFlexItem>
<EuiFieldText
id="drilldownVisInput"
className="eui-fullHeight"
value={card.cardName}
onChange={({ target: { value } }) => {
updateCard(index, { ...card, cardName: value });
}}
fullWidth={true}
/>
</EuiFlexItem>

<EuiFlexItem>
<EuiTitle size="xs">
<h2>
<label htmlFor="drilldownVisInput">Description</label>
</h2>
</EuiTitle>
</EuiFlexItem>

<EuiFlexItem>
<EuiTextArea
id="markdownVisInput"
className="eui-fullHeight"
value={card.cardDescription}
onChange={({ target: { value } }) => {
updateCard(index, { ...card, cardDescription: value });
}}
fullWidth={true}
data-test-subj="markdownTextarea"
/>
</EuiFlexItem>

<EuiFlexItem>
<EuiTitle size="xs">
<h2>
<label htmlFor="drilldownVisInput">Url</label>
</h2>
</EuiTitle>
</EuiFlexItem>

<EuiFlexItem>
<EuiFieldText
id="drilldownVisInput"
placeholder=""
className="eui-fullHeight"
value={card.cardUrl}
onChange={({ target: { value } }) => {
updateCard(index, { ...card, cardUrl: value });
}}
fullWidth={true}
/>
</EuiFlexItem>

<EuiFlexItem>
<EuiTitle size="xs">
<h2>
<label htmlFor="drilldownVisInput">Select a Destination</label>
</h2>
</EuiTitle>
</EuiFlexItem>

<EuiSuperSelect
options={options}
valueOfSelected={valueOfSelected}
onChange={onChange}
fullWidth={true}
data-test-subj="chartPicker"
/>
</EuiFlexGroup>
</EuiPanel>
</EuiAccordion>
);
};

export { CardForm };
39 changes: 6 additions & 33 deletions src/plugins/vis_type_drilldown/public/drilldown_fn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import { i18n } from '@osd/i18n';
import { ExpressionFunctionDefinition, Render } from '../../expressions/public';
import { DrilldownVisParams, DrilldownArguments } from './types';
import { DrilldownArguments, DrilldownVisParams } from './types';

export interface DrilldownVisRenderValue {
visType: 'drilldown';
Expand All @@ -23,38 +23,14 @@ export const createDrilldownVisFn = (): DrilldownVisExpressionFunctionDefinition
name: 'drilldownVis',
type: 'render',
inputTypes: [],
help: i18n.translate('visDrilldown.function.help', {
help: i18n.translate('visTypeDrilldown.function.help', {
defaultMessage: 'Drilldown visualization',
}),
args: {
// font: {
// types: ['style'],
// help: i18n.translate('visTypeMarkdown.function.font.help', {
// defaultMessage: 'Font settings.',
// }),
// default: `{font size=12}`,
// },
// openLinksInNewTab: {
// types: ['boolean'],
// default: false,
// help: i18n.translate('visTypeMarkdown.function.openLinksInNewTab.help', {
// defaultMessage: 'Opens links in new tab',
// }),
// },
cardName: {
cards: {
types: ['string'],
aliases: ['_'],
required: true,
help: i18n.translate('visTypeDrilldown.function.cardName.help', {
defaultMessage: 'Card name',
}),
},
cardDescription: {
types: ['string'],
aliases: ['_'],
required: true,
help: i18n.translate('visTypeDrilldown.function.cardDescription.help', {
defaultMessage: 'Card description',
help: i18n.translate('visTypeDrilldown.function.cards.help', {
defaultMessage: 'Cards',
}),
},
},
Expand All @@ -65,10 +41,7 @@ export const createDrilldownVisFn = (): DrilldownVisExpressionFunctionDefinition
value: {
visType: 'drilldown',
visParams: {
cardName: args.cardName,
cardDescription: args.cardDescription,
// openLinksInNewTab: args.openLinksInNewTab,
// fontSize: parseInt(args.font.spec.fontSize || '12', 10),
cards: args.cards,
},
},
};
Expand Down
123 changes: 47 additions & 76 deletions src/plugins/vis_type_drilldown/public/drilldown_options.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,40 @@
* SPDX-License-Identifier: Apache-2.0
*/

import React, { useCallback, Fragment, useState, useEffect, useRef } from 'react';
import React, { useCallback, Fragment, useEffect, useRef } from 'react';
import {
EuiPanel,
EuiTitle,
EuiTextArea,
EuiFlexGroup,
EuiFlexItem,
EuiFieldText,
EuiAccordion,
EuiSuperSelect,
EuiText,
EuiButtonEmpty,
} from '@elastic/eui';

import { FormattedMessage } from '@osd/i18n/react';
import { VisOptionsProps } from 'src/plugins/vis_default_editor/public';
import { useOpenSearchDashboards } from '../../opensearch_dashboards_react/public';
import { DrilldownServices, DrilldownVisParams } from './types';
import { Card, DrilldownServices, DrilldownVisParams } from './types';
import { CardForm } from './components/card_form';

function DrilldownOptions({ stateParams, setValue }: VisOptionsProps<DrilldownVisParams>) {
const onMarkdownUpdate = useCallback(
(value: DrilldownVisParams['cardName']) => setValue('cardName', value),
[setValue]
const updateCard = useCallback(
(index: number, card: Card) => {
const updatedCards = [...stateParams.cards];
updatedCards[index] = card;
setValue('cards', updatedCards);
},
[stateParams.cards, setValue]
);

const addCardForm = useCallback(() => {
const newCard: Card = {
cardName: 'newDrilldownCard',
cardDescription: 'newDrilldownCard',
cardUrl: 'newDrilldownCard',
};
setValue('cards', [...stateParams.cards, newCard]);
}, [stateParams.cards, setValue]);

const {
services: { http, savedObjects },
} = useOpenSearchDashboards<DrilldownServices>();
Expand Down Expand Up @@ -56,14 +67,14 @@ function DrilldownOptions({ stateParams, setValue }: VisOptionsProps<DrilldownVi
]);

const saved = useRef<any>();
const index = useRef<any>();
// const index = useRef<any>();

useEffect(() => {
const fetchData = async () => {
saved.current = savedObjects?.client.find({
type: 'dashboard',
});
const path = (await saved.current).savedObjects[0]['client']
const path = (await saved.current).savedObjects[0].client
.getPath(['dashboard', (await saved.current).savedObjects[0].id])
.substring(28);
const savedObjectURL = http.basePath.prepend('/app/dashboards#/view/' + path);
Expand All @@ -87,76 +98,36 @@ function DrilldownOptions({ stateParams, setValue }: VisOptionsProps<DrilldownVi
];
};
fetchData();
}, []);

const onDescriptionUpdate = useCallback(
(value: DrilldownVisParams['cardDescription']) => setValue('cardDescription', value),
[setValue]
);
});

const activeVisName = '';
const handleVisTypeChange = () => {};

return (
<EuiAccordion buttonContent="Drilldown 1">
<EuiPanel paddingSize="s">
<EuiFlexGroup direction="column" gutterSize="m" className="eui-fullHeight">
<EuiFlexItem>
<EuiTitle size="xs">
<h2>
<label htmlFor="drilldownVisInput">Card Name</label>
</h2>
</EuiTitle>
</EuiFlexItem>

<EuiFlexItem>
<EuiFieldText
id="drilldownVisInput"
placeholder="Placeholder text"
className="eui-fullHeight"
value={stateParams.cardName}
onChange={({ target: { value } }) => onMarkdownUpdate(value)}
fullWidth={true}
/>
</EuiFlexItem>

<EuiFlexItem>
<EuiTitle size="xs">
<h2>
<label htmlFor="drilldownVisInput">Description</label>
</h2>
</EuiTitle>
</EuiFlexItem>

<EuiFlexItem>
<EuiTextArea
id="markdownVisInput"
className="eui-fullHeight"
value={stateParams.cardDescription}
onChange={({ target: { value } }) => onDescriptionUpdate(value)}
fullWidth={true}
data-test-subj="markdownTextarea"
<EuiFlexGroup
className="visEditorSidebar"
justifyContent="spaceBetween"
gutterSize="none"
responsive={false}
direction="column"
>
{stateParams.cards &&
stateParams.cards.map((card, index) => (
<>
<CardForm
index={index}
card={card}
updateCard={updateCard}
options={options.current}
valueOfSelected={activeVisName}
onChange={handleVisTypeChange}
/>
</EuiFlexItem>

<EuiFlexItem>
<EuiTitle size="xs">
<h2>
<label htmlFor="drilldownVisInput">Select a Destination</label>
</h2>
</EuiTitle>
</EuiFlexItem>

<EuiSuperSelect
options={options.current}
valueOfSelected={activeVisName}
onChange={handleVisTypeChange}
fullWidth
data-test-subj="chartPicker"
/>
</EuiFlexGroup>
</EuiPanel>
</EuiAccordion>
</>
))}
<EuiButtonEmpty size="xs" iconType="plusInCircleFilled" onClick={addCardForm}>
<FormattedMessage id="visDefaultEditor.aggAdd.addButtonLabel" defaultMessage="Add" />
</EuiButtonEmpty>
</EuiFlexGroup>
);
}

Expand Down
Loading

0 comments on commit fc0915f

Please sign in to comment.