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

[Graph] Save modal #44261

Merged
merged 39 commits into from
Sep 5, 2019
Merged
Show file tree
Hide file tree
Changes from 37 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
067158a
create graph listing page
flash1293 Aug 26, 2019
5fddc10
clean up app folder
flash1293 Aug 26, 2019
95f003b
remove inline loading menu
flash1293 Aug 27, 2019
ae44388
also add badge to workspace route
flash1293 Aug 27, 2019
2f1056f
fix tests
flash1293 Aug 27, 2019
5d637f5
fix graph spaces functional test
flash1293 Aug 27, 2019
9d17862
generate documentation for new breadcrumb property
flash1293 Aug 27, 2019
db1d740
fix test subject names
flash1293 Aug 27, 2019
e09b70d
remove unused translations
flash1293 Aug 27, 2019
2dab994
start implementing save modal flow for Graph
flash1293 Aug 27, 2019
c34d845
fix spaces functional test
flash1293 Aug 27, 2019
2d775e6
wip save modal
flash1293 Aug 27, 2019
ebe80d1
wip save modal
flash1293 Aug 27, 2019
fab1577
add and style save modal
flash1293 Aug 28, 2019
a9d31c8
add placeholder to description field
flash1293 Aug 28, 2019
9d2822e
Merge remote-tracking branch 'upstream/master' into graph/listing-page
flash1293 Aug 28, 2019
d0b9247
Merge remote-tracking branch 'upstream/master' into graph/listing-page
flash1293 Aug 29, 2019
d187eae
disable dirty check on breadcrumb navigation and fix delete function
flash1293 Aug 29, 2019
21ba056
Merge branch 'graph/listing-page' into graph/savemodal
flash1293 Aug 29, 2019
a289d7d
improve onClick typing on breadcrumb
flash1293 Aug 29, 2019
989481c
Merge branch 'graph/listing-page' into graph/savemodal
flash1293 Aug 29, 2019
be1e59a
fix newline error and use new types in dashboard app controller
flash1293 Aug 29, 2019
c5ac49b
fix translation errors
flash1293 Aug 30, 2019
8d6cec1
fix i18n translation for real
flash1293 Aug 30, 2019
0472505
Merge remote-tracking branch 'upstream/master' into graph/savemodal
flash1293 Aug 30, 2019
173804a
code review
flash1293 Sep 2, 2019
54e9a7b
Merge remote-tracking branch 'upstream/master' into graph/savemodal
flash1293 Sep 2, 2019
6f1bbca
fix i18n phrases
flash1293 Sep 2, 2019
7c94337
remove fragments
flash1293 Sep 2, 2019
f489b07
Merge remote-tracking branch 'upstream/master' into graph/savemodal
flash1293 Sep 4, 2019
bcc280f
remove unnecessary max-width and add commentary
flash1293 Sep 5, 2019
a578814
move to async syntax
flash1293 Sep 5, 2019
4897b52
clean up implementation
flash1293 Sep 5, 2019
7b2b91b
use description instead of title
flash1293 Sep 5, 2019
208b4db
Merge remote-tracking branch 'upstream/master' into graph/savemodal
flash1293 Sep 5, 2019
e4b9aa0
fix snapshot
flash1293 Sep 5, 2019
1195f36
adress review comments and set width for all save modals
flash1293 Sep 5, 2019
372f3b4
fix bug and improve typing
flash1293 Sep 5, 2019
3de7e4f
fix classname
flash1293 Sep 5, 2019
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 @@ -33,7 +33,6 @@ import { FilterBarQueryFilterProvider } from 'ui/filter_manager/query_filter';

import { docTitle } from 'ui/doc_title/doc_title';

// @ts-ignore
import { showSaveModal } from 'ui/saved_objects/show_saved_object_save_modal';

import { showShareContextMenu, ShareContextMenuExtensionsRegistryProvider } from 'ui/share';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,6 @@ import 'uiExports/visualize';
import { i18n } from '@kbn/i18n';

import { capabilities } from 'ui/capabilities';
// @ts-ignore
import { showSaveModal } from 'ui/saved_objects/show_saved_object_save_modal';
// @ts-ignore
import { SavedObjectSaveModal } from 'ui/saved_objects/components/saved_object_save_modal';

import chrome from 'ui/chrome';
import { getVisualizeLoader } from 'ui/visualize/loader';
Expand Down
1 change: 1 addition & 0 deletions src/legacy/ui/public/_index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
@import './exit_full_screen/index';
@import './field_editor/index';
@import './notify/index';
@import './saved_objects/index';
@import './share/index';
@import './style_compile/index';

Expand Down
1 change: 1 addition & 0 deletions src/legacy/ui/public/saved_objects/_index.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@import '../../../../plugins/kibana_react/public/saved_objects/index';
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,25 @@ import React from 'react';
import ReactDOM from 'react-dom';
import { I18nContext } from 'ui/i18n';

export function showSaveModal(saveModal) {
/**
* Represents the result of trying to persist the saved object.
* Contains `error` prop if something unexpected happened (e.g. network error).
* Contains an `id` if persisting was successful. If `id` and
* `error` are undefined, persisting was not successful, but the
* modal can still recover (e.g. the name of the saved object was already taken).
*/
type SaveResult = { id?: string } | { error: Error };

function isError(result: SaveResult): result is { error: Error } {
return 'error' in result;
}

interface MinimalSaveModalProps {
onSave: (...args: any[]) => Promise<SaveResult>;
onClose: () => void;
}

export function showSaveModal(saveModal: React.ReactElement<MinimalSaveModalProps>) {
const container = document.createElement('div');
const closeModal = () => {
ReactDOM.unmountComponentAtNode(container);
Expand All @@ -30,21 +48,19 @@ export function showSaveModal(saveModal) {

const onSave = saveModal.props.onSave;

const onSaveConfirmed = (...args) => {
onSave(...args).then(({ id, error }) => {
if (id || error) {
closeModal();
}
});
const onSaveConfirmed: MinimalSaveModalProps['onSave'] = async (...args) => {
const response = await onSave(...args);
// close modal if we either hit an error or the saved object got an id
if (Boolean(isError(response) ? response.error : response.id)) {
closeModal();
}
return response;
};
document.body.appendChild(container);
const element = React.cloneElement(
saveModal,
{
onSave: onSaveConfirmed,
onClose: closeModal
}
);
const element = React.cloneElement(saveModal, {
onSave: onSaveConfirmed,
onClose: closeModal,
});

ReactDOM.render(<I18nContext>{element}</I18nContext>, container);
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/plugins/kibana_react/public/saved_objects/_index.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@import './saved_object_save_modal';
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.saveModal {
width: $euiSizeXXL * 10;
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,9 @@ import {
import { FormattedMessage } from '@kbn/i18n/react';
import React from 'react';
import { EuiText } from '@elastic/eui';
import { i18n } from '@kbn/i18n';

interface OnSaveProps {
export interface OnSaveProps {
newTitle: string;
newCopyOnSave: boolean;
isTitleDuplicateConfirmed: boolean;
Expand Down Expand Up @@ -72,14 +73,14 @@ export class SavedObjectSaveModal extends React.Component<Props, State> {
};

public render() {
const { isTitleDuplicateConfirmed, hasTitleDuplicate, title, isLoading } = this.state;
const { isTitleDuplicateConfirmed, hasTitleDuplicate, title } = this.state;

return (
<EuiOverlayMask>
<form onSubmit={this.onFormSubmit}>
<EuiModal
data-test-subj="savedObjectSaveModal"
className="dshSaveModal"
className="saveModal"
Copy link
Contributor

Choose a reason for hiding this comment

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

This className needs a prefix to be less specific and match BEM naming conventions. Since this is a Kibana global component I'd call it

Suggested change
className="saveModal"
className="kbnSavedObjectSaveModal"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good suggestion, I renamed it

onClose={this.props.onClose}
>
<EuiModalHeader>
Expand Down Expand Up @@ -136,22 +137,7 @@ export class SavedObjectSaveModal extends React.Component<Props, State> {
/>
</EuiButtonEmpty>

<EuiButton
fill
data-test-subj="confirmSaveSavedObjectButton"
isLoading={isLoading}
isDisabled={title.length === 0}
type="submit"
>
{this.props.confirmButtonLabel ? (
this.props.confirmButtonLabel
) : (
<FormattedMessage
id="kibana-react.savedObjects.saveModal.confirmSaveButtonLabel"
defaultMessage="Confirm Save"
/>
)}
</EuiButton>
{this.renderConfirmButton()}
</EuiModalFooter>
</EuiModal>
</form>
Expand Down Expand Up @@ -204,6 +190,34 @@ export class SavedObjectSaveModal extends React.Component<Props, State> {
this.saveSavedObject();
};

private renderConfirmButton = () => {
const { isLoading, title, hasTitleDuplicate } = this.state;

let confirmLabel: string | React.ReactNode = hasTitleDuplicate
? i18n.translate('kibana-react.savedObjects.saveModal.confirmSaveButtonLabel', {
defaultMessage: 'Confirm save',
})
: i18n.translate('kibana-react.savedObjects.saveModal.saveButtonLabel', {
defaultMessage: 'Save',
});

if (this.props.confirmButtonLabel) {
confirmLabel = this.props.confirmButtonLabel;
}

return (
<EuiButton
fill
data-test-subj="confirmSaveSavedObjectButton"
isLoading={isLoading}
isDisabled={title.length === 0}
type="submit"
>
{confirmLabel}
</EuiButton>
);
};

private renderDuplicateTitleCallout = () => {
if (!this.state.hasTitleDuplicate) {
return;
Expand All @@ -230,10 +244,14 @@ export class SavedObjectSaveModal extends React.Component<Props, State> {
objectType: this.props.objectType,
confirmSaveLabel: (
<strong>
<FormattedMessage
id="kibana-react.savedObjects.saveModal.duplicateTitleDescription.confirmSaveText"
defaultMessage="Confirm Save"
/>
{this.props.confirmButtonLabel
? this.props.confirmButtonLabel
: i18n.translate(
lizozom marked this conversation as resolved.
Show resolved Hide resolved
'kibana-react.savedObjects.saveModal.duplicateTitleDescription.confirmSaveText',
{
defaultMessage: 'Confirm save',
}
)}
</strong>
),
}}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
<kbn-top-nav name="workspacesTopNav" config="topNavMenu">
</kbn-top-nav>

<div class="gphGraph__menus" ng-show="menus.showSave || menus.showSettings">
<graph-save ng-show="menus.showSave"></graph-save>
<div class="gphGraph__menus" ng-show="menus.showSettings">
<graph-settings ng-show="menus.showSettings"></graph-settings>
</div>

Expand Down

This file was deleted.

Loading