Übersetzungen Server und Client
This commit is contained in:
@@ -0,0 +1,26 @@
|
|||||||
|
import ky from 'ky'
|
||||||
|
import type { Translation } from '../../data/translation'
|
||||||
|
|
||||||
|
export const getTranslations = async (): Promise<Translation[]> => {
|
||||||
|
return ky.get(`http://localhost:8088/translations`).json<Translation[]>()
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getTranslationById = async (id: number): Promise<Translation> => {
|
||||||
|
return ky.get(`http://localhost:8088/translation/${id}`).json<Translation>()
|
||||||
|
}
|
||||||
|
|
||||||
|
export const createTranslation = async (translation: Translation): Promise<Translation> => {
|
||||||
|
return ky.post(`http://localhost:8088/translation`, { json: translation }).json<Translation>()
|
||||||
|
}
|
||||||
|
|
||||||
|
export const updateTranslation = async (translation: Translation): Promise<Translation> => {
|
||||||
|
return ky.put(`http://localhost:8088/translation`, { json: translation }).json<Translation>()
|
||||||
|
}
|
||||||
|
|
||||||
|
export const deleteTranslation = async (id: number): Promise<void> => {
|
||||||
|
return ky.delete(`http://localhost:8088/translation/${id}`).json<void>()
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getTranslationsByLanguageId = async (language_id: number): Promise<Translation[]> => {
|
||||||
|
return ky.get(`http://localhost:8088/translations/${language_id}`).json<Translation[]>()
|
||||||
|
}
|
||||||
@@ -38,7 +38,7 @@ const LanguagesTableView = ({ languages, setSelectedRow }: { languages: Language
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Paper sx={{ height: 600, width: '100%' }}>
|
<Paper sx={{ height: 600, width: '30vw', marginRight: 2 }}>
|
||||||
<DataGrid
|
<DataGrid
|
||||||
sx={{ border: 1, borderRadius: 2,
|
sx={{ border: 1, borderRadius: 2,
|
||||||
boxShadow: 2,
|
boxShadow: 2,
|
||||||
|
|||||||
@@ -1,24 +1,35 @@
|
|||||||
import Tooltip from '@mui/material/Tooltip';
|
import Tooltip from '@mui/material/Tooltip';
|
||||||
import { ExportCsv } from '@mui/x-data-grid';
|
import { ExportCsv } from '@mui/x-data-grid';
|
||||||
import type {Language} from '../data/language';
|
import * as React from 'react';
|
||||||
|
|
||||||
import { DataGrid, Toolbar, ToolbarButton} from '@mui/x-data-grid';
|
import { DataGrid, Toolbar, ToolbarButton} from '@mui/x-data-grid';
|
||||||
import Paper from '@mui/material/Paper';
|
import Paper from '@mui/material/Paper';
|
||||||
import DeleteIcon from '@mui/icons-material/Delete';
|
import DeleteIcon from '@mui/icons-material/Delete';
|
||||||
import AddIcon from '@mui/icons-material/Add';
|
import AddIcon from '@mui/icons-material/Add';
|
||||||
import FileDownloadIcon from '@mui/icons-material/FileDownload';
|
import FileDownloadIcon from '@mui/icons-material/FileDownload';
|
||||||
import {updateLanguage} from '../api/language/languages.api';
|
import {getLanguageById, updateLanguage} from '../api/language/languages.api';
|
||||||
import type { GridSelectionModel } from '@mui/x-data-grid';
|
import type { Translation } from '../data/translation';
|
||||||
import { Typography } from '@mui/material';
|
import { Typography } from '@mui/material';
|
||||||
|
import { getTranslationsByLanguageId, updateTranslation } from '../api/language/translations.api';
|
||||||
|
import type { Language } from '../data/language';
|
||||||
|
|
||||||
const TranslationsTableView = ({ selectedRow }: { selectedRow: number }) => {
|
const TranslationsTableView = ({ selectedRow }: { selectedRow: number }) => {
|
||||||
// const [languages, setLanguages] = useState<Language[]>([]);
|
const [translations, setTranslations] = React.useState<Translation[]>([]);
|
||||||
|
const [language, setLanguage] = React.useState<Language | null>(null);
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
getTranslationsByLanguageId(selectedRow).then(setTranslations);
|
||||||
|
}, [selectedRow]);
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
getLanguageById(selectedRow).then(setLanguage);
|
||||||
|
}, [selectedRow]);
|
||||||
|
|
||||||
|
|
||||||
function CustomToolbar() {
|
function CustomToolbar() {
|
||||||
return (
|
return (
|
||||||
<Toolbar>
|
<Toolbar>
|
||||||
<Typography variant="body1" component="div" sx={{ flexGrow: 1 }}>
|
<Typography variant="body1" component="div" sx={{ flexGrow: 1 }}>
|
||||||
Here you see all your available languages for translations.
|
Translations for {language?.language}.
|
||||||
</Typography>
|
</Typography>
|
||||||
<Tooltip title="Download as CSV">
|
<Tooltip title="Download as CSV">
|
||||||
<ExportCsv render={<ToolbarButton />}>
|
<ExportCsv render={<ToolbarButton />}>
|
||||||
@@ -38,11 +49,8 @@ const TranslationsTableView = ({ selectedRow }: { selectedRow: number }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Paper sx={{ height: 600, width: '100%' }}>{selectedRow}</Paper>
|
<Paper sx={{ height: 600, width: '50vw' }}>
|
||||||
</div>
|
<DataGrid
|
||||||
);
|
|
||||||
}
|
|
||||||
/*{ <DataGrid
|
|
||||||
sx={{ border: 1, borderRadius: 2,
|
sx={{ border: 1, borderRadius: 2,
|
||||||
boxShadow: 2,
|
boxShadow: 2,
|
||||||
borderColor: 'primary.main',
|
borderColor: 'primary.main',
|
||||||
@@ -56,36 +64,35 @@ const TranslationsTableView = ({ selectedRow }: { selectedRow: number }) => {
|
|||||||
rowSpacingType="margin"
|
rowSpacingType="margin"
|
||||||
initialState={{
|
initialState={{
|
||||||
sorting: {
|
sorting: {
|
||||||
sortModel: [{ field: 'language', sort: 'asc' }],
|
sortModel: [{ field: 'original', sort: 'asc' }],
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
rows={languages}
|
rows={translations}
|
||||||
columns={[
|
columns={[
|
||||||
{ field: 'id', headerName: 'ID', width: 100 ,align: 'right', headerAlign: 'right', editable: false},
|
{ field: 'id', headerName: 'ID', width: 100 ,align: 'right', headerAlign: 'right', editable: false},
|
||||||
{ field: 'locale', headerName: 'Locale', width: 200, editable: true },
|
{ field: 'original', headerName: 'Original', width: 200 , editable: true},
|
||||||
{ field: 'language', headerName: 'Language', width: 200 , editable: true},
|
{ field: 'translated', headerName: 'Translated', width: 200 , editable: true},
|
||||||
]}
|
]}
|
||||||
slots={{
|
slots={{
|
||||||
toolbar: CustomToolbar,
|
toolbar: CustomToolbar,
|
||||||
}}
|
}}
|
||||||
processRowUpdate={(updatedRow, originalRow) => {
|
processRowUpdate={(updatedRow, originalRow) => {
|
||||||
updateLanguage({id: updatedRow.id, locale: updatedRow.locale, language: updatedRow.language});
|
updateTranslation({
|
||||||
|
id: updatedRow.id,
|
||||||
|
language_id: updatedRow.language_id,
|
||||||
|
translated: updatedRow.translated,
|
||||||
|
original: updatedRow.original}
|
||||||
|
)
|
||||||
return updatedRow;
|
return updatedRow;
|
||||||
}}
|
}}
|
||||||
getRowClassName={(params) =>
|
getRowClassName={(params) =>
|
||||||
params.indexRelativeToCurrentPage % 2 === 0 ? 'even-row' : 'odd-row'
|
params.indexRelativeToCurrentPage % 2 === 0 ? 'even-row' : 'odd-row'
|
||||||
}
|
}
|
||||||
onSelectionModelChange={(newSelection) => {
|
|
||||||
const selectedRowId = newSelection[0];
|
|
||||||
const selectedRow = languages.find((row) => row.id === selectedRowId);
|
|
||||||
setSelectedRow(selectedRow ? selectedRow.id : 0);
|
|
||||||
}}
|
|
||||||
|
|
||||||
showToolbar
|
showToolbar
|
||||||
/> }
|
/>
|
||||||
</Paper>
|
</Paper>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};*/
|
};
|
||||||
|
|
||||||
export default TranslationsTableView;
|
export default TranslationsTableView;
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
export type Translation = {
|
||||||
|
id: number;
|
||||||
|
language_id: number;
|
||||||
|
original: string;
|
||||||
|
translated: string;
|
||||||
|
};
|
||||||
|
|
||||||
@@ -3,7 +3,6 @@ import LanguagesTableView from '../components/LanguagesTableView';
|
|||||||
import TranslationsTableView from '../components/TranslationsTableView';
|
import TranslationsTableView from '../components/TranslationsTableView';
|
||||||
import Box from '@mui/material/Box';
|
import Box from '@mui/material/Box';
|
||||||
import Typography from '@mui/material/Typography';
|
import Typography from '@mui/material/Typography';
|
||||||
import Grid from '@mui/material/Grid';
|
|
||||||
import type { Language } from '../data/language';
|
import type { Language } from '../data/language';
|
||||||
import { getLanguages } from '../api/language/languages.api';
|
import { getLanguages } from '../api/language/languages.api';
|
||||||
|
|
||||||
@@ -23,6 +22,7 @@ const LanguagesPage: React.FC = () => {
|
|||||||
sx={{
|
sx={{
|
||||||
display: "flex", // Arrange children in a row
|
display: "flex", // Arrange children in a row
|
||||||
flexDirection: "row",
|
flexDirection: "row",
|
||||||
|
width: "100vw", // Full width of the parent
|
||||||
p: 2, // Padding around the flex container
|
p: 2, // Padding around the flex container
|
||||||
bgcolor: "#f5f5f5"
|
bgcolor: "#f5f5f5"
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -0,0 +1,125 @@
|
|||||||
|
package controller
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"scpq-editor-server/models"
|
||||||
|
"scpq-editor-server/services"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
type TranslationsController struct {
|
||||||
|
TranslationsService *services.TranslationsService
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewTranslationsController(TranslationsService *services.TranslationsService) *TranslationsController {
|
||||||
|
return &TranslationsController{
|
||||||
|
TranslationsService: TranslationsService,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lc TranslationsController) CreateTranslation(ctx *gin.Context) {
|
||||||
|
body, err := io.ReadAll(ctx.Request.Body)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Error while reading create Translation request body", err)
|
||||||
|
ctx.AbortWithError(http.StatusInternalServerError, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var Translation models.Translation
|
||||||
|
err = json.Unmarshal(body, &Translation)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Error while unmarshaling create runner request body", err)
|
||||||
|
ctx.AbortWithError(http.StatusInternalServerError, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
response, responseErr := lc.TranslationsService.CreateTranslation(&Translation)
|
||||||
|
if responseErr != nil {
|
||||||
|
ctx.AbortWithStatusJSON(responseErr.Status, responseErr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.JSON(http.StatusOK, response)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lc TranslationsController) UpdateTranslation(ctx *gin.Context) {
|
||||||
|
body, err := io.ReadAll(ctx.Request.Body)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Error while reading update Translation request body", err)
|
||||||
|
ctx.AbortWithError(http.StatusInternalServerError, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var Translation models.Translation
|
||||||
|
err = json.Unmarshal(body, &Translation)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Error while unmarshaling update Translation request body", err)
|
||||||
|
ctx.AbortWithError(http.StatusInternalServerError, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
responseErr := lc.TranslationsService.UpdateTranslation(&Translation)
|
||||||
|
if responseErr != nil {
|
||||||
|
ctx.AbortWithStatusJSON(responseErr.Status, responseErr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.Status(http.StatusNoContent)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lc TranslationsController) DeleteTranslation(ctx *gin.Context) {
|
||||||
|
TranslationId := ctx.Param("id")
|
||||||
|
lId, err := strconv.Atoi(TranslationId)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Error TranslationId not int", err)
|
||||||
|
ctx.AbortWithError(http.StatusInternalServerError, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
responseErr := lc.TranslationsService.DeleteTranslation(lId)
|
||||||
|
if responseErr != nil {
|
||||||
|
ctx.JSON(responseErr.Status, responseErr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.Status(http.StatusNoContent)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lc TranslationsController) GetTranslation(ctx *gin.Context) {
|
||||||
|
TranslationId := ctx.Param("id")
|
||||||
|
lId, err := strconv.Atoi(TranslationId)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Error TranslationId not int", err)
|
||||||
|
ctx.AbortWithError(http.StatusInternalServerError, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
response, responseErr := lc.TranslationsService.GetTranslation(lId)
|
||||||
|
if responseErr != nil {
|
||||||
|
ctx.JSON(responseErr.Status, responseErr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.JSON(http.StatusOK, response)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lc TranslationsController) GetAllTranslations(ctx *gin.Context) {
|
||||||
|
response, responseErr := lc.TranslationsService.GetAllTranslations()
|
||||||
|
if responseErr != nil {
|
||||||
|
ctx.JSON(responseErr.Status, responseErr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.JSON(http.StatusOK, response)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lc TranslationsController) GetAllTranslationsByLanguageId(ctx *gin.Context) {
|
||||||
|
languageId := ctx.Param("languageId")
|
||||||
|
lId, err := strconv.Atoi(languageId)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Error languageId not int", err)
|
||||||
|
ctx.AbortWithError(http.StatusInternalServerError, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
response, responseErr := lc.TranslationsService.GetAllTranslationsByLanguageId(lId)
|
||||||
|
if responseErr != nil {
|
||||||
|
ctx.JSON(responseErr.Status, responseErr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.JSON(http.StatusOK, response)
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
type Translation struct {
|
||||||
|
ID int `json:"id"`
|
||||||
|
LanguageID int `json:"language_id"`
|
||||||
|
Original string `json:"original"`
|
||||||
|
Translated string `json:"translated"`
|
||||||
|
}
|
||||||
@@ -0,0 +1,254 @@
|
|||||||
|
package repositories
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"net/http"
|
||||||
|
"scpq-editor-server/models"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
type TranslationsRepository struct {
|
||||||
|
dbHandler *sql.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewTranslationsRepository(dbHandler *sql.DB) *TranslationsRepository {
|
||||||
|
return &TranslationsRepository{
|
||||||
|
dbHandler: dbHandler,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rr TranslationsRepository) CreateTranslation(Translation *models.Translation) (*models.Translation, *models.ResponseError) {
|
||||||
|
query := `INSERT INTO Translations(language_id, original, translated ) VALUES($1,$2,$3) RETURNING id`
|
||||||
|
rows, err := rr.dbHandler.Query(query, Translation.LanguageID, Translation.Original, Translation.Translated)
|
||||||
|
if err != nil {
|
||||||
|
return nil, &models.ResponseError{
|
||||||
|
Message: err.Error(),
|
||||||
|
Status: http.StatusInternalServerError,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
defer rows.Close()
|
||||||
|
var idstr string
|
||||||
|
for rows.Next() {
|
||||||
|
err := rows.Scan(&idstr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, &models.ResponseError{
|
||||||
|
Message: err.Error(),
|
||||||
|
Status: http.StatusInternalServerError,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if rows.Err() != nil {
|
||||||
|
return nil, &models.ResponseError{
|
||||||
|
Message: err.Error(),
|
||||||
|
Status: http.StatusInternalServerError,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TranslationId, err := strconv.Atoi(idstr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, &models.ResponseError{
|
||||||
|
Message: "Translation id not int",
|
||||||
|
Status: http.StatusInternalServerError,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &models.Translation{
|
||||||
|
ID: TranslationId,
|
||||||
|
LanguageID: Translation.LanguageID,
|
||||||
|
Original: Translation.Original,
|
||||||
|
Translated: Translation.Translated,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rr TranslationsRepository) UpdateTranslation(Translation *models.Translation) *models.ResponseError {
|
||||||
|
query := `UPDATE Translations SET language_id=$1, original=$2, translated=$3 WHERE id=$4`
|
||||||
|
res, err := rr.dbHandler.Exec(query, Translation.LanguageID, Translation.Original, Translation.Translated, Translation.ID)
|
||||||
|
if err != nil {
|
||||||
|
return &models.ResponseError{
|
||||||
|
Message: err.Error(),
|
||||||
|
Status: http.StatusInternalServerError,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rowsAffeced, err := res.RowsAffected()
|
||||||
|
if err != nil {
|
||||||
|
return &models.ResponseError{
|
||||||
|
Message: err.Error(),
|
||||||
|
Status: http.StatusInternalServerError,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if rowsAffeced == 0 {
|
||||||
|
return &models.ResponseError{
|
||||||
|
Message: "No Translation found with the given id",
|
||||||
|
Status: http.StatusNotFound,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func (rr TranslationsRepository) DeleteTranslation(TranslationId int) *models.ResponseError {
|
||||||
|
query := `DELETE FROM Translations WHERE id=$1`
|
||||||
|
res, err := rr.dbHandler.Exec(query, TranslationId)
|
||||||
|
if err != nil {
|
||||||
|
return &models.ResponseError{
|
||||||
|
Message: err.Error(),
|
||||||
|
Status: http.StatusInternalServerError,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rowsAffeced, err := res.RowsAffected()
|
||||||
|
if err != nil {
|
||||||
|
return &models.ResponseError{
|
||||||
|
Message: err.Error(),
|
||||||
|
Status: http.StatusInternalServerError,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if rowsAffeced == 0 {
|
||||||
|
return &models.ResponseError{
|
||||||
|
Message: "No Translation found with the given id",
|
||||||
|
Status: http.StatusNotFound,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rr TranslationsRepository) GetTranslation(TranslationId int) (*models.Translation, *models.ResponseError) {
|
||||||
|
query := `SELECT id, language_id, original, translated FROM Translations WHERE id=$1`
|
||||||
|
rows, err := rr.dbHandler.Query(query, TranslationId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, &models.ResponseError{
|
||||||
|
Message: err.Error(),
|
||||||
|
Status: http.StatusInternalServerError,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
defer rows.Close()
|
||||||
|
var idstr, language_id_str, original, translated string
|
||||||
|
for rows.Next() {
|
||||||
|
err := rows.Scan(&idstr, &language_id_str, &original, &translated)
|
||||||
|
if err != nil {
|
||||||
|
return nil, &models.ResponseError{
|
||||||
|
Message: err.Error(),
|
||||||
|
Status: http.StatusInternalServerError,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if rows.Err() != nil {
|
||||||
|
return nil, &models.ResponseError{
|
||||||
|
Message: err.Error(),
|
||||||
|
Status: http.StatusInternalServerError,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
languageId, err := strconv.Atoi(language_id_str)
|
||||||
|
if err != nil {
|
||||||
|
return nil, &models.ResponseError{
|
||||||
|
Message: "Translation id not int",
|
||||||
|
Status: http.StatusInternalServerError,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &models.Translation{
|
||||||
|
ID: TranslationId,
|
||||||
|
LanguageID: languageId,
|
||||||
|
Original: original,
|
||||||
|
Translated: translated,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rr TranslationsRepository) GetAllTranslations() ([]*models.Translation, *models.ResponseError) {
|
||||||
|
query := "SELECT id, language_id, original, translated FROM Translations"
|
||||||
|
rows, err := rr.dbHandler.Query(query)
|
||||||
|
if err != nil {
|
||||||
|
return nil, &models.ResponseError{
|
||||||
|
Message: err.Error(),
|
||||||
|
Status: http.StatusInternalServerError,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
defer rows.Close()
|
||||||
|
Translations := make([]*models.Translation, 0)
|
||||||
|
var idstr, language_id_str, original, translated string
|
||||||
|
for rows.Next() {
|
||||||
|
err := rows.Scan(&idstr, &language_id_str, &original, &translated)
|
||||||
|
if err != nil {
|
||||||
|
return nil, &models.ResponseError{
|
||||||
|
Message: err.Error(),
|
||||||
|
Status: http.StatusInternalServerError,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
id, err := strconv.Atoi(idstr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, &models.ResponseError{
|
||||||
|
Message: "Translation id not int",
|
||||||
|
Status: http.StatusInternalServerError,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
languageId, err := strconv.Atoi(language_id_str)
|
||||||
|
if err != nil {
|
||||||
|
return nil, &models.ResponseError{
|
||||||
|
Message: "Translation id not int",
|
||||||
|
Status: http.StatusInternalServerError,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Translation := &models.Translation{
|
||||||
|
ID: id,
|
||||||
|
LanguageID: languageId,
|
||||||
|
Original: original,
|
||||||
|
Translated: translated,
|
||||||
|
}
|
||||||
|
Translations = append(Translations, Translation)
|
||||||
|
|
||||||
|
}
|
||||||
|
if rows.Err() != nil {
|
||||||
|
return nil, &models.ResponseError{
|
||||||
|
Message: err.Error(),
|
||||||
|
Status: http.StatusInternalServerError,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Translations, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rr TranslationsRepository) GetAllTranslationsByLanguageID(languageId int) ([]*models.Translation, *models.ResponseError) {
|
||||||
|
query := "SELECT id, original, translated FROM Translations WHERE language_id=$1"
|
||||||
|
rows, err := rr.dbHandler.Query(query, languageId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, &models.ResponseError{
|
||||||
|
Message: err.Error(),
|
||||||
|
Status: http.StatusInternalServerError,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
defer rows.Close()
|
||||||
|
Translations := make([]*models.Translation, 0)
|
||||||
|
var idstr, original, translated string
|
||||||
|
for rows.Next() {
|
||||||
|
err := rows.Scan(&idstr, &original, &translated)
|
||||||
|
if err != nil {
|
||||||
|
return nil, &models.ResponseError{
|
||||||
|
Message: err.Error(),
|
||||||
|
Status: http.StatusInternalServerError,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
id, err := strconv.Atoi(idstr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, &models.ResponseError{
|
||||||
|
Message: "Translation id not int",
|
||||||
|
Status: http.StatusInternalServerError,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Translation := &models.Translation{
|
||||||
|
ID: id,
|
||||||
|
LanguageID: languageId,
|
||||||
|
Original: original,
|
||||||
|
Translated: translated,
|
||||||
|
}
|
||||||
|
Translations = append(Translations, Translation)
|
||||||
|
|
||||||
|
}
|
||||||
|
if rows.Err() != nil {
|
||||||
|
return nil, &models.ResponseError{
|
||||||
|
Message: err.Error(),
|
||||||
|
Status: http.StatusInternalServerError,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Translations, nil
|
||||||
|
}
|
||||||
@@ -29,18 +29,21 @@ func InitHttpServer(config *viper.Viper, dbHandler *sql.DB) HttpServer {
|
|||||||
propertygroupsRepository := repositories.NewPropertiesgroupsRepository(dbHandler)
|
propertygroupsRepository := repositories.NewPropertiesgroupsRepository(dbHandler)
|
||||||
valuetypesRepository := repositories.NewValuetypesRepository(dbHandler)
|
valuetypesRepository := repositories.NewValuetypesRepository(dbHandler)
|
||||||
valuecomplexitiesRepository := repositories.NewValuecomplexitiesRepository(dbHandler)
|
valuecomplexitiesRepository := repositories.NewValuecomplexitiesRepository(dbHandler)
|
||||||
|
translationsRepository := repositories.NewTranslationsRepository(dbHandler)
|
||||||
|
|
||||||
// service initialisation:
|
// service initialisation:
|
||||||
languagesService := services.NewLanguagesService(languagesRepository)
|
languagesService := services.NewLanguagesService(languagesRepository)
|
||||||
propertygroupsService := services.NewPropertygroupsService(propertygroupsRepository)
|
propertygroupsService := services.NewPropertygroupsService(propertygroupsRepository)
|
||||||
valuetypesService := services.NewValuetypesService(valuetypesRepository)
|
valuetypesService := services.NewValuetypesService(valuetypesRepository)
|
||||||
valuecomplexitiesService := services.NewValuecomplexitiesService(valuecomplexitiesRepository)
|
valuecomplexitiesService := services.NewValuecomplexitiesService(valuecomplexitiesRepository)
|
||||||
|
translationsService := services.NewTranslationsService(translationsRepository)
|
||||||
|
|
||||||
// controller initialisation:
|
// controller initialisation:
|
||||||
languageController := controller.NewLanguagesController(languagesService)
|
languageController := controller.NewLanguagesController(languagesService)
|
||||||
propertygroupsController := controller.NewPropertygroupsController(propertygroupsService)
|
propertygroupsController := controller.NewPropertygroupsController(propertygroupsService)
|
||||||
valuetypesController := controller.NewValuetypesController(valuetypesService)
|
valuetypesController := controller.NewValuetypesController(valuetypesService)
|
||||||
valuecomplexitiesController := controller.NewValuecomplexitiesController(valuecomplexitiesService)
|
valuecomplexitiesController := controller.NewValuecomplexitiesController(valuecomplexitiesService)
|
||||||
|
translationsController := controller.NewTranslationsController(translationsService)
|
||||||
|
|
||||||
// Service API
|
// Service API
|
||||||
router := gin.Default()
|
router := gin.Default()
|
||||||
@@ -61,6 +64,14 @@ func InitHttpServer(config *viper.Viper, dbHandler *sql.DB) HttpServer {
|
|||||||
router.GET("/propertygroup/:id", propertygroupsController.GetPropertygroup)
|
router.GET("/propertygroup/:id", propertygroupsController.GetPropertygroup)
|
||||||
router.GET("/propertygroups", propertygroupsController.GetAllPropertygroups)
|
router.GET("/propertygroups", propertygroupsController.GetAllPropertygroups)
|
||||||
|
|
||||||
|
// translation centric routing
|
||||||
|
router.POST("/translation", translationsController.CreateTranslation)
|
||||||
|
router.PUT("/translation", translationsController.UpdateTranslation)
|
||||||
|
router.DELETE("/translation/:id", translationsController.DeleteTranslation)
|
||||||
|
router.GET("/translation/:id", translationsController.GetTranslation)
|
||||||
|
router.GET("/translations", translationsController.GetAllTranslations)
|
||||||
|
router.GET("/translations/:languageId", translationsController.GetAllTranslationsByLanguageId)
|
||||||
|
|
||||||
// valuetype centric routing
|
// valuetype centric routing
|
||||||
router.GET("/valuetype/:id", valuetypesController.GetValuetype)
|
router.GET("/valuetype/:id", valuetypesController.GetValuetype)
|
||||||
router.GET("/valuetypes", valuetypesController.GetAllValuetypes)
|
router.GET("/valuetypes", valuetypesController.GetAllValuetypes)
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
package services
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"scpq-editor-server/models"
|
||||||
|
"scpq-editor-server/repositories"
|
||||||
|
)
|
||||||
|
|
||||||
|
type TranslationsService struct {
|
||||||
|
translationsRepository *repositories.TranslationsRepository
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewTranslationsService(TranslationsRepository *repositories.TranslationsRepository) *TranslationsService {
|
||||||
|
return &TranslationsService{
|
||||||
|
translationsRepository: TranslationsRepository,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ls TranslationsService) CreateTranslation(translation *models.Translation) (*models.Translation, *models.ResponseError) {
|
||||||
|
responseErr := validateTranslation(translation)
|
||||||
|
if responseErr != nil {
|
||||||
|
return nil, responseErr
|
||||||
|
}
|
||||||
|
return ls.translationsRepository.CreateTranslation(translation)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ls TranslationsService) UpdateTranslation(Translation *models.Translation) *models.ResponseError {
|
||||||
|
responseErr := validateTranslation(Translation)
|
||||||
|
if responseErr != nil {
|
||||||
|
return responseErr
|
||||||
|
}
|
||||||
|
return ls.translationsRepository.UpdateTranslation(Translation)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ls TranslationsService) DeleteTranslation(TranslationId int) *models.ResponseError {
|
||||||
|
return ls.translationsRepository.DeleteTranslation(TranslationId)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ls TranslationsService) GetTranslation(TranslationId int) (*models.Translation, *models.ResponseError) {
|
||||||
|
return ls.translationsRepository.GetTranslation(TranslationId)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ls TranslationsService) GetAllTranslations() ([]*models.Translation, *models.ResponseError) {
|
||||||
|
return ls.translationsRepository.GetAllTranslations()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ls TranslationsService) GetAllTranslationsByLanguageId(languageId int) ([]*models.Translation, *models.ResponseError) {
|
||||||
|
return ls.translationsRepository.GetAllTranslationsByLanguageID(languageId)
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateTranslation(Translation *models.Translation) *models.ResponseError {
|
||||||
|
if Translation.Original == "" {
|
||||||
|
return &models.ResponseError{
|
||||||
|
Message: "Invalid Translation original",
|
||||||
|
Status: http.StatusBadRequest,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user