mirror of
https://github.com/shlinkio/shlink-web-client.git
synced 2024-12-23 01:20:24 +03:00
Passed API error while creating URLs to display proper error messages
This commit is contained in:
parent
18d417e78c
commit
54b1ab12cd
3 changed files with 32 additions and 16 deletions
|
@ -9,6 +9,7 @@ import { ShortUrlCreation } from '../reducers/shortUrlCreation';
|
||||||
import { StateFlagTimeout } from '../../utils/helpers/hooks';
|
import { StateFlagTimeout } from '../../utils/helpers/hooks';
|
||||||
import { Result } from '../../utils/Result';
|
import { Result } from '../../utils/Result';
|
||||||
import './CreateShortUrlResult.scss';
|
import './CreateShortUrlResult.scss';
|
||||||
|
import { isInvalidArgumentError } from '../../utils/services/types';
|
||||||
|
|
||||||
export interface CreateShortUrlResultProps extends ShortUrlCreation {
|
export interface CreateShortUrlResultProps extends ShortUrlCreation {
|
||||||
resetCreateShortUrl: () => void;
|
resetCreateShortUrl: () => void;
|
||||||
|
@ -16,7 +17,7 @@ export interface CreateShortUrlResultProps extends ShortUrlCreation {
|
||||||
}
|
}
|
||||||
|
|
||||||
const CreateShortUrlResult = (useStateFlagTimeout: StateFlagTimeout) => (
|
const CreateShortUrlResult = (useStateFlagTimeout: StateFlagTimeout) => (
|
||||||
{ error, result, resetCreateShortUrl, canBeClosed = false }: CreateShortUrlResultProps,
|
{ error, errorData, result, resetCreateShortUrl, canBeClosed = false }: CreateShortUrlResultProps,
|
||||||
) => {
|
) => {
|
||||||
const [ showCopyTooltip, setShowCopyTooltip ] = useStateFlagTimeout();
|
const [ showCopyTooltip, setShowCopyTooltip ] = useStateFlagTimeout();
|
||||||
|
|
||||||
|
@ -28,7 +29,8 @@ const CreateShortUrlResult = (useStateFlagTimeout: StateFlagTimeout) => (
|
||||||
return (
|
return (
|
||||||
<Result type="error" className="mt-3">
|
<Result type="error" className="mt-3">
|
||||||
{canBeClosed && <FontAwesomeIcon icon={closeIcon} className="float-right pointer" onClick={resetCreateShortUrl} />}
|
{canBeClosed && <FontAwesomeIcon icon={closeIcon} className="float-right pointer" onClick={resetCreateShortUrl} />}
|
||||||
An error occurred while creating the URL :(
|
{errorData?.detail ?? 'An error occurred while creating the URL :('}
|
||||||
|
{isInvalidArgumentError(errorData) && <p>Invalid elements: [{errorData.invalidElements.join(', ')}]</p>}
|
||||||
</Result>
|
</Result>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ import { GetState } from '../../container/types';
|
||||||
import { ShortUrl, ShortUrlData } from '../data';
|
import { ShortUrl, ShortUrlData } from '../data';
|
||||||
import { buildReducer, buildActionCreator } from '../../utils/helpers/redux';
|
import { buildReducer, buildActionCreator } from '../../utils/helpers/redux';
|
||||||
import { ShlinkApiClientBuilder } from '../../utils/services/ShlinkApiClientBuilder';
|
import { ShlinkApiClientBuilder } from '../../utils/services/ShlinkApiClientBuilder';
|
||||||
|
import { ProblemDetailsError } from '../../utils/services/types';
|
||||||
|
|
||||||
/* eslint-disable padding-line-between-statements */
|
/* eslint-disable padding-line-between-statements */
|
||||||
export const CREATE_SHORT_URL_START = 'shlink/createShortUrl/CREATE_SHORT_URL_START';
|
export const CREATE_SHORT_URL_START = 'shlink/createShortUrl/CREATE_SHORT_URL_START';
|
||||||
|
@ -15,21 +16,26 @@ export interface ShortUrlCreation {
|
||||||
result: ShortUrl | null;
|
result: ShortUrl | null;
|
||||||
saving: boolean;
|
saving: boolean;
|
||||||
error: boolean;
|
error: boolean;
|
||||||
|
errorData?: ProblemDetailsError;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CreateShortUrlAction extends Action<string> {
|
export interface CreateShortUrlAction extends Action<string> {
|
||||||
result: ShortUrl;
|
result: ShortUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface CreateShortUrlFailedAction extends Action<string> {
|
||||||
|
errorData?: ProblemDetailsError;
|
||||||
|
}
|
||||||
|
|
||||||
const initialState: ShortUrlCreation = {
|
const initialState: ShortUrlCreation = {
|
||||||
result: null,
|
result: null,
|
||||||
saving: false,
|
saving: false,
|
||||||
error: false,
|
error: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default buildReducer<ShortUrlCreation, CreateShortUrlAction>({
|
export default buildReducer<ShortUrlCreation, CreateShortUrlAction & CreateShortUrlFailedAction>({
|
||||||
[CREATE_SHORT_URL_START]: (state) => ({ ...state, saving: true, error: false }),
|
[CREATE_SHORT_URL_START]: (state) => ({ ...state, saving: true, error: false }),
|
||||||
[CREATE_SHORT_URL_ERROR]: (state) => ({ ...state, saving: false, error: true }),
|
[CREATE_SHORT_URL_ERROR]: (state, { errorData }) => ({ ...state, saving: false, error: true, errorData }),
|
||||||
[CREATE_SHORT_URL]: (_, { result }) => ({ result, saving: false, error: false }),
|
[CREATE_SHORT_URL]: (_, { result }) => ({ result, saving: false, error: false }),
|
||||||
[RESET_CREATE_SHORT_URL]: () => initialState,
|
[RESET_CREATE_SHORT_URL]: () => initialState,
|
||||||
}, initialState);
|
}, initialState);
|
||||||
|
@ -46,7 +52,7 @@ export const createShortUrl = (buildShlinkApiClient: ShlinkApiClientBuilder) =>
|
||||||
|
|
||||||
dispatch<CreateShortUrlAction>({ type: CREATE_SHORT_URL, result });
|
dispatch<CreateShortUrlAction>({ type: CREATE_SHORT_URL, result });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
dispatch({ type: CREATE_SHORT_URL_ERROR });
|
dispatch<CreateShortUrlFailedAction>({ type: CREATE_SHORT_URL_ERROR, errorData: e.response?.data });
|
||||||
|
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,12 +25,12 @@ interface ShlinkTagsStats {
|
||||||
|
|
||||||
export interface ShlinkTags {
|
export interface ShlinkTags {
|
||||||
tags: string[];
|
tags: string[];
|
||||||
stats?: ShlinkTagsStats[]; // Is only optional in old Shlink versions
|
stats?: ShlinkTagsStats[]; // Is only optional in Shlink older than v2.2
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ShlinkTagsResponse {
|
export interface ShlinkTagsResponse {
|
||||||
data: string[];
|
data: string[];
|
||||||
stats?: ShlinkTagsStats[]; // Is only optional in old Shlink versions
|
stats?: ShlinkTagsStats[]; // Is only optional in Shlink older than v2.2
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ShlinkPaginator {
|
export interface ShlinkPaginator {
|
||||||
|
@ -41,7 +41,7 @@ export interface ShlinkPaginator {
|
||||||
|
|
||||||
export interface ShlinkVisits {
|
export interface ShlinkVisits {
|
||||||
data: Visit[];
|
data: Visit[];
|
||||||
pagination?: ShlinkPaginator; // Is only optional in old Shlink versions
|
pagination: ShlinkPaginator;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ShlinkVisitsOverview {
|
export interface ShlinkVisitsOverview {
|
||||||
|
@ -60,14 +60,6 @@ export interface ShlinkShortUrlMeta extends ShortUrlMeta {
|
||||||
longUrl?: string;
|
longUrl?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ProblemDetailsError {
|
|
||||||
type: string;
|
|
||||||
detail: string;
|
|
||||||
title: string;
|
|
||||||
status: number;
|
|
||||||
[extraProps: string]: any;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ShlinkDomain {
|
export interface ShlinkDomain {
|
||||||
domain: string;
|
domain: string;
|
||||||
isDefault: boolean;
|
isDefault: boolean;
|
||||||
|
@ -76,3 +68,19 @@ export interface ShlinkDomain {
|
||||||
export interface ShlinkDomainsResponse {
|
export interface ShlinkDomainsResponse {
|
||||||
data: ShlinkDomain[];
|
data: ShlinkDomain[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ProblemDetailsError {
|
||||||
|
type: string;
|
||||||
|
detail: string;
|
||||||
|
title: string;
|
||||||
|
status: number;
|
||||||
|
[extraProps: string]: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface InvalidArgumentError extends ProblemDetailsError {
|
||||||
|
type: 'INVALID_ARGUMENT';
|
||||||
|
invalidElements: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export const isInvalidArgumentError = (error?: ProblemDetailsError): error is InvalidArgumentError =>
|
||||||
|
error?.type === 'INVALID_ARGUMENT';
|
||||||
|
|
Loading…
Reference in a new issue