diff --git a/client/gulp/config.js b/client/gulp/config.js index 481c1b5f..86e35dc7 100644 --- a/client/gulp/config.js +++ b/client/gulp/config.js @@ -5,15 +5,10 @@ module.exports = { 'serverport': 3000, 'scripts': { - 'src': './src/**/*.js', + 'src': './src/*.js', 'dest': './build/js/' }, - 'phpserver': { - 'base': './src/server/', - 'port': 8000 - }, - 'images': { 'src': './src/assets/images/**/*.{jpeg,jpg,png}', 'dest': './build/images/' diff --git a/client/gulp/tasks/browserify.js b/client/gulp/tasks/browserify.js index 352a2ebe..51e38361 100644 --- a/client/gulp/tasks/browserify.js +++ b/client/gulp/tasks/browserify.js @@ -66,4 +66,10 @@ gulp.task('browserify', function() { // Only run watchify if NOT production return buildScript('index.js', !global.isProd); +}); + +gulp.task('config', function() { + + return gulp.src(config.sourceDir + 'config.js') + .pipe(gulp.dest(config.scripts.dest)) }); \ No newline at end of file diff --git a/client/gulp/tasks/development.js b/client/gulp/tasks/development.js index 4d745d1e..fada97fe 100644 --- a/client/gulp/tasks/development.js +++ b/client/gulp/tasks/development.js @@ -10,6 +10,6 @@ gulp.task('dev', ['clean'], function(callback) { global.isProd = false; // Run all tasks once - return runSequence(['sass', 'imagemin', 'browserify', 'copyFonts', 'copyIndex', 'copyIcons', 'serverphp', 'fonts'], 'watch', callback); + return runSequence(['sass', 'imagemin', 'browserify', 'copyFonts', 'copyIndex', 'copyIcons', 'config', 'fonts'], 'watch', callback); }); \ No newline at end of file diff --git a/client/gulp/tasks/serverphp.js b/client/gulp/tasks/serverphp.js deleted file mode 100644 index ea36f95f..00000000 --- a/client/gulp/tasks/serverphp.js +++ /dev/null @@ -1,9 +0,0 @@ -'use strict'; - -var config = require('../config'); -var gulp = require('gulp'); -var connect = require('gulp-connect-php'); - -gulp.task('serverphp', function() { - //connect.server(config.phpserver); -}); diff --git a/client/src/app-components/toggle-button.js b/client/src/app-components/toggle-button.js index ee32845b..ebd3098e 100644 --- a/client/src/app-components/toggle-button.js +++ b/client/src/app-components/toggle-button.js @@ -4,7 +4,6 @@ import classNames from 'classnames'; import i18n from 'lib-app/i18n'; class ToggleButton extends React.Component { - static propTypes = { value: React.PropTypes.bool, @@ -22,6 +21,7 @@ class ToggleButton extends React.Component { getClass() { let classes = { 'toggle-button': true, + 'toggle-button_disabled': (this.props.disabled), [this.props.className]: (this.props.className) }; @@ -30,7 +30,7 @@ class ToggleButton extends React.Component { onClick() { - if (this.props.onChange) { + if (this.props.onChange && !this.props.disabled) { this.props.onChange({ target: { value: !this.props.value diff --git a/client/src/app-components/toggle-button.scss b/client/src/app-components/toggle-button.scss index 6006ae56..f0c3ce7f 100644 --- a/client/src/app-components/toggle-button.scss +++ b/client/src/app-components/toggle-button.scss @@ -7,4 +7,11 @@ border-radius: 4px; text-align: center; user-select: none; + cursor: pointer; + + &_disabled { + cursor: default; + background-color: transparent; + color: $dark-grey; + } } \ No newline at end of file diff --git a/client/src/app/Routes.js b/client/src/app/Routes.js index ee18c790..f6d3c668 100644 --- a/client/src/app/Routes.js +++ b/client/src/app/Routes.js @@ -53,6 +53,15 @@ import AdminPanelSystemPreferences from 'app/admin/panel/settings/admin-panel-sy import AdminPanelAdvancedSettings from 'app/admin/panel/settings/admin-panel-advanced-settings'; import AdminPanelEmailTemplates from 'app/admin/panel/settings/admin-panel-email-templates'; +// INSTALLATION +import InstallLayout from 'app/install/install-layout'; +import InstallStep1Language from 'app/install/install-step-1-language'; +import InstallStep2Requirements from 'app/install/install-step-2-requirements'; +import InstallStep3Database from 'app/install/install-step-3-database'; +import InstallStep4UserSystem from 'app/install/install-step-4-user-system'; +import InstallStep5Admin from 'app/install/install-step-5-admin'; +import InstallStep6Completed from 'app/install/install-step-6-completed'; + const history = syncHistoryWithStore(browserHistory, store); export default ( @@ -82,6 +91,15 @@ export default ( + + + + + + + + + diff --git a/client/src/app/install/install-layout.js b/client/src/app/install/install-layout.js new file mode 100644 index 00000000..c7fb2601 --- /dev/null +++ b/client/src/app/install/install-layout.js @@ -0,0 +1,108 @@ +import React from 'react'; +import classNames from 'classnames'; +import _ from 'lodash'; +import {browserHistory} from 'react-router'; + +import i18n from 'lib-app/i18n'; +import API from 'lib-app/api-call'; + +import Widget from 'core-components/widget'; +import Icon from 'core-components/icon'; + +const steps = [ + 'LANGUAGE', + 'SERVER_REQUIREMENTS', + 'DATABASE_CONFIGURATION', + 'USER_SYSTEM', + 'ADMIN_SETUP', + 'COMPLETED' +]; + +class InstallLayout extends React.Component { + + componentDidMount() { + API.call({ + path: '/system/installation-step', + data: {} + }).then((result) => { + if(result.data != this.getCurrentStep()) { + browserHistory.push('/install/step-' + (result.data + 1)); + } + }); + } + + render() { + return ( + +
+
+ OpenSupports Installation +
+
+
+ {i18n('INSTALL_HEADER_TITLE')} +
+
+ {i18n('INSTALL_HEADER_DESCRIPTION')} +
+
+
+ +
+
+
    + {steps.map(this.renderStep.bind(this))} +
+
+
+ {this.props.children} +
+
+
+ ); + } + + renderStep(key, index) { + let classes = { + 'install-layout__step': true, + 'install-layout__step_current': index === this.getCurrentStep(), + 'install-layout__step_previous': index < this.getCurrentStep() + }; + let icon = 'circle-thin'; + + if(index === this.getCurrentStep()) { + icon = 'arrow-circle-right'; + } else if(index < this.getCurrentStep()) { + icon = 'check-circle'; + } + + return ( +
  • + + + {index+1}. {i18n(key)} + +
  • + ) + } + + getCurrentStep() { + const pathname = this.props.location.pathname; + + if(_.includes(pathname, 'step-1')) { + return 0; + } else if(_.includes(pathname, 'step-2')) { + return 1; + } else if(_.includes(pathname, 'step-3')) { + return 2; + } else if(_.includes(pathname, 'step-4')) { + return 3; + } else if(_.includes(pathname, 'step-5')) { + return 4; + } else if(_.includes(pathname, 'step-6')) { + return 5; + } + } +} + +export default InstallLayout; \ No newline at end of file diff --git a/client/src/app/install/install-layout.scss b/client/src/app/install/install-layout.scss new file mode 100644 index 00000000..f6e7cf15 --- /dev/null +++ b/client/src/app/install/install-layout.scss @@ -0,0 +1,75 @@ +@import "../../scss/vars"; + +.install-layout { + margin: 0 auto; + width: 900px; + min-height: 0; + + @media screen and (max-width: 900px) { + width: 100%; + } + + &__header { + text-align: left; + + &-logo { + display: inline-block; + max-width: 300px; + } + + &-text { + display: inline-block; + margin-left: 20px; + } + + &-title { + text-align: left; + font-weight: bold; + font-size: $font-size--md; + color: $primary-black; + } + + &-description { + text-align: left; + color: $dark-grey; + } + } + + &__body { + margin-top: 20px; + text-align: left; + } + + &__steps { + padding: 0; + list-style-type: none; + border-right: 1px solid $primary-blue; + } + + &__step { + color: $primary-black; + + &-icon { + color: $primary-blue; + margin-right: 10px; + } + + &_current { + + .install-layout__step-icon { + color: $secondary-blue; + } + } + + &_previous { + + .install-layout__step-icon { + color: $primary-green; + } + } + } + + &__content { + min-height: 130px; + } +} diff --git a/client/src/app/install/install-step-1-language.js b/client/src/app/install/install-step-1-language.js new file mode 100644 index 00000000..890ada50 --- /dev/null +++ b/client/src/app/install/install-step-1-language.js @@ -0,0 +1,47 @@ +import React from 'react'; +import {connect} from 'react-redux'; +import {browserHistory} from 'react-router'; + +import i18n from 'lib-app/i18n'; +import ConfigActions from 'actions/config-actions'; + +import LanguageSelector from 'app-components/language-selector'; +import Button from 'core-components/button'; +import Header from 'core-components/header'; + +class InstallStep1Language extends React.Component { + + render() { + return ( +
    +
    + +
    + +
    +
    + ); + } + + getLanguageSelectorProps() { + return { + className: 'install-step-1__languages', + value: this.props.config.language, + type: 'allowed', + onChange: this.changeLanguage.bind(this) + }; + } + + changeLanguage(event) { + this.props.dispatch(ConfigActions.changeLanguage(event.target.value)); + } +} + + +export default connect((store) => { + return { + config: store.config + }; +})(InstallStep1Language); \ No newline at end of file diff --git a/client/src/app/install/install-step-1-language.scss b/client/src/app/install/install-step-1-language.scss new file mode 100644 index 00000000..c21546e8 --- /dev/null +++ b/client/src/app/install/install-step-1-language.scss @@ -0,0 +1,13 @@ +@import "../../scss/vars"; + +.install-step-1 { + + &__label { + font-size: $font-size--md; + margin-bottom: 20px; + } + + &__button { + margin-top: 20px; + } +} \ No newline at end of file diff --git a/client/src/app/install/install-step-2-requirements.js b/client/src/app/install/install-step-2-requirements.js new file mode 100644 index 00000000..8b532704 --- /dev/null +++ b/client/src/app/install/install-step-2-requirements.js @@ -0,0 +1,95 @@ +import React from 'react'; +import _ from 'lodash'; +import classNames from 'classnames'; +import {browserHistory} from 'react-router'; + +import i18n from 'lib-app/i18n'; +import API from 'lib-app/api-call'; + +import Icon from 'core-components/icon'; +import Button from 'core-components/button'; +import Header from 'core-components/header'; +import Table from 'core-components/table'; + +class InstallStep2Requirements extends React.Component { + + state = { + loading: true, + requirements: { + phpVersion: {}, + PDO: {}, + files: {}, + configFile: {} + } + }; + + componentDidMount() { + this.retrieveRequirements(); + } + + render() { + return ( +
    +
    +
    + +
    + +
    + +
    + + ); + } + + getTableProps() { + return { + className: 'install-step-2__requirement-list', + pageSize: 30, + loading: this.state.loading, + headers: [ + {key: 'name', value: i18n('REQUIREMENT'), className: 'col-md-3'}, + {key: 'value', value: i18n('VALUE'), className: 'col-md-9'} + ], + rows: Object.keys(this.state.requirements).map(this.getRequirement.bind(this)) + }; + } + + getRequirement(key) { + const requirement = this.state.requirements[key]; + + return { + className: this.getRequirementClass(requirement), + name: requirement.name, + value: ( +
    + {requirement.value} + +
    + ) + }; + } + + getRequirementClass(requirement) { + let classes = { + 'install-step-2__requirement': true, + 'install-step-2__requirement_error': !requirement.ok + }; + + return classNames(classes); + } + + isAllOk() { + return _.every(this.state.requirements, {ok: true}); + } + + retrieveRequirements() { + this.setState({loading: true}, () => API.call({path: '/system/check-requirements'}).then(({data}) => this.setState({requirements: data, loading: false}))); + } +} + +export default InstallStep2Requirements; \ No newline at end of file diff --git a/client/src/app/install/install-step-2-requirements.scss b/client/src/app/install/install-step-2-requirements.scss new file mode 100644 index 00000000..1c5e2bd5 --- /dev/null +++ b/client/src/app/install/install-step-2-requirements.scss @@ -0,0 +1,51 @@ +@import "../../scss/vars"; + +.install-step-2 { + + &__refresh { + margin: 15px 0; + + &-button { + width: 120px; + position: relative; + text-align: right; + } + + &-icon { + position: absolute; + left: 8px; + top: 8px; + } + } + + &__requirement-list { + margin-bottom: 20px; + } + + &__requirement { + color: $secondary-blue; + + &-value { + width: 200px; + } + + &-assert { + color: $primary-green; + float: right; + margin-top: 3px; + } + + &_error { + color: $secondary-red; + background-color: #ffdfe0 !important; + + .install-step-2__requirement-assert { + color: $secondary-red; + } + } + } + + &__next { + + } +} \ No newline at end of file diff --git a/client/src/app/install/install-step-3-database.js b/client/src/app/install/install-step-3-database.js new file mode 100644 index 00000000..08ed8ebb --- /dev/null +++ b/client/src/app/install/install-step-3-database.js @@ -0,0 +1,78 @@ +import React from 'react'; +import {browserHistory} from 'react-router'; + +import i18n from 'lib-app/i18n'; +import API from 'lib-app/api-call'; + +import Button from 'core-components/button'; +import Header from 'core-components/header'; +import Form from 'core-components/form'; +import FormField from 'core-components/form-field'; +import SubmitButton from 'core-components/submit-button'; +import Message from 'core-components/message'; + +class InstallStep3Database extends React.Component { + + state = { + loading: false, + error: false, + errorMessage: '' + }; + + render() { + return ( +
    +
    + {this.renderMessage()} +
    + + + + +
    + {i18n('NEXT')} + +
    + +
    + ); + } + + renderMessage() { + let message = null; + + if(this.state.error) { + message = ( + + {i18n('ERROR_UPDATING_SETTINGS')}: {this.state.errorMessage} + + ); + } + + return message; + } + + onPreviousClick(event) { + event.preventDefault(); + browserHistory.push('/install/step-2'); + } + + onSubmit(form) { + this.setState({ + loading: true + }, () => { + API.call({ + path: '/system/init-database', + data: form + }) + .then(() => browserHistory.push('/install/step-4')) + .catch(({message}) => this.setState({ + loading: false, + error: true, + errorMessage: message + })); + }); + } +} + +export default InstallStep3Database; \ No newline at end of file diff --git a/client/src/app/install/install-step-3-database.scss b/client/src/app/install/install-step-3-database.scss new file mode 100644 index 00000000..6a4bac27 --- /dev/null +++ b/client/src/app/install/install-step-3-database.scss @@ -0,0 +1,18 @@ +@import "../../scss/vars"; + +.install-step-3 { + + &__message { + margin-bottom: 20px; + } + + &__previous { + float: left; + } + + &__next { + float: left; + position: absolute; + margin-left: 286px; + } +} \ No newline at end of file diff --git a/client/src/app/install/install-step-4-user-system.js b/client/src/app/install/install-step-4-user-system.js new file mode 100644 index 00000000..b5f5af88 --- /dev/null +++ b/client/src/app/install/install-step-4-user-system.js @@ -0,0 +1,68 @@ +import React from 'react'; +import {browserHistory} from 'react-router'; + +import i18n from 'lib-app/i18n'; +import API from 'lib-app/api-call'; + +import ToggleButton from 'app-components/toggle-button'; +import Button from 'core-components/button'; +import Header from 'core-components/header'; +import Form from 'core-components/form'; +import FormField from 'core-components/form-field'; +import SubmitButton from 'core-components/submit-button'; + +class InstallStep4UserSystem extends React.Component { + + state = { + form: { + 'user-system-enabled': true, + 'registration': true + } + }; + + render() { + return ( +
    +
    +
    + + +
    + {i18n('NEXT')} + +
    + +
    + ); + } + + onChange(form) { + this.setState({ + form: { + 'user-system-enabled': form['user-system-enabled'], + 'registration': form['user-system-enabled'] && form['registration'] + } + }); + } + + onPreviousClick(event) { + event.preventDefault(); + browserHistory.push('/install/step-3'); + } + + onSubmit(form) { + API.call({ + path: '/system/init-settings', + data: { + 'user-system-enabled': form['user-system-enabled'], + 'registration': form['registration'] + } + }).then(() => browserHistory.push('/install/step-5')); + } + + isDisabled() { + return !this.state.form['user-system-enabled']; + } +} + +export default InstallStep4UserSystem; \ No newline at end of file diff --git a/client/src/app/install/install-step-4-user-system.scss b/client/src/app/install/install-step-4-user-system.scss new file mode 100644 index 00000000..92e326bb --- /dev/null +++ b/client/src/app/install/install-step-4-user-system.scss @@ -0,0 +1,14 @@ +@import "../../scss/vars"; + +.install-step-4 { + + &__previous { + margin-right: 20px; + } + + &__next { + float: left; + position: absolute; + margin-left: 286px; + } +} \ No newline at end of file diff --git a/client/src/app/install/install-step-5-admin.js b/client/src/app/install/install-step-5-admin.js new file mode 100644 index 00000000..0c5c1903 --- /dev/null +++ b/client/src/app/install/install-step-5-admin.js @@ -0,0 +1,77 @@ +import React from 'react'; +import {browserHistory} from 'react-router'; + +import i18n from 'lib-app/i18n'; +import API from 'lib-app/api-call'; + +import Button from 'core-components/button'; +import Header from 'core-components/header'; +import Form from 'core-components/form'; +import FormField from 'core-components/form-field'; +import SubmitButton from 'core-components/submit-button'; +import Message from 'core-components/message'; + +class InstallStep5Admin extends React.Component { + + state = { + loading: false, + error: false, + errorMessage: '' + }; + + render() { + return ( +
    +
    + {this.renderMessage()} +
    + + + +
    + {i18n('NEXT')} + +
    + +
    + ); + } + + renderMessage() { + let message = null; + + if(this.state.error) { + message = ( + + {i18n('ERROR_UPDATING_SETTINGS')}: {this.state.errorMessage} + + ); + } + + return message; + } + + onPreviousClick(event) { + event.preventDefault(); + browserHistory.push('/install/step-4'); + } + + onSubmit(form) { + this.setState({ + loading: true + }, () => { + API.call({ + path: '/system/init-admin', + data: form + }) + .then(() => browserHistory.push('/install/step-6')) + .catch(({message}) => this.setState({ + loading: false, + error: true, + errorMessage: message + })); + }); + } +} + +export default InstallStep5Admin; \ No newline at end of file diff --git a/client/src/app/install/install-step-5-admin.scss b/client/src/app/install/install-step-5-admin.scss new file mode 100644 index 00000000..2b8eb92d --- /dev/null +++ b/client/src/app/install/install-step-5-admin.scss @@ -0,0 +1,18 @@ +@import "../../scss/vars"; + +.install-step-5 { + + &__message { + margin-bottom: 20px; + } + + &__previous { + margin-right: 20px; + } + + &__next { + float: left; + position: absolute; + margin-left: 286px; + } +} \ No newline at end of file diff --git a/client/src/app/install/install-step-6-completed.js b/client/src/app/install/install-step-6-completed.js new file mode 100644 index 00000000..e610a83d --- /dev/null +++ b/client/src/app/install/install-step-6-completed.js @@ -0,0 +1,28 @@ +import React from 'react'; +import {browserHistory} from 'react-router'; + +import i18n from 'lib-app/i18n'; +import API from 'lib-app/api-call'; + +import Header from 'core-components/header'; +import Message from 'core-components/message'; + +class InstallStep6Completed extends React.Component { + + componentDidMount() { + setTimeout(() => browserHistory.push('/admin'), 5000); + } + + render() { + return ( +
    +
    + + {i18n('INSTALLATION_COMPLETED_DESCRIPTION')} + +
    + ); + } +} + +export default InstallStep6Completed; \ No newline at end of file diff --git a/client/src/app/install/install-step-6-completed.scss b/client/src/app/install/install-step-6-completed.scss new file mode 100644 index 00000000..c990d9a8 --- /dev/null +++ b/client/src/app/install/install-step-6-completed.scss @@ -0,0 +1 @@ +@import "../../scss/vars"; diff --git a/client/src/config.js b/client/src/config.js new file mode 100644 index 00000000..e206592e --- /dev/null +++ b/client/src/config.js @@ -0,0 +1,2 @@ +root = 'http://localhost:3000'; +apiRoot = 'http://localhost:3000/api'; diff --git a/client/src/core-components/form-field.js b/client/src/core-components/form-field.js index 376c11db..ee5a1441 100644 --- a/client/src/core-components/form-field.js +++ b/client/src/core-components/form-field.js @@ -29,7 +29,8 @@ class FormField extends React.Component { }; static defaultProps = { - field: 'input' + field: 'input', + fieldProps: {} }; static getDefaultValue(field) { @@ -120,7 +121,7 @@ class FormField extends React.Component { getFieldProps() { let props = _.extend({}, this.props.fieldProps, { - disabled: this.context.loading, + disabled: this.isDisabled(), errored: !!this.props.error, name: this.props.name, placeholder: this.props.placeholder, @@ -171,6 +172,12 @@ class FormField extends React.Component { this.props.onChange(event) } } + + isDisabled() { + const fieldProps = this.props.fieldProps; + + return (fieldProps.disabled === undefined) ? this.context.loading : fieldProps.disabled; + } focus() { if (this.refs.nativeField) { diff --git a/client/src/core-components/table.js b/client/src/core-components/table.js index 099557d4..fe882f72 100644 --- a/client/src/core-components/table.js +++ b/client/src/core-components/table.js @@ -146,6 +146,8 @@ class Table extends React.Component { 'table__row-highlighted': row.highlighted }; + classes[row.className] = (row.className); + return classNames(classes); } diff --git a/client/src/data/fixtures/system-fixtures.js b/client/src/data/fixtures/system-fixtures.js index b71b7219..d160a64a 100644 --- a/client/src/data/fixtures/system-fixtures.js +++ b/client/src/data/fixtures/system-fixtures.js @@ -56,6 +56,37 @@ module.exports = [ } } }, + { + path: '/system/init-settings', + time: 50, + response: function() { + return { + status: 'success', + data: {} + }; + } + }, + { + path: '/system/init-database', + time: 50, + response: function() { + return { + status: 'success', + message: 'ERROR_SERVER', + data: {} + }; + } + }, + { + path: '/system/init-admin', + time: 50, + response: function() { + return { + status: 'success', + data: {} + }; + } + }, { path: '/system/edit-settings', time: 50, @@ -63,7 +94,38 @@ module.exports = [ return { status: 'success', data: {} - } + }; + } + }, + { + path: '/system/check-requirements', + time: 50, + response: function () { + return { + status: 'success', + data: { + phpVersion: { + name: 'PHP Version', + value: 5.6, + ok: true + }, + PDO: { + name: 'PDO Module', + value: 'Available', + ok: true + }, + files: { + name: 'Folder: /api/files', + value: 'Writable', + ok: true + }, + configFile: { + name: 'File: /api/config.php', + value: 'Writable', + ok: true + } + } + }; } }, { diff --git a/client/src/data/languages/en.js b/client/src/data/languages/en.js index b56acad0..b6b8ee57 100644 --- a/client/src/data/languages/en.js +++ b/client/src/data/languages/en.js @@ -173,7 +173,8 @@ export default { 'ACTIVITY': 'Activity', 'HOME': 'Home', 'TICKET_NUMBER': 'Ticket number', - + 'NEXT': 'Next', + 'CHART_CREATE_TICKET': 'Tickets created', 'CHART_CLOSE': 'Tickets closed', 'CHART_SIGNUP': 'Signups', @@ -208,6 +209,37 @@ export default { 'ACTIVITY_DELETE_USER': 'deleted user', 'ACTIVITY_UN_BAN_USER': 'banned user', + 'SERVER_REQUIREMENTS': 'Server requirements', + 'DATABASE_CONFIGURATION': 'Database configuration', + 'ADMIN_SETUP': 'Admin setup', + 'COMPLETED': 'Completed', + 'INSTALL_HEADER_TITLE': 'OpenSupports Installation Wizard', + 'INSTALL_HEADER_DESCRIPTION': 'This wizard will help you to configure and install OpenSupports on your website', + 'SELECT_LANGUAGE': 'Select language', + 'REQUIREMENT': 'Requirement', + 'VALUE': 'Value', + 'REFRESH': 'Refresh', + 'USER_SYSTEM': 'User System', + 'PREVIOUS': 'Previous', + 'DATABASE_HOST': 'MySQL server', + 'DATABASE_NAME': 'MySQL database name', + 'DATABASE_USER': 'MySQL user', + 'DATABASE_PASSWORD': 'MySQL password', + 'ADMIN_NAME': 'Admin account name', + 'ADMIN_EMAIL': 'Admin account email', + 'ADMIN_PASSWORD': 'Admin account password', + 'ADMIN_PASSWORD_DESCRIPTION': 'Please remember this password. It is needed for accessing the admin panel. You can change it later.', + 'INSTALLATION_COMPLETED': 'Installation completed.', + 'INSTALLATION_COMPLETED_DESCRIPTION': 'The installation of OpenSupports is completed. Redirecting to admin panel...', + + 'STEP_TITLE': 'Step {current} of {total} - {title}', + 'STEP_1_DESCRIPTION': 'Select your preferred language for the installation wizard.', + 'STEP_2_DESCRIPTION': 'Here are listed the requirements for running OpenSupports. Please make sure that all requirements are satisfied.', + 'STEP_3_DESCRIPTION': 'Please fill the MySQL database configuration.', + 'STEP_4_DESCRIPTION': 'Please select your user system preferences.', + 'STEP_5_DESCRIPTION': 'Please configure the administrator account.', + 'STEP_6_DESCRIPTION': 'Installation is completed.', + //VIEW DESCRIPTIONS 'CREATE_TICKET_DESCRIPTION': 'This is a form for creating tickets. Fill the form and send us your issues/doubts/suggestions. Our support system will answer it as soon as possible.', 'TICKET_LIST_DESCRIPTION': 'Here you can find a list of all tickets you have sent to our support team.', diff --git a/client/src/index.html b/client/src/index.html index d6e6adbb..04d3e7f6 100644 --- a/client/src/index.html +++ b/client/src/index.html @@ -9,11 +9,13 @@ OS4 +
    + diff --git a/client/src/lib-app/api-call.js b/client/src/lib-app/api-call.js index b20cf618..1e61dc52 100644 --- a/client/src/lib-app/api-call.js +++ b/client/src/lib-app/api-call.js @@ -2,9 +2,6 @@ const _ = require('lodash'); const APIUtils = require('lib-core/APIUtils'); const SessionStore = require('lib-app/session-store'); -const url = 'http://localhost:3000'; -const apiUrl = 'http://localhost:3000/api'; - function processData (data, dataAsForm = false) { let newData; @@ -31,7 +28,7 @@ module.exports = { call: function ({path, data, plain, dataAsForm}) { console.log('request ' + path, data); return new Promise(function (resolve, reject) { - APIUtils.post(apiUrl + path, processData(data, dataAsForm), dataAsForm) + APIUtils.post(apiRoot + path, processData(data, dataAsForm), dataAsForm) .then(function (result) { console.log(result); @@ -53,14 +50,14 @@ module.exports = { }, getFileLink(filePath) { - return apiUrl + '/system/download?file=' + filePath; + return apiRoot + '/system/download?file=' + filePath; }, getAPIUrl() { - return apiUrl; + return apiRoot; }, getURL() { - return url; + return root; } }; \ No newline at end of file