Hi !
I’m trying develop a configuration section in my plugin.
The configuration section is shown but my “edit configuration” button does not show the bootstrap modal on click. In fact nothing happen and no javascript error is raised.
The code:
Settings.jsx
import React, { useState } from 'react';
import { useStore } from 'stores/connect';
import { StreamsStore } from 'views/stores/StreamsStore';
import { defaultCompare } from 'logic/DefaultCompare'
import { BootstrapModalForm, Button, Input } from 'components/bootstrap';
import IfPermitted from 'components/common/IfPermitted';
import Select from 'components/common/Select';
import Spinner from 'components/common/Spinner';
const DEFAULT_CONFIG = {
graylog_endpoint: 'https://127.0.0.1:9000',
example_service_token: 'XXX',
};
const _formatOption = (key, value) => {
return { value: value, label: key };
};
const _displayOptionalConfigurationValue = (value) => {
if (!value) {
return '[not set]';
}
return value;
};
const Settings = ({ config = DEFAULT_CONFIG, updateConfig }) => {
const [nextConfiguration, setNextConfiguration] = useState(config);
const [showModal, setShowModal] = useState(false);
const { streams: streamList = [] } = useStore(StreamsStore);
const _openModal = () => {
setShowModal(true);
};
const _closeModal = () => {
setShowModal(false);
};
/* TODO is this necessary?
useEffect(() => {
setNextConfiguration({ ...config });
}, [config]);
*/
const _saveConfiguration = () => {
updateConfig(nextConfiguration).then(() => {
_closeModal();
})
};
const _resetConfiguration = () => {
setNextConfiguration(config);
};
const _updateConfigurationField = (field, value) => {
const newConfiguration = {...nextConfiguration};
newConfiguration[field] = value;
setNextConfiguration(newConfiguration);
};
const _onUpdate = (field) => {
return e => {
_updateConfigurationField(field, e.target.value);
};
};
if (!streamList) {
return <Spinner />;
}
const formattedStreams = streamList
.map(stream => _formatOption(stream.title, stream.id))
.sort((s1, s2) => defaultCompare(s1.label.toLowerCase(), s2.label.toLowerCase()));
return (
<div>
<h3>ExampleConfiguration</h3>
<p>
Example needs two parameters:\n
Graylog endpoint : The SIEM endpoint for API requesting\n
Example service token: A graylog service token for API authentication
</p>
<dl className="deflist">
<dt>Graylog endpoint: </dt>
<dd>
{_displayOptionalConfigurationValue(config.graylog_endpoint)}
</dd>
</dl>
<dl className="deflist">
<dt>Example service token: </dt>
<dd>
{_displayOptionalConfigurationValue(config.example_service_token)}
</dd>
</dl>
<IfPermitted permissions="clusterconfigentry:edit">
<Button bsStyle="info" bsSize="xs" onClick={_openModal}>
Edit configuration test
</Button>
</IfPermitted>
<BootstrapModalForm
show={showModal}
title="Update example Configuration"
onSubmitForm={_saveConfiguration}
onCancel={_resetConfiguration}
submitButtonText="Save">
<fieldset>
<Input
id="graylog_endpoint"
type="text"
label="Graylog endpoint"
name="graylog_endpoint"
help="Graylog endpoint for API requesting."
value={nextConfiguration.graylog_endpoint}
onChange={_onUpdate('graylog_endpoint')}
/>
<Input
id="example_service_token"
type="text"
label="example service token"
name="example_service_token"
help="example service token for API authentication."
value={nextConfiguration.example_service_token}
onChange={_onUpdate('example_service_token')}
/>
</fieldset>
</BootstrapModalForm>
</div>
);
};
export default Settings;
Settings.java
package com.package.graylog;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.auto.value.AutoValue;
import javax.annotation.Nullable;
import static org.graylog2.plugin.streams.Stream.DEFAULT_STREAM_ID;
/**
* This is the general configuration of the plugin (see System/Configurations)
* It is probably linked to the IHM, just by the configuration in the web index.jsx.
*/
@JsonAutoDetect
@AutoValue
public abstract class Settings {
@JsonProperty("graylog_endpoint")
public abstract String accessGraylogEndpoint();
@JsonProperty("example_service_token")
public abstract String accessexampleServiceToken();
@JsonCreator
public static Settings create(
@JsonProperty("graylog_endpoint") String graylog_endpoint,
@JsonProperty("example_service_token") String examplel_service_token){
return builder()
.accessGraylogEndpoint(graylog_endpoint)
.accessExampleServiceToken(examplel_service_token)
.build();
}
public static Settings createDefault() {
return builder()
.accessGraylogEndpoint("https://127.0.0.1:9000")
.accessExampleServiceToken("XXX")
.build();
}
public static Builder builder() {
return new AutoValue_Settings.Builder();
}
public abstract Builder toBuilder();
@AutoValue.Builder
public abstract static class Builder {
public abstract Builder accessGraylogEndpoint(String accessGraylogEndpoint);
public abstract Builder accessExampleServiceToken(String accessExampleServiceToken);
public abstract Settings build();
}
}
Index.jsx
import packageJson from '../../package.json';
import { PluginManifest, PluginStore } from 'graylog-web-plugin/plugin';
import SamplePage from 'pages/SamplePage';
import Settings from "./components/settings";
PluginStore.register(new PluginManifest(packageJson, {
/* This is the place where you define which entities you are providing to the web interface.
Right now you can add routes and navigation elements to it. */
systemConfigurations: [
{
component: Settings,
configType: 'com.package.graylog.Settings',
},
],
routes: [
{path: '/example', component: SamplePage},
],
navigation: [
{
path: '/example', description: 'Example'
},
],
}));