1
0
mirror of https://github.com/ascribe/onion.git synced 2024-12-22 09:23:13 +01:00

Use UrlResolver to resolve api urls based on white labelling rather than updating ApiUrl's export

Keeping an export constant is more predictable and less surprising for
most people.
This commit is contained in:
Brett Sun 2016-06-14 13:05:57 +02:00
parent 17762ed7b2
commit 7014514654
38 changed files with 151 additions and 146 deletions

View File

@ -14,8 +14,8 @@ import AppConstants from './constants/application_constants';
import { getDefaultSubdomainSettings, getSubdomainSettings } from './utils/constants';
import { initLogging } from './utils/error';
import requests from './utils/requests';
import { getCurrentSubdomain } from './utils/url';
import UrlResolver from './utils/url_resolver';
// FIXME: rename these event actions
@ -74,17 +74,8 @@ const AppGateway = {
AppResolver
.resolve(settings)
.then(({ apiUrls, redirectRoute, routes }) => {
// Initialize api urls and defaults for outgoing requests
requests.defaults({
urlMap: apiUrls,
http: {
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
credentials: 'include'
}
});
// Set url mapping for outgoing api requests
UrlResolver.setUrlMapping(apiUrls);
ReactDOM.render((
<Router history={history}>

View File

@ -11,7 +11,7 @@ import withContext from '../context/with_context';
import { currentUserShape } from '../prop_types';
import { getLangText } from '../../utils/lang';
import ApiUrls from '../../constants/api_urls';
import { resolveUrl } from '../../utils/url_resolver';
const UnConsignRequestButton = React.createClass({
@ -36,7 +36,7 @@ const UnConsignRequestButton = React.createClass({
handleSuccess={handleSuccess}
title={getLangText('Request to Un-Consign')}>
<UnConsignRequestForm
url={ApiUrls.ownership_unconsigns_request}
url={resolveUrl('ownership_unconsigns_request')}
id={{'bitcoin_id': edition.bitcoin_id}}
message={`${getLangText('Hi')},

View File

@ -24,9 +24,9 @@ import Property from '../ascribe_forms/property';
import AclProxy from '../acl_proxy';
import withContext from '../context/with_context';
import ApiUrls from '../../constants/api_urls';
import AscribeSpinner from '../ascribe_spinner';
import { resolveUrl } from '../../utils/url_resolver';
import { getLangText } from '../../utils/lang';
@ -120,7 +120,7 @@ const Edition = React.createClass({
placeholder={getLangText('Enter your comments ...')}
editable={true}
successMessage={getLangText('Private note saved')}
url={ApiUrls.note_private_edition} />
url={resolveUrl('note_private_edition')} />
<Note
id={() => {return {'bitcoin_id': edition.bitcoin_id}; }}
label={getLangText('Personal note (public)')}
@ -129,7 +129,7 @@ const Edition = React.createClass({
editable={!!edition.acl.acl_edit}
show={!!(edition.public_note || edition.acl.acl_edit)}
successMessage={getLangText('Public edition note saved')}
url={ApiUrls.note_public_edition} />
url={resolveUrl('note_public_edition')} />
</CollapsibleParagraph>
<CollapsibleParagraph
title={getLangText('Further Details')}

View File

@ -26,9 +26,8 @@ import AclProxy from '../acl_proxy';
import withContext from '../context/with_context';
import { routerShape } from '../prop_types';
import ApiUrls from '../../constants/api_urls';
import { getLangText } from '../../utils/lang';
import { resolveUrl } from '../../utils/url_resolver';
/*
A component that handles all the actions inside of the edition detail
@ -121,7 +120,7 @@ const EditionActionPanel = React.createClass({
aclObject={edition.acl}
aclName="acl_withdraw_transfer">
<Form
url={ApiUrls.ownership_transfers_withdraw}
url={resolveUrl('ownership_transfers_withdraw')}
handleSuccess={this.handleSuccess}
className='inline'
isInline={true}>
@ -142,7 +141,7 @@ const EditionActionPanel = React.createClass({
aclObject={edition.acl}
aclName="acl_withdraw_consign">
<Form
url={ApiUrls.ownership_consigns_withdraw}
url={resolveUrl('ownership_consigns_withdraw')}
handleSuccess={this.handleSuccess}
className='inline'
isInline={true}>

View File

@ -6,12 +6,12 @@ import Property from './../ascribe_forms/property';
import ReactS3FineUploader from './../ascribe_uploader/react_s3_fine_uploader';
import ApiUrls from '../../constants/api_urls';
import AppConstants from '../../constants/application_constants';
import { validationTypes } from '../../constants/uploader_constants';
import { getCookie } from '../../utils/fetch_api';
import { getLangText } from '../../utils/lang';
import { resolveUrl } from '../../utils/url_resolver';
const { func, bool, number, object, string, arrayOf } = React.PropTypes;
@ -75,7 +75,7 @@ let FurtherDetailsFileuploader = React.createClass({
areAssetsDownloadable
areAssetsEditable={editable}
createBlobRoutine={{
url: ApiUrls.blob_otherdatas,
url: resolveUrl('blob_otherdatas'),
pieceId: pieceId
}}
deleteFile={{

View File

@ -39,11 +39,10 @@ import AscribeSpinner from '../ascribe_spinner';
import withContext from '../context/with_context';
import { routerShape } from '../prop_types';
import ApiUrls from '../../constants/api_urls';
import { setDocumentTitle } from '../../utils/dom';
import { safeMerge } from '../../utils/general';
import { getLangText } from '../../utils/lang';
import { resolveUrl } from '../../utils/url_resolver';
/**
* This is the component that implements resource/data specific functionality
@ -302,7 +301,7 @@ const PieceContainer = React.createClass({
placeholder={getLangText('Enter your comments ...')}
editable={true}
successMessage={getLangText('Private note saved')}
url={ApiUrls.note_private_piece} />
url={resolveUrl('note_private_piece')} />
<Note
id={this.getId}
label={getLangText('Personal note (public)')}
@ -311,7 +310,7 @@ const PieceContainer = React.createClass({
editable={!!piece.acl.acl_edit}
show={!!(piece.public_note || piece.acl.acl_edit)}
successMessage={getLangText('Public note saved')}
url={ApiUrls.note_public_piece} />
url={resolveUrl('note_public_piece')} />
</CollapsibleParagraph>
<CollapsibleParagraph
title={getLangText('Further Details')}

View File

@ -16,9 +16,9 @@ import withContext from '../context/with_context';
import { currentUserShape } from '../prop_types';
import AppConstants from '../../constants/application_constants';
import ApiUrls from '../../constants/api_urls';
import { getAclFormMessage, getAclFormDataId } from '../../utils/form';
import { resolveUrl } from '../../utils/url_resolver';
let AclFormFactory = React.createClass({
propTypes: {
@ -86,7 +86,7 @@ let AclFormFactory = React.createClass({
message={formMessage}
labels={labels}
id={this.getFormDataId()}
url={ApiUrls.ownership_consigns}
url={resolveUrl('ownership_consigns')}
handleSuccess={showNotification ? this.showSuccessNotification : handleSuccess} />
);
} else if (action === 'acl_unconsign') {
@ -94,7 +94,7 @@ let AclFormFactory = React.createClass({
<UnConsignForm
message={formMessage}
id={this.getFormDataId()}
url={ApiUrls.ownership_unconsigns}
url={resolveUrl('ownership_unconsigns')}
handleSuccess={showNotification ? this.showSuccessNotification : handleSuccess} />
);
} else if (action === 'acl_transfer') {
@ -102,7 +102,7 @@ let AclFormFactory = React.createClass({
<TransferForm
message={formMessage}
id={this.getFormDataId()}
url={ApiUrls.ownership_transfers}
url={resolveUrl('ownership_transfers')}
handleSuccess={showNotification ? this.showSuccessNotification : handleSuccess} />
);
} else if (action === 'acl_loan') {
@ -111,8 +111,8 @@ let AclFormFactory = React.createClass({
email={email}
message={formMessage}
id={this.getFormDataId()}
url={this.isPiece() ? ApiUrls.ownership_loans_pieces
: ApiUrls.ownership_loans_editions}
url={resolveUrl(this.isPiece() ? 'ownership_loans_pieces'
: 'ownership_loans_editions')}
handleSuccess={showNotification ? this.showSuccessNotification : handleSuccess} />
);
} else if (action === 'acl_loan_request') {
@ -120,7 +120,7 @@ let AclFormFactory = React.createClass({
<LoanRequestAnswerForm
message={formMessage}
id={this.getFormDataId()}
url={ApiUrls.ownership_loans_pieces_request_confirm}
url={resolveUrl('ownership_loans_pieces_request_confirm')}
handleSuccess={showNotification ? this.showSuccessNotification : handleSuccess} />
);
} else if (action === 'acl_share') {
@ -128,8 +128,8 @@ let AclFormFactory = React.createClass({
<ShareForm
message={formMessage}
id={this.getFormDataId()}
url={this.isPiece() ? ApiUrls.ownership_shares_pieces
: ApiUrls.ownership_shares_editions}
url={resolveUrl(this.isPiece() ? 'ownership_shares_pieces'
: 'ownership_shares_editions')}
handleSuccess={showNotification ? this.showSuccessNotification : handleSuccess} />
);
} else {

View File

@ -9,9 +9,9 @@ import GlobalNotificationModel from '../../models/global_notification_model';
import GlobalNotificationActions from '../../actions/global_notification_actions';
import AscribeSpinner from '../ascribe_spinner';
import ApiUrls from '../../constants/api_urls';
import { getLangText } from '../../utils/lang';
import { resolveUrl } from '../../utils/url_resolver';
let CreateEditionsForm = React.createClass({
propTypes: {
@ -40,7 +40,7 @@ let CreateEditionsForm = React.createClass({
return (
<Form
ref='form'
url={ApiUrls.editions}
url={resolveUrl('editions')}
getFormData={this.getFormData}
handleSuccess={this.handleSuccess}
buttons={

View File

@ -11,10 +11,10 @@ import Property from './property';
import withContext from '../context/with_context';
import { currentUserShape } from '../prop_types';
import ApiUrls from '../../constants/api_urls';
import AppConstants from '../../constants/application_constants';
import { getLangText } from '../../utils/lang';
import { resolveUrl } from '../../utils/url_resolver';
const { bool } = React.PropTypes;
@ -50,7 +50,7 @@ const CopyrightAssociationForm = React.createClass({
return (
<Form
ref='form'
url={ApiUrls.users_profile}
url={resolveUrl('users_profile')}
getFormData={this.getProfileFormData}
handleSuccess={this.handleSubmitSuccess}>
<Property

View File

@ -12,12 +12,12 @@ import InputFineUploader from './input_fineuploader';
import Form from '../ascribe_forms/form';
import Property from '../ascribe_forms/property';
import ApiUrls from '../../constants/api_urls';
import AppConstants from '../../constants/application_constants';
import { validationTypes } from '../../constants/uploader_constants';
import { getLangText } from '../../utils/lang';
import { formSubmissionValidation } from '../ascribe_uploader/react_s3_fine_uploader_utils';
import { resolveUrl } from '../../utils/url_resolver';
let CreateContractForm = React.createClass({
@ -64,7 +64,7 @@ let CreateContractForm = React.createClass({
return (
<Form
ref='form'
url={ApiUrls.ownership_contract_list}
url={resolveUrl('ownership_contract_list')}
handleSuccess={this.handleCreateSuccess}>
<Property
name="blob"
@ -76,7 +76,7 @@ let CreateContractForm = React.createClass({
fileClass: 'contract'
}}
createBlobRoutine={{
url: ApiUrls.blob_contracts
url: resolveUrl('blob_contracts')
}}
validation={{
itemLimit: validationTypes.additionalData.itemLimit,

View File

@ -8,9 +8,8 @@ import AclInformation from '../ascribe_buttons/acl_information';
import AscribeSpinner from '../ascribe_spinner';
import ApiUrls from '../../constants/api_urls';
import { getLangText } from '../../utils/lang';
import { resolveUrl } from '../../utils/url_resolver';
let EditionDeleteForm = React.createClass({
@ -40,7 +39,7 @@ let EditionDeleteForm = React.createClass({
return (
<Form
ref='form'
url={ApiUrls.edition_delete}
url={resolveUrl('edition_delete')}
getFormData={this.getFormData}
method="delete"
handleSuccess={this.props.handleSuccess}

View File

@ -8,9 +8,8 @@ import AclInformation from '../ascribe_buttons/acl_information';
import AscribeSpinner from '../ascribe_spinner';
import ApiUrls from '../../constants/api_urls';
import { getLangText } from '../../utils/lang';
import { resolveUrl } from '../../utils/url_resolver';
let PieceDeleteForm = React.createClass({
@ -31,7 +30,7 @@ let PieceDeleteForm = React.createClass({
return (
<Form
ref='form'
url={ApiUrls.piece}
url={resolveUrl('piece')}
getFormData={this.getFormData}
method="delete"
handleSuccess={this.props.handleSuccess}

View File

@ -14,9 +14,8 @@ import AscribeSpinner from '../ascribe_spinner';
import withContext from '../context/with_context';
import { locationShape } from '../prop_types';
import ApiUrls from '../../constants/api_urls';
import { getLangText } from '../../utils/lang';
import { resolveUrl } from '../../utils/url_resolver';
let LoginForm = React.createClass({
@ -55,7 +54,7 @@ let LoginForm = React.createClass({
<Form
className="ascribe-form-bordered"
ref="loginForm"
url={ApiUrls.users_login}
url={resolveUrl('users_login')}
handleSuccess={this.handleSuccess}
autoComplete="on"
buttons={

View File

@ -6,10 +6,9 @@ import Form from './form';
import Property from './property';
import InputTextAreaToggable from './input_textarea_toggable';
import ApiUrls from '../../constants/api_urls';
import requests from '../../utils/requests';
import { getLangText } from '../../utils/lang.js';
import { resolveUrl } from '../../utils/url_resolver';
let PieceExtraDataForm = React.createClass({
@ -47,7 +46,7 @@ let PieceExtraDataForm = React.createClass({
disabled={!editable}
getFormData={this.getFormData}
handleSuccess={handleSuccess}
url={requests.prepareUrl(ApiUrls.piece_extradata, { piece_id: pieceId })}>
url={requests.prepareUrl(resolveUrl('piece_extradata'), { piece_id: pieceId })}>
<Property
name={name}
label={title}>

View File

@ -14,12 +14,12 @@ import AscribeSpinner from '../ascribe_spinner';
import withContext from '../context/with_context';
import { currentUserShape, locationShape } from '../prop_types';
import ApiUrls from '../../constants/api_urls';
import AppConstants from '../../constants/application_constants';
import { validationParts, validationTypes } from '../../constants/uploader_constants';
import { FileStatus, formSubmissionValidation } from '../ascribe_uploader/react_s3_fine_uploader_utils';
import { getLangText } from '../../utils/lang';
import { resolveUrl } from '../../utils/url_resolver';
let RegisterPieceForm = React.createClass({
@ -138,7 +138,7 @@ let RegisterPieceForm = React.createClass({
disabled={disabled}
className="ascribe-form-bordered"
ref='form'
url={ApiUrls.pieces_list}
url={resolveUrl('pieces_list')}
handleSuccess={handleSuccess}
buttons={
<FormSubmitButton
@ -168,7 +168,7 @@ let RegisterPieceForm = React.createClass({
fileClass: 'digitalwork'
}}
createBlobRoutine={{
url: ApiUrls.blob_digitalworks
url: resolveUrl('blob_digitalworks')
}}
validation={validationTypes.registerWork}
setIsUploadReady={this.setIsUploadReady('digitalWorkKeyReady')}
@ -187,7 +187,7 @@ let RegisterPieceForm = React.createClass({
ref={ref => this.refs.thumbnailFineUploader = ref}
fileInputElement={UploadButton({ className: 'btn btn-secondary btn-sm' })}
createBlobRoutine={{
url: ApiUrls.blob_thumbnails
url: resolveUrl('blob_thumbnails')
}}
handleChangedFile={this.handleChangedThumbnail}
onValidationFailed={this.handleThumbnailValidationFailed}

View File

@ -6,9 +6,8 @@ import Form from './form';
import AscribeSpinner from '../ascribe_spinner';
import ApiUrls from '../../constants/api_urls';
import { getLangText } from '../../utils/lang';
import { resolveUrl } from '../../utils/url_resolver';
let EditionRemoveFromCollectionForm = React.createClass({
propTypes: {
@ -36,7 +35,7 @@ let EditionRemoveFromCollectionForm = React.createClass({
return (
<Form
ref='form'
url={ApiUrls.edition_remove_from_collection}
url={resolveUrl('edition_remove_from_collection')}
getFormData={this.getFormData}
method="delete"
handleSuccess={this.props.handleSuccess}

View File

@ -6,9 +6,8 @@ import Form from './form';
import AscribeSpinner from '../ascribe_spinner';
import ApiUrls from '../../constants/api_urls';
import { getLangText } from '../../utils/lang';
import { resolveUrl } from '../../utils/url_resolver';
let PieceRemoveFromCollectionForm = React.createClass({
@ -29,7 +28,7 @@ let PieceRemoveFromCollectionForm = React.createClass({
return (
<Form
ref='form'
url={ApiUrls.piece_remove_from_collection}
url={resolveUrl('piece_remove_from_collection')}
getFormData={this.getFormData}
method="delete"
handleSuccess={this.props.handleSuccess}

View File

@ -14,10 +14,9 @@ import NotificationActions from '../../actions/notification_actions';
import GlobalNotificationModel from '../../models/global_notification_model';
import GlobalNotificationActions from '../../actions/global_notification_actions';
import ApiUrls from '../../constants/api_urls';
import { getAclFormDataId } from '../../utils/form';
import { getLangText } from '../../utils/lang.js';
import { resolveUrl } from '../../utils/url_resolver';
let RequestActionForm = React.createClass({
propTypes: {
@ -35,25 +34,30 @@ let RequestActionForm = React.createClass({
},
getUrls() {
let urls = {};
const urls = {};
if (this.props.notifications.action === 'consign') {
urls.accept = ApiUrls.ownership_consigns_confirm;
urls.deny = ApiUrls.ownership_consigns_deny;
urls.accept = 'ownership_consigns_confirm';
urls.deny = 'ownership_consigns_deny';
} else if (this.props.notifications.action === 'unconsign') {
urls.accept = ApiUrls.ownership_unconsigns;
urls.deny = ApiUrls.ownership_unconsigns_deny;
urls.accept = 'ownership_unconsigns';
urls.deny = 'ownership_unconsigns_deny';
} else if (this.props.notifications.action === 'loan' && !this.isPiece()) {
urls.accept = ApiUrls.ownership_loans_confirm;
urls.deny = ApiUrls.ownership_loans_deny;
urls.accept = 'ownership_loans_confirm';
urls.deny = 'ownership_loans_deny';
} else if (this.props.notifications.action === 'loan' && this.isPiece()) {
urls.accept = ApiUrls.ownership_loans_pieces_confirm;
urls.deny = ApiUrls.ownership_loans_pieces_deny;
urls.accept = 'ownership_loans_pieces_confirm';
urls.deny = 'ownership_loans_pieces_deny';
} else if (this.props.notifications.action === 'loan_request' && this.isPiece()) {
urls.accept = ApiUrls.ownership_loans_pieces_request_confirm;
urls.deny = ApiUrls.ownership_loans_pieces_request_deny;
urls.accept = 'ownership_loans_pieces_request_confirm';
urls.deny = 'ownership_loans_pieces_request_deny';
}
// Resolve the urls
Object.entries(urls).forEach(([key, val]) => {
urls[key] = resolveUrl(val);
});
return urls;
},

View File

@ -16,10 +16,9 @@ import AscribeSpinner from '../ascribe_spinner';
import withContext from '../context/with_context';
import { routerShape } from '../prop_types';
import ApiUrls from '../../constants/api_urls';
import { safeMerge } from '../../utils/general';
import { getLangText } from '../../utils/lang';
import { resolveUrl } from '../../utils/url_resolver';
const SendContractAgreementForm = React.createClass({
@ -103,7 +102,7 @@ const SendContractAgreementForm = React.createClass({
<Form
className="ascribe-form-bordered ascribe-form-wrapper"
ref='form'
url={ApiUrls.ownership_contract_agreements}
url={resolveUrl('ownership_contract_agreements')}
getFormData={this.getFormData}
handleSuccess={this.handleSubmitSuccess}
buttons={<button

View File

@ -15,9 +15,8 @@ import AscribeSpinner from '../ascribe_spinner';
import withContext from '../context/with_context';
import { locationShape } from '../prop_types';
import ApiUrls from '../../constants/api_urls';
import { getLangText } from '../../utils/lang';
import { resolveUrl } from '../../utils/url_resolver';
let SignupForm = React.createClass({
@ -71,7 +70,7 @@ let SignupForm = React.createClass({
<Form
className="ascribe-form-bordered"
ref='form'
url={ApiUrls.users_signup}
url={resolveUrl('users_signup')}
getFormData={this.getFormData}
handleSuccess={this.handleSuccess}
buttons={

View File

@ -17,9 +17,8 @@ import AscribeSpinner from '../ascribe_spinner';
import withContext from '../context/with_context';
import { currentUserShape, whitelabelShape } from '../prop_types';
import ApiUrls from '../../constants/api_urls';
import { getLangText } from '../../utils/lang';
import { resolveUrl } from '../../utils/url_resolver';
let AccountSettings = React.createClass({
propTypes: {
@ -49,7 +48,7 @@ let AccountSettings = React.createClass({
if (currentUser.username) {
content = (
<Form
url={ApiUrls.users_username}
url={resolveUrl('users_username')}
handleSuccess={this.handleSuccess}>
<Property
name='username'
@ -79,7 +78,7 @@ let AccountSettings = React.createClass({
aclObject={whitelabel}
aclName="acl_view_settings_account_hash">
<Form
url={ApiUrls.users_profile}
url={resolveUrl('users_profile')}
handleSuccess={this.handleSuccess}
getFormData={this.getFormDataProfile}>
<Property

View File

@ -14,10 +14,10 @@ import Property from '../ascribe_forms/property';
import ActionPanel from '../ascribe_panel/action_panel';
import CollapsibleParagraph from '../ascribe_collapsible/collapsible_paragraph';
import ApiUrls from '../../constants/api_urls';
import AscribeSpinner from '../ascribe_spinner';
import { getLangText } from '../../utils/lang';
import { resolveUrl } from '../../utils/url_resolver';
let APISettings = React.createClass({
@ -99,7 +99,7 @@ let APISettings = React.createClass({
title={getLangText('API Integration')}
defaultExpanded={this.props.defaultExpanded}>
<Form
url={ApiUrls.applications}
url={resolveUrl('applications')}
handleSuccess={this.handleCreateSuccess}>
<Property
name='name'

View File

@ -10,13 +10,13 @@ import GlobalNotificationActions from '../../actions/global_notification_actions
import ReactS3FineUploader from '../ascribe_uploader/react_s3_fine_uploader';
import UploadButton from '../ascribe_uploader/ascribe_upload_button/upload_button';
import ApiUrls from '../../constants/api_urls';
import AppConstants from '../../constants/application_constants';
import { validationTypes } from '../../constants/uploader_constants';
import { formSubmissionValidation } from '../ascribe_uploader/react_s3_fine_uploader_utils';
import { getCookie } from '../../utils/fetch_api';
import { getLangText } from '../../utils/lang';
import { resolveUrl } from '../../utils/url_resolver';
let ContractSettingsUpdateButton = React.createClass({
@ -66,7 +66,7 @@ let ContractSettingsUpdateButton = React.createClass({
fileClass: 'contract'
}}
createBlobRoutine={{
url: ApiUrls.blob_contracts
url: resolveUrl('blob_contracts')
}}
validation={{
itemLimit: validationTypes.registerWork.itemLimit,

View File

@ -16,10 +16,10 @@ import AclProxy from '../acl_proxy';
import ActionPanel from '../ascribe_panel/action_panel';
import CollapsibleParagraph from '../ascribe_collapsible/collapsible_paragraph';
import ApiUrls from '../../constants/api_urls';
import AscribeSpinner from '../ascribe_spinner';
import { getLangText } from '../../utils/lang';
import { resolveUrl } from '../../utils/url_resolver';
let WebhookSettings = React.createClass({
@ -143,7 +143,7 @@ let WebhookSettings = React.createClass({
<AclProxy show={this.state.webhookEvents && this.state.webhookEvents.length > 0}>
<Form
ref="webhookCreateForm"
url={ApiUrls.webhooks}
url={resolveUrl('webhooks')}
handleSuccess={this.handleCreateSuccess}>
{this.getEvents()}
<Property

View File

@ -13,10 +13,9 @@ import AscribeSpinner from './ascribe_spinner';
import withContext from './context/with_context';
import { locationShape } from './prop_types';
import ApiUrls from '../constants/api_urls';
import { setDocumentTitle } from '../utils/dom';
import { getLangText } from '../utils/lang';
import { resolveUrl } from '../utils/url_resolver';
let CoaVerifyContainer = React.createClass({
@ -75,7 +74,7 @@ let CoaVerifyForm = React.createClass({
return (
<Form
url={ApiUrls.coa_verify}
url={resolveUrl('coa_verify')}
handleSuccess={this.handleSuccess}
buttons={
<button

View File

@ -12,10 +12,9 @@ import AscribeSpinner from './ascribe_spinner';
import withContext from './context/with_context';
import { locationShape, routerShape } from './prop_types';
import ApiUrls from '../constants/api_urls';
import { setDocumentTitle } from '../utils/dom';
import { getLangText } from '../utils/lang';
import { resolveUrl } from '../utils/url_resolver';
let PasswordResetContainer = React.createClass({
@ -76,7 +75,7 @@ let PasswordRequestResetForm = React.createClass({
<Form
ref="form"
className='ascribe-form-wrapper'
url={ApiUrls.users_password_reset_request}
url={resolveUrl('users_password_reset_request')}
handleSuccess={this.handleSuccess}
buttons={
<button
@ -136,7 +135,7 @@ let PasswordResetForm = withContext(React.createClass({
<Form
ref="form"
className='ascribe-form-wrapper'
url={ApiUrls.users_password_reset}
url={resolveUrl('users_password_reset')}
handleSuccess={this.handleSuccess}
getFormData={this.getFormData}
buttons={

View File

@ -15,9 +15,8 @@ import Piece from '../../../../../components/ascribe_detail/piece';
import AscribeSpinner from '../../../../ascribe_spinner';
import withContext from '../../../../context/with_context';
import ApiUrls from '../../../../../constants/api_urls';
import { getLangText } from '../../../../../utils/lang';
import { resolveUrl } from '../../../../../utils/url_resolver';
let WalletPieceContainer = React.createClass({
@ -85,7 +84,7 @@ let WalletPieceContainer = React.createClass({
placeholder={getLangText('Enter your comments ...')}
editable={true}
successMessage={getLangText('Private note saved')}
url={ApiUrls.note_private_piece} />
url={resolveUrl('note_private_piece')} />
</CollapsibleParagraph>
{children}
</Piece>

View File

@ -12,13 +12,12 @@ import FurtherDetailsFileuploader from '../../../../../ascribe_detail/further_de
import GlobalNotificationModel from '../../../../../../models/global_notification_model';
import GlobalNotificationActions from '../../../../../../actions/global_notification_actions';
import ApiUrls from '../../../../../../constants/api_urls';
import AscribeSpinner from '../../../../../ascribe_spinner';
import requests from '../../../../../../utils/requests';
import { getLangText } from '../../../../../../utils/lang';
import { formSubmissionValidation } from '../../../../../ascribe_uploader/react_s3_fine_uploader_utils';
import requests from '../../../../../../utils/requests';
import { resolveUrl } from '../../../../../../utils/url_resolver';
let CylandAdditionalDataForm = React.createClass({
@ -113,7 +112,7 @@ let CylandAdditionalDataForm = React.createClass({
disabled={disabled}
className="ascribe-form-bordered"
ref='form'
url={requests.prepareUrl(ApiUrls.piece_extradata, { piece_id: piece.id })}
url={requests.prepareUrl(resolveUrl('piece_extradata'), { piece_id: piece.id })}
handleSuccess={handleSuccess || this.handleSuccess}
getFormData={this.getFormData}
buttons={buttons}

View File

@ -26,12 +26,11 @@ import SlidesContainer from '../../../../ascribe_slides_container/slides_contain
import withContext from '../../../../context/with_context';
import { currentUserShape, locationShape, routerShape, whitelabelShape } from '../../../../prop_types';
import ApiUrls from '../../../../../constants/api_urls';
import { setDocumentTitle } from '../../../../../utils/dom';
import { getAclFormMessage } from '../../../../../utils/form';
import { safeMerge } from '../../../../../utils/general';
import { getLangText } from '../../../../../utils/lang';
import { resolveUrl } from '../../../../../utils/url_resolver';
const CylandRegisterPiece = React.createClass({
@ -199,7 +198,7 @@ const CylandRegisterPiece = React.createClass({
senderName: currentUser.username
})}
id={{piece_id: piece.id}}
url={ApiUrls.ownership_loans_pieces}
url={resolveUrl('ownership_loans_pieces')}
email={whitelabel.user}
gallery="Cyland Archive"
startDate={today}

View File

@ -10,12 +10,11 @@ import InputTextAreaToggable from '../../../../../ascribe_forms/input_textarea_t
import GlobalNotificationModel from '../../../../../../models/global_notification_model';
import GlobalNotificationActions from '../../../../../../actions/global_notification_actions';
import ApiUrls from '../../../../../../constants/api_urls';
import AscribeSpinner from '../../../../../ascribe_spinner';
import requests from '../../../../../../utils/requests';
import { getLangText } from '../../../../../../utils/lang';
import requests from '../../../../../../utils/requests';
import { resolveUrl } from '../../../../../../utils/url_resolver';
let IkonotvArtistDetailsForm = React.createClass({
@ -98,7 +97,7 @@ let IkonotvArtistDetailsForm = React.createClass({
disabled={disabled}
className="ascribe-form-bordered"
ref='form'
url={requests.prepareUrl(ApiUrls.piece_extradata, { piece_id: piece.id })}
url={requests.prepareUrl(resolveUrl('piece_extradata'), { piece_id: piece.id })}
handleSuccess={handleSuccess || this.handleSuccess}
getFormData={this.getFormData}
buttons={buttons}

View File

@ -10,12 +10,11 @@ import InputTextAreaToggable from '../../../../../ascribe_forms/input_textarea_t
import GlobalNotificationModel from '../../../../../../models/global_notification_model';
import GlobalNotificationActions from '../../../../../../actions/global_notification_actions';
import ApiUrls from '../../../../../../constants/api_urls';
import AscribeSpinner from '../../../../../ascribe_spinner';
import requests from '../../../../../../utils/requests';
import { getLangText } from '../../../../../../utils/lang';
import requests from '../../../../../../utils/requests';
import { resolveUrl } from '../../../../../../utils/url_resolver';
let IkonotvArtworkDetailsForm = React.createClass({
@ -98,7 +97,7 @@ let IkonotvArtworkDetailsForm = React.createClass({
disabled={disabled}
className="ascribe-form-bordered"
ref='form'
url={requests.prepareUrl(ApiUrls.piece_extradata, { piece_id: piece.id })}
url={requests.prepareUrl(resolveUrl('piece_extradata'), { piece_id: piece.id })}
handleSuccess={handleSuccess || this.handleSuccess}
getFormData={this.getFormData}
buttons={buttons}

View File

@ -24,10 +24,9 @@ import SlidesContainer from '../../../../ascribe_slides_container/slides_contain
import withContext from '../../../../context/with_context';
import { currentUserShape, locationShape, routerShape, whitelabelShape } from '../../../../prop_types';
import ApiUrls from '../../../../../constants/api_urls';
import { safeMerge } from '../../../../../utils/general';
import { getLangText } from '../../../../../utils/lang';
import { resolveUrl } from '../../../../../utils/url_resolver';
const IkonotvRegisterPiece = React.createClass({
@ -193,7 +192,7 @@ const IkonotvRegisterPiece = React.createClass({
<LoanForm
loanHeading={getLangText('Loan to IkonoTV archive')}
id={{piece_id: piece.id}}
url={ApiUrls.ownership_loans_pieces}
url={resolveUrl('ownership_loans_pieces')}
email={whitelabel.user}
startDate={today}
endDate={endDate}

View File

@ -13,13 +13,12 @@ import Property from '../../../../../ascribe_forms/property';
import AscribeSpinner from '../../../../../ascribe_spinner';
import ApiUrls from '../../../../../../constants/api_urls';
import { validationParts, validationTypes } from '../../../../../../constants/uploader_constants';
import requests from '../../../../../../utils/requests';
import { formSubmissionValidation } from '../../../../../ascribe_uploader/react_s3_fine_uploader_utils';
import { getLangText } from '../../../../../../utils/lang';
import requests from '../../../../../../utils/requests';
import { resolveUrl } from '../../../../../../utils/url_resolver';
let MarketAdditionalDataForm = React.createClass({
@ -153,7 +152,7 @@ let MarketAdditionalDataForm = React.createClass({
className="ascribe-form-bordered"
ref='form'
key={this.state.forceUpdateKey}
url={requests.prepareUrl(ApiUrls.piece_extradata, { piece_id: pieceId })}
url={requests.prepareUrl(resolveUrl('piece_extradata'), { piece_id: pieceId })}
handleSuccess={showNotification ? this.handleSuccessWithNotification : handleSuccess}
getFormData={this.getFormData}
buttons={buttons}

View File

@ -4,7 +4,7 @@ import Redirect from 'react-router/es6/Redirect';
import getWalletApiUrls from './constants/wallet_api_urls';
import getWalletRoutes from './wallet_routes';
import { updateApiUrls } from '../../../constants/api_urls';
import { mergeWithBaseApiUrls } from '../../../constants/api_urls';
function resolve(subdomain) {
@ -14,7 +14,7 @@ function resolve(subdomain) {
return {
redirectRoute,
apiUrls: updateApiUrls(getWalletApiUrls(subdomain)),
apiUrls: mergeWithBaseApiUrls(getWalletApiUrls(subdomain)),
routes: getWalletRoutes(subdomain)
};
}

View File

@ -72,9 +72,8 @@ const ApiUrls = {
'sign_url_s3': AppConstants.serverUrl + '/s3/sign_url/'
};
export function updateApiUrls(updatedApiUrls) {
return Object.assign(ApiUrls, updatedApiUrls);
export function mergeWithBaseApiUrls(updatedApiUrls) {
return Object.assign({}, ApiUrls, updatedApiUrls);
}
export default ApiUrls;

View File

@ -2,14 +2,14 @@
import requests from '../utils/requests';
import ApiUrls from '../constants/api_urls';
// FIXME: fix query string usage
let OwnershipFetcher = {
/**
* Fetch the default, public contract of a user from the API.
*/
fetchContract(email) {
return requests.get(ApiUrls.blob_contracts + '?loanee=' + email);
fetchContract(loanee) {
return requests.get('blob_contracts', { loanee });
},
/**
@ -21,7 +21,7 @@ let OwnershipFetcher = {
isPublic,
issuer
};
return requests.get(ApiUrls.ownership_contract_list, queryParams);
return requests.get('ownership_contract_list', queryParams);
},
@ -29,7 +29,7 @@ let OwnershipFetcher = {
* Create a contractagreement between the logged-in user and the email from the API with contract.
*/
createContractAgreement(signee, contractObj) {
return requests.post(ApiUrls.ownership_contract_agreements, { body: {signee: signee, contract: contractObj.id }});
return requests.post('ownership_contract_agreements', { body: {signee: signee, contract: contractObj.id }});
},
/**
@ -41,27 +41,27 @@ let OwnershipFetcher = {
accepted,
pending
};
return requests.get(ApiUrls.ownership_contract_agreements, queryParams);
return requests.get('ownership_contract_agreements', queryParams);
},
confirmContractAgreement(contractAgreement) {
return requests.put(ApiUrls.ownership_contract_agreements_confirm, {contract_agreement_id: contractAgreement.id});
return requests.put('ownership_contract_agreements_confirm', {contract_agreement_id: contractAgreement.id});
},
denyContractAgreement(contractAgreement) {
return requests.put(ApiUrls.ownership_contract_agreements_deny, {contract_agreement_id: contractAgreement.id});
return requests.put('ownership_contract_agreements_deny', {contract_agreement_id: contractAgreement.id});
},
fetchLoanPieceRequestList() {
return requests.get(ApiUrls.ownership_loans_pieces_request);
return requests.get('ownership_loans_pieces_request');
},
changeContract(contractObj) {
return requests.put(ApiUrls.ownership_contract, { body: contractObj, contract_id: contractObj.id });
return requests.put('ownership_contract', { body: contractObj, contract_id: contractObj.id });
},
deleteContract(contractObjId) {
return requests.delete(ApiUrls.ownership_contract, {contract_id: contractObjId});
return requests.delete('ownership_contract', {contract_id: contractObjId});
}
};

View File

@ -1,10 +1,9 @@
'use strict';
import requests from '../utils/requests';
import ApiUrls from '../constants/api_urls';
import UserActions from '../actions/user_actions';
import requests from '../utils/requests';
const UserSource = {
lookupCurrentUser: {
@ -26,7 +25,7 @@ const UserSource = {
performLogoutCurrentUser: {
remote() {
return requests.get(ApiUrls.users_logout);
return requests.get('users_logout');
},
success: UserActions.successLogoutCurrentUser,

32
js/utils/url_resolver.js Normal file
View File

@ -0,0 +1,32 @@
let URL_MAPPING;
export function resolveUrl(url) {
let apiUrl = url;
if (!url) {
throw new Error('Url was not defined');
} else if (!url.match(/^http/)) {
apiUrl = URL_MAPPING && URL_MAPPING[url];
if (!apiUrl) {
if (process.env.NODE_ENV === 'production' &&
!(URL_MAPPING && Object.keys(URL_MAPPING).length)) {
// eslint-disable-next-line no-console
console.warn('No url mapping was defined yet for ApiUrlResolver.');
}
throw new Error(`Could not find a url mapping for "${url}"`);
}
}
return apiUrl;
}
export function setUrlMapping(urlMapping) {
URL_MAPPING = urlMapping;
}
export default {
setUrlMapping,
resolve: resolveUrl
};