Commit f44a3954 authored by Alessadro's avatar Alessadro

Redux migration

parent 26c5f600
Pipeline #31351484 failed with stages
in 1 minute and 14 seconds
......@@ -13,12 +13,23 @@ window.env = {
// URL
// Online Simcaa.it
"GraphQLServer": "http://www.simcaa.it/demo/apisimcaa-graphql/public/graphql/query",
"GraphQLServerNoAuth": "http://www.simcaa.it/demo/apisimcaa-graphql/public/graphql/query/noauth",
"GraphQLLogin": "http://www.simcaa.it/demo/apisimcaa-graphql/public/graphql/login",
"GraphQLCurrentUser": "http://www.simcaa.it/demo/apisimcaa-graphql/public/graphql/me",
"GraphQLRefreshToken": "http://www.simcaa.it/demo/apisimcaa-graphql/public/graphql/jwtrefresh",
"RestApiCard": "http://www.simcaa.it/demo/apisimcaa-graphql/public/graphql/card",
// "GraphQLServer": "http://www.simcaa.it/demo/apisimcaa-graphql/public/graphql/query",
// "GraphQLServerNoAuth": "http://www.simcaa.it/demo/apisimcaa-graphql/public/graphql/query/noauth",
// "GraphQLLogin": "http://www.simcaa.it/demo/apisimcaa-graphql/public/graphql/login",
// "GraphQLCurrentUser": "http://www.simcaa.it/demo/apisimcaa-graphql/public/graphql/me",
// "GraphQLRefreshToken": "http://www.simcaa.it/demo/apisimcaa-graphql/public/graphql/jwtrefresh",
// "RestApiCard": "http://www.simcaa.it/demo/apisimcaa-graphql/public/graphql/card",
// TEMP: DEMO2 (DELETE LATER)
// Online Simcaa.it
"GraphQLServer": "http://www.simcaa.it/demo2/apisimcaa-graphql/public/graphql/query",
"GraphQLServerNoAuth": "http://www.simcaa.it/demo2/apisimcaa-graphql/public/graphql/query/noauth",
"GraphQLLogin": "http://www.simcaa.it/demo2/apisimcaa-graphql/public/graphql/login",
"GraphQLCurrentUser": "http://www.simcaa.it/demo2/apisimcaa-graphql/public/graphql/me",
"GraphQLRefreshToken": "http://www.simcaa.it/demo2/apisimcaa-graphql/public/graphql/jwtrefresh",
"RestApiCard": "http://www.simcaa.it/demo2/apisimcaa-graphql/public/graphql/card",
// Local
// "GraphQLServer": "http://10.0.0.132:8085/graphql/query",
......
......@@ -10,6 +10,7 @@ window.language = {
"MAIN_LBL_NEWS": "Ultime News",
"MAIN_TBL_NAME": "Nome",
"MAIN_TBL_PROFILEOWN": "Proprietario del Profilo",
"MAIN_TBL_TEAMOWN": "Team associato al Profilo",
"MAIN_TBL_DATEUPDATE": "Ultimo aggiornamento",
"MAIN_TBL_NOTES": "Note",
"MAIN_TBL_SHARE": "Condivisione",
......@@ -161,6 +162,7 @@ window.language = {
"PRJ_FRM_TITLE": "Titolo del capitolo",
"PRJ_FRM_ERROR_HEADER": "Errore",
"PRJ_FRM_ERROR_CONTENT": "Il titolo del progetto non può essere lasciato vuoto o il formato del margine non è corretto",
"PRJ_FRM_ERROR_PROFILE": "Selezionare il profilo da usare per il progetto",
"PRJ_FRM_LAYOUT": "Layout del capitolo",
"PRJ_BTN_CREATE": "Crea Capitolo",
"PRJ_BTN_CLOSE": "Chiudi",
......@@ -172,6 +174,14 @@ window.language = {
"BTN_DENY": "Annulla",
"BTN_CONFIRM": "Conferma",
"BTN_MOD": "Modifica",
"BTN_SEARCH": "Cerca",
"BTN_RESET": "Resetta la ricerca",
// FILTER
"FLT_FILTER": "Filtri",
"FLT_PRIVATE": "Elenca i tuoi progetti",
"FLT_TEAM": "Elenca i progetti del team selezionato",
"FLT_PUBLIC": "Elenca i progetti pubblici",
// TTS
"HEAD_TTS_TEXT": "Opzioni Sintesi Vocale",
......@@ -184,6 +194,19 @@ window.language = {
"TTS_FRM_HIGHLIGHTER_CARD": "Sulla Card",
"TTS_FRM_HIGHLIGHTER_INPUT": "Sul Testo",
// INIT APP
"INIT_FETCH_PROJECT": "Sto caricando i progetti",
"INIT_FETCH_PROFILE": "Sto caricando i profili",
"INIT_FETCH_LAYOUT": "Sto caricando i layout",
"INIT_FETCH_CLASS": "Sto caricando le classi dei lemmi",
"INIT_FETCH_STYLE": "Sto caricando gli stili",
"INIT_FETCH_SIMSTYLE": "Sto caricando gli stili dei simboli",
"INIT_FETCH_TEAM": "Sto caricando i team",
"TMSEL_DROP_PLACEHOLDER": "Scegli un team",
"TMSEL_MSG_ERROR": "Nessun team selezionato",
"TMSEL_HEADER": "Sono stati rilevati più team per il tuo utente, scegli un team con cui procedere",
"TMSEL_BTN_CONTINUE": "Continua",
//ADMINISTRATION
//ADMIN-MENU
......@@ -267,7 +290,7 @@ window.language = {
"POPUP_DELETE": "Elimina carta",
// ERROR
"ERR_FILESIZE_EXCEED": "Le dimensioni dell'immagine sono troppo alte (Max: 500Kb)",
"ERR_FILESIZE_EXCEED": "Le dimensioni dell'immagine sono troppo alte (Max: 5Mb)",
"ERR_DUPLICATE_RECORD": "Record doppi trovati",
"ERR_UPLOAD_SYMBOL": "Errore nell'immagine o nel lemma",
......@@ -296,6 +319,7 @@ window.language = {
"MAIN_LBL_NEWS": "Last News",
"MAIN_TBL_NAME": "Name",
"MAIN_TBL_PROFILEOWN": "Profile Owner",
"MAIN_TBL_TEAMOWN": "Profile's team",
"MAIN_TBL_DATEUPDATE": "Date Update",
"MAIN_TBL_NOTES": "Notes",
"MAIN_TBL_SHARE": "Share",
......@@ -447,6 +471,7 @@ window.language = {
"PRJ_FRM_TITLE": "Chapter Title",
"PRJ_FRM_ERROR_HEADER": "Error",
"PRJ_FRM_ERROR_CONTENT": "The project title cannot be empty or the margin size format is incorrect",
"PRJ_FRM_ERROR_PROFILE": "Select a profile for the current project",
"PRJ_FRM_LAYOUT": "Chapter Layout",
"PRJ_BTN_CREATE": "Create Chapter",
"PRJ_BTN_CLOSE": "Close",
......@@ -458,6 +483,14 @@ window.language = {
"BTN_DENY": "Deny",
"BTN_CONFIRM": "Confirm",
"BTN_MOD": "Modify",
"BTN_SEARCH": "Search",
"BTN_RESET": "Reset search",
// FILTER
"FLT_FILTER": "Filter",
"FLT_PRIVATE": "View your projects",
"FLT_TEAM": "View your team projetcs",
"FLT_PUBLIC": "View public projetcs",
// TTS
"HEAD_TTS_TEXT": "Options Text to Speech",
......@@ -470,6 +503,19 @@ window.language = {
"TTS_FRM_HIGHLIGHTER_CARD": "on Card",
"TTS_FRM_HIGHLIGHTER_INPUT": "on Text",
// INIT APP
"INIT_FETCH_PROJECT": "Fetching projetcs",
"INIT_FETCH_PROFILE": "Fetching profiles",
"INIT_FETCH_LAYOUT": "Fetching layouts",
"INIT_FETCH_CLASS": "Fetching classes",
"INIT_FETCH_STYLE": "Fetching styles",
"INIT_FETCH_SIMSTYLE": "Fetching symbol styles",
"INIT_FETCH_TEAM": "Fetching teams",
"TMSEL_DROP_PLACEHOLDER": "Select a team",
"TMSEL_MSG_ERROR": "No team has been selected",
"TMSEL_HEADER": "Your user has more than one team, please choose one to continue",
"TMSEL_BTN_CONTINUE": "Continue",
//ADMINISTRATION
//ADMIN-MENU
......@@ -552,7 +598,7 @@ window.language = {
"POPUP_DELETE": "Delete card",
// ERROR
"ERR_FILESIZE_EXCEED": "The size of the image is too high (Max: 500Kb)",
"ERR_FILESIZE_EXCEED": "The size of the image is too high (Max: 5Mb)",
"ERR_DUPLICATE_RECORD": "Duplicate record found",
"ERR_UPLOAD_SYMBOL": "Error in image or word",
......
This diff is collapsed.
......@@ -2,7 +2,7 @@
position:fixed !important;
bottom:0px;
width:100%;
max-height: 400px;
max-height: 30%;
overflow: auto;
}
......@@ -26,34 +26,39 @@
}
/* Paddding Card Content Image */
.imgpadding0 {
padding: 0em !important;
}
.imgpadding1 {
padding: 1em !important;
padding: 0.2em !important;
}
.imgpadding2 {
padding: 2em !important;
padding: 0.5em !important;
}
.imgpadding3 {
padding: 3em !important;
padding: 0.7em !important;
}
.imgpadding4 {
padding: 4em !important;
padding: 1em !important;
}
.imgpadding5 {
padding: 5em !important;
}
.imgpadding6 {
padding: 6em !important;
padding: 2em !important;
}
.ui.disabled.input {
opacity: 1 !important;
}
/* Padding input card */
.ui.card > div > div > input {
padding: 0px !important;
}
/* Font Size Style */
.uppercaseInput > input {
text-transform: uppercase;
......
import React, { Component } from 'react'
import { HashRouter, Route, Redirect } from 'react-router-dom'
import RootComponent from './RootComponent'
import BasicProject from './BasicProject'
import LayoutExport from './LayoutExport'
import Project from './Project'
import Login from './Login'
import RootComponent from './containers/homepage/RootComponent'
import BasicProject from './containers/BasicProject'
import LayoutExport from './containers/typo/LayoutExport'
import Project from './containers/project/Project'
import Admin from './administration/Administration'
import Login from './containers/Login'
import InitProgress from './containers/InitProgress'
import SelectTeam from './containers/SelectTeam'
// Import CSS files
import './css/grid_styles.css'
......@@ -14,13 +16,8 @@ import './css/react-draft-wysiwyg.css'
class App extends Component {
login(token) {
sessionStorage.setItem('jwt', token)
}
isLogged(Component) {
let jwt = sessionStorage.getItem('jwt')
console.log(Date() + jwt);
return !jwt ? (
<Redirect to="/login"/>
) : (
......@@ -39,10 +36,10 @@ class App extends Component {
<Route path="/basic/:mode?/:projectid?/:chapterid?" render={this.isLogged.bind(this, BasicProject)} />
<Route path="/project/:projectid?" render={this.isLogged.bind(this, Project)} />
<Route path="/layout/:mode?/:projectid?/:chapterid?" render={this.isLogged.bind(this, LayoutExport)} />
<Route path="/login" render={() => (
<Login checkLogin={this.login} />
)}/>
<Route path="/login" render={() => (<Login />)}/>
<Route path="/administration" render={this.isLogged.bind(this, Admin)} />
<Route path="/init" render={this.isLogged.bind(this, InitProgress)} />
<Route path="/teamselect" render={this.isLogged.bind(this, SelectTeam)} />
</div>
</HashRouter>
)
......
This diff is collapsed.
This diff is collapsed.
......@@ -3,18 +3,13 @@ import { Button, Segment, Dropdown } from 'semantic-ui-react'
import { translate, Trans } from 'react-i18next'
class LanguageSwitcher extends Component {
constructor(props) {
super(props)
this.state = {
}
}
render() {
const { t, i18n } = this.props
const changeLanguage = (lng) => {
i18n.changeLanguage(lng);
}
if (this.props.type === 'dropdown') {
return (
<Dropdown item text={t("HOME_NAVBAR_LANGUAGE")}>
......@@ -25,6 +20,7 @@ class LanguageSwitcher extends Component {
</Dropdown>
)
}
return (
<Segment basic>
<Button onClick={() => changeLanguage('it')}>Italiano</Button>
......
import React, { Component } from 'react'
import { Segment, Loader } from 'semantic-ui-react'
import { Rnd } from 'react-rnd'
import CardLayout from './CardLayout'
import CardLayout from './components/CardLayout'
import { translate, Trans } from 'react-i18next'
import { withApolloFetch } from './withApolloFetch'
import { withRouter } from 'react-router-dom'
......
import React, { Component } from 'react'
import { Link } from 'react-router-dom'
import { Button, Menu, Card, Confirm, Loader, Icon } from 'semantic-ui-react'
import { withApolloFetch } from './withApolloFetch'
import { translate, Trans } from 'react-i18next'
import { withRouter } from 'react-router-dom'
import { withCurrentProject } from './withCurrentProject'
import { withCurrentUser } from './withCurrentUser'
import NewProfileForm from './NewProfileForm'
import NewChapterForm from './NewChapterForm'
class Project extends Component {
constructor(props) {
super(props)
this.state= {
openConfirm: false,
deleteChaptId: 0,
chapters: [{}],
fetchFinished: false
}
}
componentWillMount() {
let currentProjectId = this.props.match.params.projectid
let query = `
query currentChapthers {
chapters(caa_project_id: ${currentProjectId}) {
data {
id
chapt_title
chapt_user_block
}
}
}
`
let self = this
this.props.apolloFetch({ query })
.then((data) => {
self.setState({chapters: data.data.chapters.data, fetchFinished: true})
})
}
handleOpenConfirm(id, event) {
this.setState({openConfirm: true, deleteChaptId: id})
}
handleCancel() {
this.setState({openConfirm: false})
}
handleConfirm() {
this.setState({openConfirm: false})
this.deleteChapter()
}
createNewChapter(title) {
let currentProjectId = this.props.match.params.projectid
let escapedTitle = this.escapeQuotes(title)
let query = `
mutation NewChapter {
createCaaChapter(caa_project_id: ${currentProjectId},
chapt_title: "${escapedTitle}",
chapt_content: "",
chapt_user_block: 0) {
id
}
}
`
this.props.apolloFetch({ query })
.then((data) => {
this.componentWillMount()
})
}
deleteChapter(id, event) {
let query = `
mutation DeleteChapter {
deleteCaaChapter(id: ${this.state.deleteChaptId}) {
id
}
}
`
this.props.apolloFetch({ query })
.then((data) => {
this.componentWillMount()
})
.catch((error) => {
console.log(error);
})
}
updateProjectProfile(data) {
let proj_profile = this.escapeQuotes(data)
let proj_name = this.escapeQuotes(this.props.project.proj_name)
let proj_note = this.escapeQuotes(this.props.project.proj_note)
let query = `
mutation updateProject {
updateCaaProject(id: ${this.props.project.id},
proj_name: "${proj_name}",
proj_owner: ${this.props.project.proj_owner},
proj_share: ${this.props.project.proj_share},
proj_profile: "${proj_profile}",
proj_blocked: ${this.props.project.proj_blocked},
proj_note: "${proj_note}"){
id
}
}
`
this.props.apolloFetch({ query })
.then((data) => {
this.componentWillMount()
})
.catch((error) => {
console.log(error);
})
}
// Forza l'unlock del capitolo se si è il proprietario o l'admin
forceUnlockChapter(id, event) {
let query = `
mutation BlockChapter {
updateCaaChapter(id: ${id}, chapt_user_block: 0) {
id
}
}
`
this.props.apolloFetch({ query })
.then((data) => {
this.componentWillMount()
})
.catch((error) => {
console.log(error);
})
}
// Escape quotes if needed
escapeQuotes(item) {
if (typeof item === 'string' || item instanceof String) {
return item.replace(/\\([\s\S])|(")/g,"\\$1$2")
} else {
return JSON.stringify(item).replace(/\\([\s\S])|(")/g,"\\$1$2")
}
}
render() {
const { t, i18n } = this.props
let localChapters = this.state.chapters
localChapters = localChapters.map((item, index) => {
let ifBlocked = item.chapt_user_block === 0 ? false : true
let contentButton
if (ifBlocked === true && (item.chapt_user_block === this.props.user.id || this.props.user.group_id === 1)) {
ifBlocked = false
contentButton = <Button color='green'
disabled={ifBlocked}
onClick={this.forceUnlockChapter.bind(this, item.id)}
>
<Icon name='lock' /> Unlock
</Button>
} else {
contentButton = <Button color='green'
as={Link}
disabled={ifBlocked}
to={'/basic/edit/' + this.props.match.params.projectid + '/' + item.id}
>
{t("PRJ_BTN_EDIT")}
</Button>
}
return (
<Card style={{'textAlign': 'center', 'width': 'auto'}} key={index}>
<Card.Content header={'Chapt id: ' + item.id}/>
<Card.Content>
{item.chapt_title}
</Card.Content>
<Card.Content extra>
<Button.Group>
{contentButton}
<Button.Or />
<Button color='blue'
as={Link}
to={'/basic/view/' + this.props.match.params.projectid + '/' + item.id}
>
{t("PRJ_BTN_VIEW")}
</Button>
<Button.Or />
<Button color='red'
disabled={ifBlocked}
onClick={this.handleOpenConfirm.bind(this, item.id)}
>
{t("PRJ_BTN_DELETE")}
</Button>
</Button.Group>
</Card.Content>
</Card>
)
})
if (!this.state.fetchFinished) {
return (
<div>
<Loader active inline='centered' size='massive'/>
</div>
)
} else {
return (
<div>
<Menu>
<Menu.Item>
<Button color='red' as={Link} to='/home'>{t("PRJ_MNU_BACK")}</Button>
</Menu.Item>
<Menu.Item>
<NewProfileForm
className='icon-pointer'
size='big'
edit='button'
data={this.props.project.proj_profile}
updateProfile={this.updateProjectProfile.bind(this)}
/>
</Menu.Item>
</Menu>
<Card.Group>
{localChapters}
<Card style={{'textAlign': 'center'}}>
<Card.Content header={t("PRJ_LBL_NEWCHAPT")}/>
<Card.Content>
<NewChapterForm
className='icon-pointer'
name='add square'
size='huge'
createChapter={this.createNewChapter.bind(this)}
/>
</Card.Content>
<Card.Content extra>
{t("PRJ_LBL_INFO")}
</Card.Content>
</Card>
</Card.Group>
<Confirm
open={this.state.openConfirm}
header={t("DELETE_CNF_H")}
content={t("DELETE_CNF_P")}
onCancel={this.handleCancel.bind(this)}
onConfirm={this.handleConfirm.bind(this)}
/>
</div>
)
}
}
}
export default withRouter(withApolloFetch(translate('translations')(withCurrentProject(withCurrentUser(Project)))))
This diff is collapsed.
......@@ -4,8 +4,7 @@ import Dropzone from 'react-dropzone'
import { translate, Trans } from 'react-i18next'
import { withApolloFetchNoAuth } from './withApolloFetchNoAuth'
import { withApolloFetch } from './withApolloFetch'
import CardLayout from './CardLayout'
import CardLayout from './components/CardLayout'
class UploadSymbol extends Component {
constructor(props) {
......@@ -199,7 +198,7 @@ class UploadSymbol extends Component {
let idclass = this.state.class
let idcateg = 0
let type_img = this.state.privatePhoto === true ? 1 : 0
let with_image = 0
let with_image = 1
let symbol_sign = data.NewName
let imgcolor = this.state.color
let idstyle = this.state.style
......@@ -244,7 +243,7 @@ class UploadSymbol extends Component {
let idclass = this.state.class
let idcateg = 0
let type_img = this.state.privatePhoto === true ? 1 : 0
let with_image = 1
let with_image = this.props.card.custom === true ? 1 : 0
let symbol_sign = this.props.card.img
let imgcolor = this.state.color
let idstyle = this.state.style
......@@ -470,7 +469,7 @@ class UploadSymbol extends Component {
accept="image/jpeg, image/png"
style={{'display': 'none'}}
onDrop={this.onDrop.bind(this)}
maxSize={500000}
maxSize={5000000}
/>
<Button onClick={() => { dropzoneRef.open() }}>
{t("UPSY_OPENDIALOG")}
......
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { Progress, Grid, List, Icon } from 'semantic-ui-react'
class InitProgressBar extends Component {
constructor(props) {
super(props)
this.state = {
user: '',
password: '',
}
}
callLogin() {
this.props.login(this.state.user, this.state.password)
}
render() {
let list
if (this.props.list && this.props.listProgress) {
let listProgress = Object.assign(this.props.listProgress)
listProgress = listProgress.map((item, index) => {
return (
<List.Item key={index}>
<List.Content>
<Icon loading={item.loading} name={item.iconName} color={item.color}/>
{item.innerString}
</List.Content>
</List.Item>
)
})
list = <List>{listProgress}</List>
}
return (
<Grid
textAlign='center'
style={{ height: '100vh', margin: 'auto' }}
verticalAlign='middle'
columns={2}
>
<Grid.Column>
<Progress percent={this.props.percent} label={this.props.label} indicating />
{list}
</Grid.Column>
</Grid>
)
}
}
InitProgressBar.propTypes = {
percent: PropTypes.number.isRequired,
label: PropTypes.string,
list: PropTypes.bool,
listProgress: PropTypes.arrayOf(PropTypes.shape({
iconName: PropTypes.string.isRequired,
loading: PropTypes.bool.isRequired,
color: PropTypes.string,
innerString: PropTypes.string.isRequired
})
),
}
export default InitProgressBar
import React, { Component } from 'react'
import { Button, Form, Segment, Grid, Message } from 'semantic-ui-react'
import { withRouter } from 'react-router-dom'
class Login extends Component {
class LoginForm extends Component {
constructor(props) {
super(props)
this.state = {
user: '',
password: '',
error: { code: 0, text: 'Fill the form to Login into the App', view: false, header: 'Welcome to SimCAA'},
disabledButton: false,
}
}
......@@ -21,37 +18,11 @@ class Login extends Component {
this.setState({password: input.value})
}
login() {
this.setState({disabledButton: true})
let data = JSON.stringify({user: this.state.user, password: this.state.password})
let url = window.env.GraphQLLogin
let xhr = new XMLHttpRequest();
let self = this
xhr.addEventListener("readystatechange", function () {
if (this.readyState === 4) {
if (this.status === 200) {
let jsonRes = JSON.parse(this.responseText)
let token = jsonRes.token
self.props.checkLogin(token)
let init = self
setTimeout(function() {
init.props.history.push('/')
}, 500)
}
if (this.status !== 200) {
let textError = JSON.parse(this.responseText)
let stringError = textError.error;
let newError = {code: this.status, text: stringError, view: true, header: 'Error Detected'}
self.setState({error: newError, disabledButton: false})
}
}
})