mirror of https://github.com/apache/druid.git
Web console: misc bug fixes (#14216)
* fixing little things * clear edit columns when switching to SQL tab * updated snapshots
This commit is contained in:
parent
6ca3fb9b08
commit
4c15e978f1
|
@ -2154,9 +2154,9 @@ export function issueWithSampleData(
|
|||
if (firstData === '{') {
|
||||
return (
|
||||
<>
|
||||
This data looks like regular JSON object. For Druid to parse a text file it must have one
|
||||
row per event. Maybe look at{' '}
|
||||
<ExternalLink href="http://ndjson.org/">newline delimited JSON</ExternalLink> instead.
|
||||
This data looks like multi-line formatted JSON object. For Druid to parse a text file it
|
||||
must have one row per event. Consider reformatting your data as{' '}
|
||||
<ExternalLink href="http://ndjson.org/">newline delimited JSON</ExternalLink>.
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -2165,8 +2165,8 @@ export function issueWithSampleData(
|
|||
return (
|
||||
<>
|
||||
This data looks like a multi-line JSON array. For Druid to parse a text file it must have
|
||||
one row per event. Maybe look at{' '}
|
||||
<ExternalLink href="http://ndjson.org/">newline delimited JSON</ExternalLink> instead.
|
||||
one row per event. Consider reformatting your data as{' '}
|
||||
<ExternalLink href="http://ndjson.org/">newline delimited JSON</ExternalLink>.
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -100,8 +100,8 @@ export const ReactTablePagination = React.memo(function ReactTablePagination(
|
|||
|
||||
const start = page * pageSize + 1;
|
||||
let end = page * pageSize + pageSize;
|
||||
if (nonEmptyArray(sortedData)) {
|
||||
end = Math.min(end, page * pageSize + sortedData.length);
|
||||
if (nonEmptyArray(sortedData) && (page === 0 || sortedData.length > pageSize)) {
|
||||
end = Math.min(end, sortedData.length);
|
||||
}
|
||||
|
||||
let pageInfo = 'Showing';
|
||||
|
@ -110,7 +110,7 @@ export const ReactTablePagination = React.memo(function ReactTablePagination(
|
|||
} else {
|
||||
pageInfo += '...';
|
||||
}
|
||||
if (ofText && Array.isArray(sortedData)) {
|
||||
if (ofText && nonEmptyArray(sortedData)) {
|
||||
pageInfo += ` ${ofText} ${formatInteger(sortedData.length)}`;
|
||||
}
|
||||
|
||||
|
|
|
@ -171,7 +171,10 @@ export async function getProxyOverlordModules(): Promise<string[]> {
|
|||
throw new Error(getDruidErrorMessage(e));
|
||||
}
|
||||
|
||||
return statusResp.data.modules.map((m: any) => m.artifact);
|
||||
const { modules } = statusResp.data;
|
||||
if (!Array.isArray(modules)) throw new Error('unexpected result from overlord/status');
|
||||
|
||||
return modules.map((m: any) => m.artifact);
|
||||
}
|
||||
|
||||
export async function postToSampler(
|
||||
|
|
|
@ -159,7 +159,148 @@ exports[`LoadDataView matches snapshot batch 1`] = `
|
|||
<div
|
||||
className="ingestion-cards"
|
||||
>
|
||||
<React.Fragment />
|
||||
<React.Fragment>
|
||||
<Blueprint4.Card
|
||||
className="ingestion-card"
|
||||
elevation={1}
|
||||
interactive={true}
|
||||
onClick={[Function]}
|
||||
>
|
||||
<img
|
||||
alt="Ingestion tile for index_parallel:s3"
|
||||
src="/some/base_url/assets/s3.png"
|
||||
/>
|
||||
<p>
|
||||
Amazon S3
|
||||
</p>
|
||||
</Blueprint4.Card>
|
||||
<Blueprint4.Card
|
||||
className="ingestion-card"
|
||||
elevation={1}
|
||||
interactive={true}
|
||||
onClick={[Function]}
|
||||
>
|
||||
<img
|
||||
alt="Ingestion tile for index_parallel:azure"
|
||||
src="/some/base_url/assets/azure.png"
|
||||
/>
|
||||
<p>
|
||||
Azure Data Lake
|
||||
</p>
|
||||
</Blueprint4.Card>
|
||||
<Blueprint4.Card
|
||||
className="ingestion-card"
|
||||
elevation={1}
|
||||
interactive={true}
|
||||
onClick={[Function]}
|
||||
>
|
||||
<img
|
||||
alt="Ingestion tile for index_parallel:google"
|
||||
src="/some/base_url/assets/google.png"
|
||||
/>
|
||||
<p>
|
||||
Google Cloud Storage
|
||||
</p>
|
||||
</Blueprint4.Card>
|
||||
<Blueprint4.Card
|
||||
className="ingestion-card"
|
||||
elevation={1}
|
||||
interactive={true}
|
||||
onClick={[Function]}
|
||||
>
|
||||
<img
|
||||
alt="Ingestion tile for index_parallel:hdfs"
|
||||
src="/some/base_url/assets/hdfs.png"
|
||||
/>
|
||||
<p>
|
||||
HDFS
|
||||
</p>
|
||||
</Blueprint4.Card>
|
||||
<Blueprint4.Card
|
||||
className="ingestion-card"
|
||||
elevation={1}
|
||||
interactive={true}
|
||||
onClick={[Function]}
|
||||
>
|
||||
<img
|
||||
alt="Ingestion tile for index_parallel:druid"
|
||||
src="/some/base_url/assets/druid.png"
|
||||
/>
|
||||
<p>
|
||||
Reindex from Druid
|
||||
</p>
|
||||
</Blueprint4.Card>
|
||||
<Blueprint4.Card
|
||||
className="ingestion-card"
|
||||
elevation={1}
|
||||
interactive={true}
|
||||
onClick={[Function]}
|
||||
>
|
||||
<img
|
||||
alt="Ingestion tile for index_parallel:http"
|
||||
src="/some/base_url/assets/http.png"
|
||||
/>
|
||||
<p>
|
||||
HTTP(s)
|
||||
</p>
|
||||
</Blueprint4.Card>
|
||||
<Blueprint4.Card
|
||||
className="ingestion-card"
|
||||
elevation={1}
|
||||
interactive={true}
|
||||
onClick={[Function]}
|
||||
>
|
||||
<img
|
||||
alt="Ingestion tile for index_parallel:local"
|
||||
src="/some/base_url/assets/local.png"
|
||||
/>
|
||||
<p>
|
||||
Local disk
|
||||
</p>
|
||||
</Blueprint4.Card>
|
||||
<Blueprint4.Card
|
||||
className="ingestion-card"
|
||||
elevation={1}
|
||||
interactive={true}
|
||||
onClick={[Function]}
|
||||
>
|
||||
<img
|
||||
alt="Ingestion tile for index_parallel:inline"
|
||||
src="/some/base_url/assets/inline.png"
|
||||
/>
|
||||
<p>
|
||||
Paste data
|
||||
</p>
|
||||
</Blueprint4.Card>
|
||||
<Blueprint4.Card
|
||||
className="ingestion-card"
|
||||
elevation={1}
|
||||
interactive={true}
|
||||
onClick={[Function]}
|
||||
>
|
||||
<img
|
||||
alt="Ingestion tile for example"
|
||||
src="/some/base_url/assets/example.png"
|
||||
/>
|
||||
<p>
|
||||
Example data
|
||||
</p>
|
||||
</Blueprint4.Card>
|
||||
</React.Fragment>
|
||||
<Blueprint4.Card
|
||||
className="ingestion-card"
|
||||
elevation={1}
|
||||
interactive={true}
|
||||
onClick={[Function]}
|
||||
>
|
||||
<img
|
||||
alt="Ingestion tile for other"
|
||||
src="/some/base_url/assets/other.png"
|
||||
/>
|
||||
<p>
|
||||
Other
|
||||
</p>
|
||||
</Blueprint4.Card>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
|
@ -336,7 +477,64 @@ exports[`LoadDataView matches snapshot streaming 1`] = `
|
|||
<div
|
||||
className="ingestion-cards"
|
||||
>
|
||||
<React.Fragment />
|
||||
<React.Fragment>
|
||||
<Blueprint4.Card
|
||||
className="ingestion-card"
|
||||
elevation={1}
|
||||
interactive={true}
|
||||
onClick={[Function]}
|
||||
>
|
||||
<img
|
||||
alt="Ingestion tile for kafka"
|
||||
src="/some/base_url/assets/kafka.png"
|
||||
/>
|
||||
<p>
|
||||
Apache Kafka
|
||||
</p>
|
||||
</Blueprint4.Card>
|
||||
<Blueprint4.Card
|
||||
className="ingestion-card"
|
||||
elevation={1}
|
||||
interactive={true}
|
||||
onClick={[Function]}
|
||||
>
|
||||
<img
|
||||
alt="Ingestion tile for kinesis"
|
||||
src="/some/base_url/assets/kinesis.png"
|
||||
/>
|
||||
<p>
|
||||
Amazon Kinesis
|
||||
</p>
|
||||
</Blueprint4.Card>
|
||||
<Blueprint4.Card
|
||||
className="ingestion-card"
|
||||
elevation={1}
|
||||
interactive={true}
|
||||
onClick={[Function]}
|
||||
>
|
||||
<img
|
||||
alt="Ingestion tile for azure-event-hubs"
|
||||
src="/some/base_url/assets/azure-event-hubs.png"
|
||||
/>
|
||||
<p>
|
||||
Azure Event Hub
|
||||
</p>
|
||||
</Blueprint4.Card>
|
||||
</React.Fragment>
|
||||
<Blueprint4.Card
|
||||
className="ingestion-card"
|
||||
elevation={1}
|
||||
interactive={true}
|
||||
onClick={[Function]}
|
||||
>
|
||||
<img
|
||||
alt="Ingestion tile for other"
|
||||
src="/some/base_url/assets/other.png"
|
||||
/>
|
||||
<p>
|
||||
Other
|
||||
</p>
|
||||
</Blueprint4.Card>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
|
|
|
@ -498,10 +498,10 @@ export class LoadDataView extends React.PureComponent<LoadDataViewProps, LoadDat
|
|||
overlordModules = await getProxyOverlordModules();
|
||||
} catch (e) {
|
||||
AppToaster.show({
|
||||
message: `Failed to get overlord modules: ${e.message}`,
|
||||
message: `Failed to get the list of loaded modules from the overlord: ${e.message}`,
|
||||
intent: Intent.DANGER,
|
||||
});
|
||||
this.setState({ overlordModules: [] });
|
||||
this.setState({ overlordModules: undefined });
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -810,9 +810,10 @@ export class LoadDataView extends React.PureComponent<LoadDataViewProps, LoadDat
|
|||
disabled?: boolean,
|
||||
): JSX.Element | undefined {
|
||||
const { overlordModules, selectedComboType, spec } = this.state;
|
||||
if (!overlordModules) return;
|
||||
const requiredModule = getRequiredModule(comboType);
|
||||
const goodToGo = !disabled && (!requiredModule || overlordModules.includes(requiredModule));
|
||||
const goodToGo =
|
||||
!disabled &&
|
||||
(!requiredModule || !overlordModules || overlordModules.includes(requiredModule));
|
||||
|
||||
return (
|
||||
<Card
|
||||
|
@ -1124,7 +1125,7 @@ export class LoadDataView extends React.PureComponent<LoadDataViewProps, LoadDat
|
|||
<p>
|
||||
Please make sure that the
|
||||
<Code>"{requiredModule}"</Code> extension is included in the{' '}
|
||||
<Code>loadList</Code>.
|
||||
<Code>druid.extensions.loadList</Code>.
|
||||
</p>
|
||||
<p>
|
||||
For more information please refer to the{' '}
|
||||
|
|
|
@ -299,12 +299,30 @@ export const SchemaStep = function SchemaStep(props: SchemaStepProps) {
|
|||
onQueryStringChange(parsedQuery.apply(queryAction).toString());
|
||||
});
|
||||
|
||||
const handleModeSelect = (newMode: Mode) => {
|
||||
if (newMode === 'sql' && editorColumn) {
|
||||
if (editorColumn.dirty) {
|
||||
AppToaster.show({
|
||||
message:
|
||||
'Please save or discard the changes in the column editor before switching to the SQL tab.',
|
||||
intent: Intent.WARNING,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
setEditorColumn(undefined);
|
||||
}
|
||||
|
||||
setMode(newMode);
|
||||
};
|
||||
|
||||
const handleColumnSelect = usePermanentCallback((index: number) => {
|
||||
if (!ingestQueryPattern) return;
|
||||
|
||||
if (editorColumn?.dirty) {
|
||||
AppToaster.show({
|
||||
message: 'Please save or discard the changes in the column editor.',
|
||||
message:
|
||||
'Please save or discard the changes in the column editor before switching columns.',
|
||||
intent: Intent.WARNING,
|
||||
});
|
||||
return;
|
||||
|
@ -697,20 +715,20 @@ export const SchemaStep = function SchemaStep(props: SchemaStepProps) {
|
|||
text="Table"
|
||||
disabled={!ingestQueryPattern}
|
||||
active={effectiveMode === 'table'}
|
||||
onClick={() => setMode('table')}
|
||||
onClick={() => handleModeSelect('table')}
|
||||
/>
|
||||
<Button
|
||||
icon={IconNames.LIST_COLUMNS}
|
||||
text="List"
|
||||
disabled={!ingestQueryPattern}
|
||||
active={effectiveMode === 'list'}
|
||||
onClick={() => setMode('list')}
|
||||
onClick={() => handleModeSelect('list')}
|
||||
/>
|
||||
<Button
|
||||
icon={IconNames.APPLICATION}
|
||||
text="SQL"
|
||||
active={effectiveMode === 'sql'}
|
||||
onClick={() => setMode('sql')}
|
||||
onClick={() => handleModeSelect('sql')}
|
||||
/>
|
||||
</ButtonGroup>
|
||||
{enableAnalyze && ingestQueryPattern?.metrics && (
|
||||
|
|
Loading…
Reference in New Issue