Ask for confirmation on leaving pages with incomplete forms. Fixes #529
This commit is contained in:
parent
c3d4538219
commit
3b82f4887b
6 changed files with 266 additions and 217 deletions
5
ui/src/components/comment-form.tsx
vendored
5
ui/src/components/comment-form.tsx
vendored
|
@ -1,4 +1,5 @@
|
||||||
import { Component, linkEvent } from 'inferno';
|
import { Component, linkEvent } from 'inferno';
|
||||||
|
import { Prompt } from 'inferno-router';
|
||||||
import {
|
import {
|
||||||
CommentNode as CommentNodeI,
|
CommentNode as CommentNodeI,
|
||||||
CommentForm as CommentFormI,
|
CommentForm as CommentFormI,
|
||||||
|
@ -87,6 +88,10 @@ export class CommentForm extends Component<CommentFormProps, CommentFormState> {
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
|
<Prompt
|
||||||
|
when={this.state.commentForm.content}
|
||||||
|
message={i18n.t('block_leaving')}
|
||||||
|
/>
|
||||||
<form onSubmit={linkEvent(this, this.handleCommentSubmit)}>
|
<form onSubmit={linkEvent(this, this.handleCommentSubmit)}>
|
||||||
<div class="form-group row">
|
<div class="form-group row">
|
||||||
<div className={`col-sm-12`}>
|
<div className={`col-sm-12`}>
|
||||||
|
|
230
ui/src/components/community-form.tsx
vendored
230
ui/src/components/community-form.tsx
vendored
|
@ -1,4 +1,5 @@
|
||||||
import { Component, linkEvent } from 'inferno';
|
import { Component, linkEvent } from 'inferno';
|
||||||
|
import { Prompt } from 'inferno-router';
|
||||||
import { Subscription } from 'rxjs';
|
import { Subscription } from 'rxjs';
|
||||||
import { retryWhen, delay, take } from 'rxjs/operators';
|
import { retryWhen, delay, take } from 'rxjs/operators';
|
||||||
import {
|
import {
|
||||||
|
@ -105,120 +106,131 @@ export class CommunityForm extends Component<
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<form onSubmit={linkEvent(this, this.handleCreateCommunitySubmit)}>
|
<>
|
||||||
<div class="form-group row">
|
<Prompt
|
||||||
<label class="col-12 col-form-label" htmlFor="community-name">
|
when={
|
||||||
{i18n.t('name')}
|
!this.state.loading &&
|
||||||
</label>
|
(this.state.communityForm.name ||
|
||||||
<div class="col-12">
|
this.state.communityForm.title ||
|
||||||
<input
|
this.state.communityForm.description)
|
||||||
type="text"
|
}
|
||||||
id="community-name"
|
message={i18n.t('block_leaving')}
|
||||||
class="form-control"
|
/>
|
||||||
value={this.state.communityForm.name}
|
<form onSubmit={linkEvent(this, this.handleCreateCommunitySubmit)}>
|
||||||
onInput={linkEvent(this, this.handleCommunityNameChange)}
|
|
||||||
required
|
|
||||||
minLength={3}
|
|
||||||
maxLength={20}
|
|
||||||
pattern="[a-z0-9_]+"
|
|
||||||
title={i18n.t('community_reqs')}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group row">
|
|
||||||
<label class="col-12 col-form-label" htmlFor="community-title">
|
|
||||||
{i18n.t('title')}
|
|
||||||
</label>
|
|
||||||
<div class="col-12">
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
id="community-title"
|
|
||||||
value={this.state.communityForm.title}
|
|
||||||
onInput={linkEvent(this, this.handleCommunityTitleChange)}
|
|
||||||
class="form-control"
|
|
||||||
required
|
|
||||||
minLength={3}
|
|
||||||
maxLength={100}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group row">
|
|
||||||
<label class="col-12 col-form-label" htmlFor={this.id}>
|
|
||||||
{i18n.t('sidebar')}
|
|
||||||
</label>
|
|
||||||
<div class="col-12">
|
|
||||||
<textarea
|
|
||||||
id={this.id}
|
|
||||||
value={this.state.communityForm.description}
|
|
||||||
onInput={linkEvent(this, this.handleCommunityDescriptionChange)}
|
|
||||||
class="form-control"
|
|
||||||
rows={3}
|
|
||||||
maxLength={10000}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group row">
|
|
||||||
<label class="col-12 col-form-label" htmlFor="community-category">
|
|
||||||
{i18n.t('category')}
|
|
||||||
</label>
|
|
||||||
<div class="col-12">
|
|
||||||
<select
|
|
||||||
class="form-control"
|
|
||||||
id="community-category"
|
|
||||||
value={this.state.communityForm.category_id}
|
|
||||||
onInput={linkEvent(this, this.handleCommunityCategoryChange)}
|
|
||||||
>
|
|
||||||
{this.state.categories.map(category => (
|
|
||||||
<option value={category.id}>{category.name}</option>
|
|
||||||
))}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{this.state.enable_nsfw && (
|
|
||||||
<div class="form-group row">
|
<div class="form-group row">
|
||||||
|
<label class="col-12 col-form-label" htmlFor="community-name">
|
||||||
|
{i18n.t('name')}
|
||||||
|
</label>
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<div class="form-check">
|
<input
|
||||||
<input
|
type="text"
|
||||||
class="form-check-input"
|
id="community-name"
|
||||||
id="community-nsfw"
|
class="form-control"
|
||||||
type="checkbox"
|
value={this.state.communityForm.name}
|
||||||
checked={this.state.communityForm.nsfw}
|
onInput={linkEvent(this, this.handleCommunityNameChange)}
|
||||||
onChange={linkEvent(this, this.handleCommunityNsfwChange)}
|
required
|
||||||
/>
|
minLength={3}
|
||||||
<label class="form-check-label" htmlFor="community-nsfw">
|
maxLength={20}
|
||||||
{i18n.t('nsfw')}
|
pattern="[a-z0-9_]+"
|
||||||
</label>
|
title={i18n.t('community_reqs')}
|
||||||
</div>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
|
||||||
<div class="form-group row">
|
<div class="form-group row">
|
||||||
<div class="col-12">
|
<label class="col-12 col-form-label" htmlFor="community-title">
|
||||||
<button type="submit" class="btn btn-secondary mr-2">
|
{i18n.t('title')}
|
||||||
{this.state.loading ? (
|
</label>
|
||||||
<svg class="icon icon-spinner spin">
|
<div class="col-12">
|
||||||
<use xlinkHref="#icon-spinner"></use>
|
<input
|
||||||
</svg>
|
type="text"
|
||||||
) : this.props.community ? (
|
id="community-title"
|
||||||
capitalizeFirstLetter(i18n.t('save'))
|
value={this.state.communityForm.title}
|
||||||
) : (
|
onInput={linkEvent(this, this.handleCommunityTitleChange)}
|
||||||
capitalizeFirstLetter(i18n.t('create'))
|
class="form-control"
|
||||||
)}
|
required
|
||||||
</button>
|
minLength={3}
|
||||||
{this.props.community && (
|
maxLength={100}
|
||||||
<button
|
/>
|
||||||
type="button"
|
</div>
|
||||||
class="btn btn-secondary"
|
|
||||||
onClick={linkEvent(this, this.handleCancel)}
|
|
||||||
>
|
|
||||||
{i18n.t('cancel')}
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="form-group row">
|
||||||
</form>
|
<label class="col-12 col-form-label" htmlFor={this.id}>
|
||||||
|
{i18n.t('sidebar')}
|
||||||
|
</label>
|
||||||
|
<div class="col-12">
|
||||||
|
<textarea
|
||||||
|
id={this.id}
|
||||||
|
value={this.state.communityForm.description}
|
||||||
|
onInput={linkEvent(this, this.handleCommunityDescriptionChange)}
|
||||||
|
class="form-control"
|
||||||
|
rows={3}
|
||||||
|
maxLength={10000}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label class="col-12 col-form-label" htmlFor="community-category">
|
||||||
|
{i18n.t('category')}
|
||||||
|
</label>
|
||||||
|
<div class="col-12">
|
||||||
|
<select
|
||||||
|
class="form-control"
|
||||||
|
id="community-category"
|
||||||
|
value={this.state.communityForm.category_id}
|
||||||
|
onInput={linkEvent(this, this.handleCommunityCategoryChange)}
|
||||||
|
>
|
||||||
|
{this.state.categories.map(category => (
|
||||||
|
<option value={category.id}>{category.name}</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{this.state.enable_nsfw && (
|
||||||
|
<div class="form-group row">
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="form-check">
|
||||||
|
<input
|
||||||
|
class="form-check-input"
|
||||||
|
id="community-nsfw"
|
||||||
|
type="checkbox"
|
||||||
|
checked={this.state.communityForm.nsfw}
|
||||||
|
onChange={linkEvent(this, this.handleCommunityNsfwChange)}
|
||||||
|
/>
|
||||||
|
<label class="form-check-label" htmlFor="community-nsfw">
|
||||||
|
{i18n.t('nsfw')}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<div class="form-group row">
|
||||||
|
<div class="col-12">
|
||||||
|
<button type="submit" class="btn btn-secondary mr-2">
|
||||||
|
{this.state.loading ? (
|
||||||
|
<svg class="icon icon-spinner spin">
|
||||||
|
<use xlinkHref="#icon-spinner"></use>
|
||||||
|
</svg>
|
||||||
|
) : this.props.community ? (
|
||||||
|
capitalizeFirstLetter(i18n.t('save'))
|
||||||
|
) : (
|
||||||
|
capitalizeFirstLetter(i18n.t('create'))
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
|
{this.props.community && (
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="btn btn-secondary"
|
||||||
|
onClick={linkEvent(this, this.handleCancel)}
|
||||||
|
>
|
||||||
|
{i18n.t('cancel')}
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
10
ui/src/components/post-form.tsx
vendored
10
ui/src/components/post-form.tsx
vendored
|
@ -1,4 +1,5 @@
|
||||||
import { Component, linkEvent } from 'inferno';
|
import { Component, linkEvent } from 'inferno';
|
||||||
|
import { Prompt } from 'inferno-router';
|
||||||
import { PostListings } from './post-listings';
|
import { PostListings } from './post-listings';
|
||||||
import { Subscription } from 'rxjs';
|
import { Subscription } from 'rxjs';
|
||||||
import { retryWhen, delay, take } from 'rxjs/operators';
|
import { retryWhen, delay, take } from 'rxjs/operators';
|
||||||
|
@ -153,6 +154,15 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
<Prompt
|
||||||
|
when={
|
||||||
|
!this.state.loading &&
|
||||||
|
(this.state.postForm.name ||
|
||||||
|
this.state.postForm.url ||
|
||||||
|
this.state.postForm.body)
|
||||||
|
}
|
||||||
|
message={i18n.t('block_leaving')}
|
||||||
|
/>
|
||||||
<form onSubmit={linkEvent(this, this.handlePostSubmit)}>
|
<form onSubmit={linkEvent(this, this.handlePostSubmit)}>
|
||||||
<div class="form-group row">
|
<div class="form-group row">
|
||||||
<label class="col-sm-2 col-form-label" htmlFor="post-url">
|
<label class="col-sm-2 col-form-label" htmlFor="post-url">
|
||||||
|
|
5
ui/src/components/private-message-form.tsx
vendored
5
ui/src/components/private-message-form.tsx
vendored
|
@ -1,4 +1,5 @@
|
||||||
import { Component, linkEvent } from 'inferno';
|
import { Component, linkEvent } from 'inferno';
|
||||||
|
import { Prompt } from 'inferno-router';
|
||||||
import { Link } from 'inferno-router';
|
import { Link } from 'inferno-router';
|
||||||
import { Subscription } from 'rxjs';
|
import { Subscription } from 'rxjs';
|
||||||
import { retryWhen, delay, take } from 'rxjs/operators';
|
import { retryWhen, delay, take } from 'rxjs/operators';
|
||||||
|
@ -116,6 +117,10 @@ export class PrivateMessageForm extends Component<
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
<Prompt
|
||||||
|
when={!this.state.loading && this.state.privateMessageForm.content}
|
||||||
|
message={i18n.t('block_leaving')}
|
||||||
|
/>
|
||||||
<form onSubmit={linkEvent(this, this.handlePrivateMessageSubmit)}>
|
<form onSubmit={linkEvent(this, this.handlePrivateMessageSubmit)}>
|
||||||
{!this.props.privateMessage && (
|
{!this.props.privateMessage && (
|
||||||
<div class="form-group row">
|
<div class="form-group row">
|
||||||
|
|
230
ui/src/components/site-form.tsx
vendored
230
ui/src/components/site-form.tsx
vendored
|
@ -1,4 +1,5 @@
|
||||||
import { Component, linkEvent } from 'inferno';
|
import { Component, linkEvent } from 'inferno';
|
||||||
|
import { Prompt } from 'inferno-router';
|
||||||
import { Site, SiteForm as SiteFormI } from '../interfaces';
|
import { Site, SiteForm as SiteFormI } from '../interfaces';
|
||||||
import { WebSocketService } from '../services';
|
import { WebSocketService } from '../services';
|
||||||
import { capitalizeFirstLetter, randomStr, setupTribute } from '../utils';
|
import { capitalizeFirstLetter, randomStr, setupTribute } from '../utils';
|
||||||
|
@ -59,123 +60,138 @@ export class SiteForm extends Component<SiteFormProps, SiteFormState> {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<form onSubmit={linkEvent(this, this.handleCreateSiteSubmit)}>
|
<>
|
||||||
<h5>{`${
|
<Prompt
|
||||||
this.props.site
|
when={
|
||||||
? capitalizeFirstLetter(i18n.t('edit'))
|
!this.state.loading &&
|
||||||
: capitalizeFirstLetter(i18n.t('name'))
|
(this.state.siteForm.name || this.state.siteForm.description)
|
||||||
} ${i18n.t('your_site')}`}</h5>
|
}
|
||||||
<div class="form-group row">
|
message={i18n.t('block_leaving')}
|
||||||
<label class="col-12 col-form-label" htmlFor="create-site-name">
|
/>
|
||||||
{i18n.t('name')}
|
<form onSubmit={linkEvent(this, this.handleCreateSiteSubmit)}>
|
||||||
</label>
|
<h5>{`${
|
||||||
<div class="col-12">
|
this.props.site
|
||||||
<input
|
? capitalizeFirstLetter(i18n.t('edit'))
|
||||||
type="text"
|
: capitalizeFirstLetter(i18n.t('name'))
|
||||||
id="create-site-name"
|
} ${i18n.t('your_site')}`}</h5>
|
||||||
class="form-control"
|
<div class="form-group row">
|
||||||
value={this.state.siteForm.name}
|
<label class="col-12 col-form-label" htmlFor="create-site-name">
|
||||||
onInput={linkEvent(this, this.handleSiteNameChange)}
|
{i18n.t('name')}
|
||||||
required
|
</label>
|
||||||
minLength={3}
|
<div class="col-12">
|
||||||
maxLength={20}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group row">
|
|
||||||
<label class="col-12 col-form-label" htmlFor={this.id}>
|
|
||||||
{i18n.t('sidebar')}
|
|
||||||
</label>
|
|
||||||
<div class="col-12">
|
|
||||||
<textarea
|
|
||||||
id={this.id}
|
|
||||||
value={this.state.siteForm.description}
|
|
||||||
onInput={linkEvent(this, this.handleSiteDescriptionChange)}
|
|
||||||
class="form-control"
|
|
||||||
rows={3}
|
|
||||||
maxLength={10000}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group row">
|
|
||||||
<div class="col-12">
|
|
||||||
<div class="form-check">
|
|
||||||
<input
|
<input
|
||||||
class="form-check-input"
|
type="text"
|
||||||
id="create-site-downvotes"
|
id="create-site-name"
|
||||||
type="checkbox"
|
class="form-control"
|
||||||
checked={this.state.siteForm.enable_downvotes}
|
value={this.state.siteForm.name}
|
||||||
onChange={linkEvent(this, this.handleSiteEnableDownvotesChange)}
|
onInput={linkEvent(this, this.handleSiteNameChange)}
|
||||||
|
required
|
||||||
|
minLength={3}
|
||||||
|
maxLength={20}
|
||||||
/>
|
/>
|
||||||
<label class="form-check-label" htmlFor="create-site-downvotes">
|
|
||||||
{i18n.t('enable_downvotes')}
|
|
||||||
</label>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="form-group row">
|
||||||
<div class="form-group row">
|
<label class="col-12 col-form-label" htmlFor={this.id}>
|
||||||
<div class="col-12">
|
{i18n.t('sidebar')}
|
||||||
<div class="form-check">
|
</label>
|
||||||
<input
|
<div class="col-12">
|
||||||
class="form-check-input"
|
<textarea
|
||||||
id="create-site-enable-nsfw"
|
id={this.id}
|
||||||
type="checkbox"
|
value={this.state.siteForm.description}
|
||||||
checked={this.state.siteForm.enable_nsfw}
|
onInput={linkEvent(this, this.handleSiteDescriptionChange)}
|
||||||
onChange={linkEvent(this, this.handleSiteEnableNsfwChange)}
|
class="form-control"
|
||||||
|
rows={3}
|
||||||
|
maxLength={10000}
|
||||||
/>
|
/>
|
||||||
<label class="form-check-label" htmlFor="create-site-enable-nsfw">
|
|
||||||
{i18n.t('enable_nsfw')}
|
|
||||||
</label>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="form-group row">
|
||||||
<div class="form-group row">
|
<div class="col-12">
|
||||||
<div class="col-12">
|
<div class="form-check">
|
||||||
<div class="form-check">
|
<input
|
||||||
<input
|
class="form-check-input"
|
||||||
class="form-check-input"
|
id="create-site-downvotes"
|
||||||
id="create-site-open-registration"
|
type="checkbox"
|
||||||
type="checkbox"
|
checked={this.state.siteForm.enable_downvotes}
|
||||||
checked={this.state.siteForm.open_registration}
|
onChange={linkEvent(
|
||||||
onChange={linkEvent(
|
this,
|
||||||
this,
|
this.handleSiteEnableDownvotesChange
|
||||||
this.handleSiteOpenRegistrationChange
|
)}
|
||||||
|
/>
|
||||||
|
<label class="form-check-label" htmlFor="create-site-downvotes">
|
||||||
|
{i18n.t('enable_downvotes')}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="form-check">
|
||||||
|
<input
|
||||||
|
class="form-check-input"
|
||||||
|
id="create-site-enable-nsfw"
|
||||||
|
type="checkbox"
|
||||||
|
checked={this.state.siteForm.enable_nsfw}
|
||||||
|
onChange={linkEvent(this, this.handleSiteEnableNsfwChange)}
|
||||||
|
/>
|
||||||
|
<label
|
||||||
|
class="form-check-label"
|
||||||
|
htmlFor="create-site-enable-nsfw"
|
||||||
|
>
|
||||||
|
{i18n.t('enable_nsfw')}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="form-check">
|
||||||
|
<input
|
||||||
|
class="form-check-input"
|
||||||
|
id="create-site-open-registration"
|
||||||
|
type="checkbox"
|
||||||
|
checked={this.state.siteForm.open_registration}
|
||||||
|
onChange={linkEvent(
|
||||||
|
this,
|
||||||
|
this.handleSiteOpenRegistrationChange
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<label
|
||||||
|
class="form-check-label"
|
||||||
|
htmlFor="create-site-open-registration"
|
||||||
|
>
|
||||||
|
{i18n.t('open_registration')}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<div class="col-12">
|
||||||
|
<button type="submit" class="btn btn-secondary mr-2">
|
||||||
|
{this.state.loading ? (
|
||||||
|
<svg class="icon icon-spinner spin">
|
||||||
|
<use xlinkHref="#icon-spinner"></use>
|
||||||
|
</svg>
|
||||||
|
) : this.props.site ? (
|
||||||
|
capitalizeFirstLetter(i18n.t('save'))
|
||||||
|
) : (
|
||||||
|
capitalizeFirstLetter(i18n.t('create'))
|
||||||
)}
|
)}
|
||||||
/>
|
</button>
|
||||||
<label
|
{this.props.site && (
|
||||||
class="form-check-label"
|
<button
|
||||||
htmlFor="create-site-open-registration"
|
type="button"
|
||||||
>
|
class="btn btn-secondary"
|
||||||
{i18n.t('open_registration')}
|
onClick={linkEvent(this, this.handleCancel)}
|
||||||
</label>
|
>
|
||||||
|
{i18n.t('cancel')}
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</form>
|
||||||
<div class="form-group row">
|
</>
|
||||||
<div class="col-12">
|
|
||||||
<button type="submit" class="btn btn-secondary mr-2">
|
|
||||||
{this.state.loading ? (
|
|
||||||
<svg class="icon icon-spinner spin">
|
|
||||||
<use xlinkHref="#icon-spinner"></use>
|
|
||||||
</svg>
|
|
||||||
) : this.props.site ? (
|
|
||||||
capitalizeFirstLetter(i18n.t('save'))
|
|
||||||
) : (
|
|
||||||
capitalizeFirstLetter(i18n.t('create'))
|
|
||||||
)}
|
|
||||||
</button>
|
|
||||||
{this.props.site && (
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
class="btn btn-secondary"
|
|
||||||
onClick={linkEvent(this, this.handleCancel)}
|
|
||||||
>
|
|
||||||
{i18n.t('cancel')}
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
3
ui/translations/en.json
vendored
3
ui/translations/en.json
vendored
|
@ -245,5 +245,6 @@
|
||||||
"no_private_message_edit_allowed": "Not allowed to edit private message.",
|
"no_private_message_edit_allowed": "Not allowed to edit private message.",
|
||||||
"couldnt_update_private_message": "Couldn't update private message.",
|
"couldnt_update_private_message": "Couldn't update private message.",
|
||||||
"time": "Time",
|
"time": "Time",
|
||||||
"action": "Action"
|
"action": "Action",
|
||||||
|
"block_leaving": "Are you sure you want to leave?"
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue