Add AutoCompletion, Projects and correction
parent
c5de79c00a
commit
d02ffb5e00
|
@ -40,7 +40,6 @@ dependencies {
|
||||||
implementation("org.apache.poi:poi:5.0.0")
|
implementation("org.apache.poi:poi:5.0.0")
|
||||||
implementation("org.apache.poi:poi-ooxml:5.0.0")
|
implementation("org.apache.poi:poi-ooxml:5.0.0")
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
compose.desktop {
|
compose.desktop {
|
||||||
|
|
|
@ -21,6 +21,7 @@ fun compareResults(
|
||||||
codeWords: List<String>,
|
codeWords: List<String>,
|
||||||
onBackClick: () -> Unit
|
onBackClick: () -> Unit
|
||||||
) {
|
) {
|
||||||
|
println(glossaryWords)
|
||||||
val commonWords = findCommonWords(glossaryWords, codeWords)
|
val commonWords = findCommonWords(glossaryWords, codeWords)
|
||||||
|
|
||||||
Column(
|
Column(
|
||||||
|
|
|
@ -1,16 +1,18 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
import androidx.compose.foundation.border
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
|
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||||
import androidx.compose.material.*
|
import androidx.compose.material.*
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.ArrowBack
|
import androidx.compose.material.icons.filled.ArrowBack
|
||||||
import androidx.compose.material.icons.filled.Check
|
import androidx.compose.material.icons.filled.Check
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.runtime.MutableState
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import kotlinx.serialization.encodeToString
|
import kotlinx.serialization.encodeToString
|
||||||
|
@ -18,10 +20,12 @@ import kotlinx.serialization.json.Json
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
|
|
||||||
|
var appState = AppState
|
||||||
@OptIn(ExperimentalMaterialApi::class)
|
@OptIn(ExperimentalMaterialApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun formPage(glossary: Glossary, onCancelClick: () -> Unit) {
|
fun formPage(glossary: Glossary, onCancelClick: () -> Unit) {
|
||||||
// State to track whether to show the snackbar
|
// State to track whether to show the snackbar
|
||||||
|
var appState = AppState
|
||||||
val requiredFieldsSnackbarVisibleState = remember { mutableStateOf(false) }
|
val requiredFieldsSnackbarVisibleState = remember { mutableStateOf(false) }
|
||||||
val alreadyExistSnackbarVisibleState = remember { mutableStateOf(false) }
|
val alreadyExistSnackbarVisibleState = remember { mutableStateOf(false) }
|
||||||
|
|
||||||
|
@ -83,6 +87,7 @@ fun formPage(glossary: Glossary, onCancelClick: () -> Unit) {
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
TextField(
|
TextField(
|
||||||
value = description.value,
|
value = description.value,
|
||||||
onValueChange = { description.value = it },
|
onValueChange = { description.value = it },
|
||||||
|
@ -94,16 +99,84 @@ fun formPage(glossary: Glossary, onCancelClick: () -> Unit) {
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
var expanded by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
|
val glossaryWords = loadDatasFromFile(glossary.jsonFilePath)
|
||||||
|
var contextList: List<String> = emptyList()
|
||||||
|
glossaryWords.forEach { word: Word ->
|
||||||
|
contextList = contextList + word.mainContext
|
||||||
|
}
|
||||||
|
|
||||||
|
var listToShow by remember(mainContext.value) {
|
||||||
|
mutableStateOf(contextList.filter { it.startsWith(mainContext.value, ignoreCase = true) })
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
TextField(
|
TextField(
|
||||||
value = mainContext.value,
|
value = mainContext.value,
|
||||||
onValueChange = { mainContext.value = it },
|
onValueChange = {
|
||||||
|
mainContext.value = it
|
||||||
|
expanded = true
|
||||||
|
listToShow = contextList.filter { word -> word.startsWith(mainContext.value, ignoreCase = true) }
|
||||||
|
|
||||||
|
},
|
||||||
label = { Text("Contexte principal *") },
|
label = { Text("Contexte principal *") },
|
||||||
colors = TextFieldDefaults.textFieldColors(
|
colors = TextFieldDefaults.textFieldColors(
|
||||||
focusedIndicatorColor = customRedColor,
|
focusedIndicatorColor = customRedColor,
|
||||||
unfocusedIndicatorColor = Color.Gray,
|
unfocusedIndicatorColor = Color.Gray,
|
||||||
focusedLabelColor = customRedColor
|
focusedLabelColor = customRedColor
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
)
|
)
|
||||||
|
var dropHeight = (listToShow.count() * 60 + 30)
|
||||||
|
|
||||||
|
if (dropHeight > 300){
|
||||||
|
dropHeight = 300
|
||||||
|
}
|
||||||
|
|
||||||
|
if (expanded && mainContext.value.isNotBlank() && listToShow.isNotEmpty()) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.height(dropHeight.dp)
|
||||||
|
.padding(10.dp)
|
||||||
|
.border(1.dp, Color.Black)
|
||||||
|
) {
|
||||||
|
val scrollState = rememberLazyListState()
|
||||||
|
LazyColumn(
|
||||||
|
state = scrollState,
|
||||||
|
modifier = Modifier.padding(10.dp),
|
||||||
|
verticalArrangement = Arrangement.spacedBy(10.dp)
|
||||||
|
) {
|
||||||
|
|
||||||
|
listToShow.forEach { word ->
|
||||||
|
|
||||||
|
item {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
|
||||||
|
.width(300.dp)
|
||||||
|
.clickable {
|
||||||
|
mainContext.value = word
|
||||||
|
expanded = false
|
||||||
|
}
|
||||||
|
.border(1.dp, Color.Black)
|
||||||
|
.height(50.dp)
|
||||||
|
.padding(10.dp)
|
||||||
|
.clip(MaterialTheme.shapes.medium)
|
||||||
|
|
||||||
|
|
||||||
|
) {
|
||||||
|
Text(text = word)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
TextField(
|
TextField(
|
||||||
value = secondaryContext.value,
|
value = secondaryContext.value,
|
||||||
|
@ -219,7 +292,7 @@ fun formPage(glossary: Glossary, onCancelClick: () -> Unit) {
|
||||||
backgroundColor = customRedColor,
|
backgroundColor = customRedColor,
|
||||||
contentColor = Color.White
|
contentColor = Color.White
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
Text("OK")
|
Text("OK")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -237,7 +310,7 @@ fun formPage(glossary: Glossary, onCancelClick: () -> Unit) {
|
||||||
backgroundColor = customRedColor,
|
backgroundColor = customRedColor,
|
||||||
contentColor = Color.White
|
contentColor = Color.White
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
Text("OK")
|
Text("OK")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -249,6 +322,7 @@ fun formPage(glossary: Glossary, onCancelClick: () -> Unit) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun resetFields(
|
fun resetFields(
|
||||||
name: MutableState<String>,
|
name: MutableState<String>,
|
||||||
description: MutableState<String>,
|
description: MutableState<String>,
|
||||||
|
@ -287,7 +361,7 @@ fun saveDatasInFile(filePath: String, listeWords: List<Word>) {
|
||||||
val json = Json { prettyPrint = true }
|
val json = Json { prettyPrint = true }
|
||||||
try {
|
try {
|
||||||
val content = json.encodeToString(listeWords)
|
val content = json.encodeToString(listeWords)
|
||||||
File(filePath).writeText(content)
|
File(glossaryPath + (appState.selectedProject?.name ) + "/" + filePath).writeText(content)
|
||||||
} catch (e: IOException) {
|
} catch (e: IOException) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
}
|
}
|
||||||
|
@ -295,11 +369,12 @@ fun saveDatasInFile(filePath: String, listeWords: List<Word>) {
|
||||||
|
|
||||||
fun loadDatasFromFile(filePath: String): List<Word> {
|
fun loadDatasFromFile(filePath: String): List<Word> {
|
||||||
// If file is empty, return empty list
|
// If file is empty, return empty list
|
||||||
if (!File(filePath).exists() || File(filePath).length() == 0L) {
|
|
||||||
|
if (!File(glossaryPath + (appState.selectedProject?.name ) + "/" + filePath).exists() || File(glossaryPath + (appState.selectedProject?.name ) + "/" + filePath).length() == 0L) {
|
||||||
return emptyList()
|
return emptyList()
|
||||||
}
|
}
|
||||||
return try {
|
return try {
|
||||||
val content = File(filePath).readText()
|
val content = File(glossaryPath + (appState.selectedProject?.name ) + "/" + filePath).readText()
|
||||||
Json.decodeFromString<List<Word>>(content)
|
Json.decodeFromString<List<Word>>(content)
|
||||||
} catch (e: IOException) {
|
} catch (e: IOException) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
|
|
|
@ -85,7 +85,7 @@ fun glossaryPage(
|
||||||
onClick = {
|
onClick = {
|
||||||
importedSuccessfully.value = false
|
importedSuccessfully.value = false
|
||||||
frame.dispose()
|
frame.dispose()
|
||||||
},
|
},
|
||||||
colors = ButtonDefaults.buttonColors(
|
colors = ButtonDefaults.buttonColors(
|
||||||
backgroundColor = customRedColor,
|
backgroundColor = customRedColor,
|
||||||
contentColor = Color.White
|
contentColor = Color.White
|
||||||
|
@ -95,9 +95,33 @@ fun glossaryPage(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Button(
|
if (errorImportation.value) {
|
||||||
|
AlertDialog(
|
||||||
|
onDismissRequest = { errorImportation.value = false },
|
||||||
|
title = { Text("Importation Echouée") },
|
||||||
|
text = { Text("Le fichier n'a pas pu être importé") },
|
||||||
|
confirmButton = {
|
||||||
|
Button(
|
||||||
|
onClick = {
|
||||||
|
errorImportation.value = false
|
||||||
|
frame.dispose()
|
||||||
|
},
|
||||||
|
colors = ButtonDefaults.buttonColors(
|
||||||
|
backgroundColor = customRedColor,
|
||||||
|
contentColor = Color.White
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Text("OK")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Button(
|
||||||
onClick = onExportClick,
|
onClick = onExportClick,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.width(300.dp),
|
.width(300.dp),
|
||||||
|
@ -159,6 +183,7 @@ fun glossaryPage(
|
||||||
}
|
}
|
||||||
|
|
||||||
var importedSuccessfully = mutableStateOf(false)
|
var importedSuccessfully = mutableStateOf(false)
|
||||||
|
var errorImportation = mutableStateOf(false)
|
||||||
var exportedSuccessfully = mutableStateOf(false)
|
var exportedSuccessfully = mutableStateOf(false)
|
||||||
fun selectFile(extensions: Set<String>, onFileSelected: (String) -> Unit) {
|
fun selectFile(extensions: Set<String>, onFileSelected: (String) -> Unit) {
|
||||||
|
|
||||||
|
@ -243,26 +268,31 @@ fun importCSVFile(glossary : Glossary, filePath: String) {
|
||||||
println(value)
|
println(value)
|
||||||
}
|
}
|
||||||
val mot = header.zip(values).toMap().toMutableMap()
|
val mot = header.zip(values).toMap().toMutableMap()
|
||||||
val nouveauWord = Word(
|
try {
|
||||||
name = mot["Mot"]!!,
|
val nouveauWord = Word(
|
||||||
description = mot["Description"]!!,
|
name = mot["Mot"]!!,
|
||||||
mainContext = mot["Contexte principal"]!!,
|
description = mot["Description"]!!,
|
||||||
secondaryContext = mot["Contexte 2"]!!,
|
mainContext = mot["Contexte principal"]!!,
|
||||||
relatedTo = mot["Lié à"]!!,
|
secondaryContext = mot["Contexte 2"]!!,
|
||||||
synonymous = mot["Synonyme"]!!,
|
relatedTo = mot["Lié à"]!!,
|
||||||
antonym = mot["Antonyme"]!!
|
synonymous = mot["Synonyme"]!!,
|
||||||
)
|
antonym = mot["Antonyme"]!!
|
||||||
|
)
|
||||||
|
|
||||||
if (mot["Antonyme"] == "\r") {
|
if (mot["Antonyme"] == "\r") {
|
||||||
mot["Antonyme"] = ""
|
mot["Antonyme"] = ""
|
||||||
|
}
|
||||||
|
if (mot["Mot"] == null || mot["Mot"] == "") {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!verifyRequiredFields(mot)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
addWordToGlossary(glossary.jsonFilePath, nouveauWord)
|
||||||
|
}catch(e : NullPointerException){
|
||||||
|
errorImportation.value = true
|
||||||
}
|
}
|
||||||
if (mot["Mot"] == null || mot["Mot"] == "") {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (!verifyRequiredFields(mot)) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
addWordToGlossary(glossary.jsonFilePath, nouveauWord)
|
|
||||||
}
|
}
|
||||||
importedSuccessfully.value = true
|
importedSuccessfully.value = true
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,14 +22,16 @@ enum class Language {
|
||||||
@Composable
|
@Composable
|
||||||
fun homePage(
|
fun homePage(
|
||||||
languageManager: LanguageManager,
|
languageManager: LanguageManager,
|
||||||
onGlossaryClick: () -> Unit,
|
onProjectClick: () -> Unit,
|
||||||
onCodeToVerifyClick: () -> Unit
|
onCodeToVerifyClick: () -> Unit
|
||||||
) {
|
) {
|
||||||
|
val appState = AppState
|
||||||
val noFileSnackbarVisibleState = remember { mutableStateOf(false) }
|
val noFileSnackbarVisibleState = remember { mutableStateOf(false) }
|
||||||
var isCompareClicked by remember { mutableStateOf(false) }
|
var isCompareClicked by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
var selectedGlossary by remember { mutableStateOf<Glossary?>(null) }
|
var selectedGlossary by remember { mutableStateOf<Glossary?>(null) }
|
||||||
|
|
||||||
|
|
||||||
if (!isCompareClicked && selectedGlossary == null) {
|
if (!isCompareClicked && selectedGlossary == null) {
|
||||||
// Utilisez un Box pour placer le drapeau en haut à droite
|
// Utilisez un Box pour placer le drapeau en haut à droite
|
||||||
Box(
|
Box(
|
||||||
|
@ -61,7 +63,7 @@ fun homePage(
|
||||||
horizontalArrangement = Arrangement.spacedBy(16.dp)
|
horizontalArrangement = Arrangement.spacedBy(16.dp)
|
||||||
) {
|
) {
|
||||||
Button(
|
Button(
|
||||||
onClick = onGlossaryClick,
|
onClick = onProjectClick,
|
||||||
modifier = Modifier.width(200.dp),
|
modifier = Modifier.width(200.dp),
|
||||||
colors = ButtonDefaults.buttonColors(
|
colors = ButtonDefaults.buttonColors(
|
||||||
backgroundColor = customRedColor,
|
backgroundColor = customRedColor,
|
||||||
|
@ -124,24 +126,44 @@ fun homePage(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
var selectedProject by remember { mutableStateOf<Project?>(null) }
|
||||||
|
|
||||||
if (isCompareClicked && selectedGlossary == null) {
|
|
||||||
GlossaryList(glossaries = loadGlossaries()) { glossary ->
|
if (isCompareClicked && selectedProject == null && selectedGlossary == null) {
|
||||||
selectedGlossary = glossary
|
ProjectList(
|
||||||
}
|
projects = loadProjects(),
|
||||||
|
onProjectSelected = { project ->
|
||||||
|
selectedProject = project
|
||||||
|
appState.selectedProject = selectedProject
|
||||||
|
println("selectedProject = $selectedProject")
|
||||||
|
},
|
||||||
|
onBackClick = { isCompareClicked = false; selectedGlossary = null; selectedProject = null }
|
||||||
|
)
|
||||||
|
|
||||||
|
} else if (isCompareClicked && selectedGlossary == null) {
|
||||||
|
|
||||||
|
GlossaryList(
|
||||||
|
glossaries = loadGlossaries(appState.selectedProject!!),
|
||||||
|
onGlossarySelected = { glossary ->
|
||||||
|
selectedGlossary = glossary
|
||||||
|
println("selectedGlossary = $selectedGlossary")
|
||||||
|
},
|
||||||
|
onBackClick = { isCompareClicked = false; selectedGlossary = null; selectedProject = null }
|
||||||
|
)
|
||||||
} else if (isCompareClicked) {
|
} else if (isCompareClicked) {
|
||||||
selectedGlossary?.let {
|
selectedGlossary?.let {
|
||||||
compareResults(
|
compareResults(
|
||||||
glossaryWords = loadDatasFromFile(it.jsonFilePath),
|
glossaryWords = loadDatasFromFile(it.jsonFilePath),
|
||||||
codeWords = mostUsedWordList.keys.toList(),
|
codeWords = mostUsedWordList.keys.toList(),
|
||||||
onBackClick = { isCompareClicked = false; selectedGlossary = null }
|
onBackClick = { isCompareClicked = false; selectedGlossary = null; selectedProject = null }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun GlossaryList(glossaries: List<Glossary>, onGlossarySelected: (Glossary) -> Unit) {
|
fun GlossaryList(glossaries: List<Glossary>, onGlossarySelected: (Glossary) -> Unit, onBackClick: () -> Unit) {
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier.fillMaxSize(),
|
modifier = Modifier.fillMaxSize(),
|
||||||
verticalArrangement = Arrangement.Center,
|
verticalArrangement = Arrangement.Center,
|
||||||
|
@ -190,5 +212,81 @@ fun GlossaryList(glossaries: List<Glossary>, onGlossarySelected: (Glossary) -> U
|
||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.height(6.dp))
|
Spacer(modifier = Modifier.height(6.dp))
|
||||||
}
|
}
|
||||||
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
|
||||||
|
Button(
|
||||||
|
onClick = onBackClick,
|
||||||
|
colors = androidx.compose.material.ButtonDefaults.buttonColors(
|
||||||
|
backgroundColor = customRedColor,
|
||||||
|
contentColor = Color.White
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Text("Retour")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ProjectList(projects: List<Project>, onProjectSelected: (Project) -> Unit, onBackClick: () -> Unit) {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier.fillMaxSize(),
|
||||||
|
verticalArrangement = Arrangement.Center,
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally
|
||||||
|
) {
|
||||||
|
Text("Sélectionnez un Projet", style = MaterialTheme.typography.h5)
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.height(500.dp)
|
||||||
|
.padding(10.dp)
|
||||||
|
) {
|
||||||
|
val scrollState = rememberLazyListState()
|
||||||
|
LazyColumn(
|
||||||
|
state = scrollState,
|
||||||
|
modifier = Modifier.padding(10.dp).border(1.dp, Color.Black),
|
||||||
|
verticalArrangement = Arrangement.spacedBy(10.dp)
|
||||||
|
) {
|
||||||
|
items(projects) { project: Project ->
|
||||||
|
Row(
|
||||||
|
modifier = Modifier.width(200.dp).fillMaxWidth(),
|
||||||
|
horizontalArrangement = Arrangement.SpaceBetween
|
||||||
|
) {
|
||||||
|
Button(
|
||||||
|
onClick = {
|
||||||
|
onProjectSelected(project)
|
||||||
|
},
|
||||||
|
modifier = Modifier
|
||||||
|
.width(150.dp)
|
||||||
|
.padding(10.dp, 0.dp, 0.dp, 0.dp),
|
||||||
|
colors = ButtonDefaults.buttonColors(
|
||||||
|
backgroundColor = customRedColor,
|
||||||
|
contentColor = Color.White
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Text(project.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
VerticalScrollbar(
|
||||||
|
modifier = Modifier.align(Alignment.CenterEnd).fillMaxHeight(),
|
||||||
|
adapter = rememberScrollbarAdapter(scrollState)
|
||||||
|
)
|
||||||
|
Spacer(modifier = Modifier.height(6.dp))
|
||||||
|
}
|
||||||
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
|
||||||
|
Button(
|
||||||
|
onClick = onBackClick,
|
||||||
|
colors = androidx.compose.material.ButtonDefaults.buttonColors(
|
||||||
|
backgroundColor = customRedColor,
|
||||||
|
contentColor = Color.White
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Text("Retour")
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,13 @@ import java.util.*
|
||||||
val customRedColor = Color(0xFFB70D1B)
|
val customRedColor = Color(0xFFB70D1B)
|
||||||
val currentPage = mutableStateOf("accueil")
|
val currentPage = mutableStateOf("accueil")
|
||||||
|
|
||||||
|
val glossaryPath : String = "src/main/resources/projects/"
|
||||||
|
|
||||||
|
// Classe pour stocker l'état global
|
||||||
|
object AppState {
|
||||||
|
var selectedProject: Project? = null
|
||||||
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterialApi::class)
|
@OptIn(ExperimentalMaterialApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
@Preview
|
@Preview
|
||||||
|
@ -41,21 +48,22 @@ fun app() {
|
||||||
|
|
||||||
var selectedGlossary by remember { mutableStateOf<Glossary?>(null) }
|
var selectedGlossary by remember { mutableStateOf<Glossary?>(null) }
|
||||||
|
|
||||||
|
val appState = AppState
|
||||||
|
|
||||||
val isEmptySnackbarVisibleState = remember { mutableStateOf(false) }
|
val isEmptySnackbarVisibleState = remember { mutableStateOf(false) }
|
||||||
val containsSpaceSnackbarVisibleState = remember { mutableStateOf(false) }
|
val containsSpaceSnackbarVisibleState = remember { mutableStateOf(false) }
|
||||||
val glossaryAlreadyExistsSnackbarVisibleState = remember { mutableStateOf(false) }
|
val glossaryAlreadyExistsSnackbarVisibleState = remember { mutableStateOf(false) }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//Récupérer tous les glossaires à la racine du projet et les ajouter à la liste glossaries
|
|
||||||
glossaries = loadGlossaries()
|
|
||||||
|
|
||||||
|
|
||||||
when (currentPage.value) {
|
when (currentPage.value) {
|
||||||
"accueil" -> {
|
"accueil" -> {
|
||||||
homePage(
|
homePage(
|
||||||
languageManager,
|
languageManager,
|
||||||
onGlossaryClick = { currentPage.value = "glossaires" },
|
onProjectClick = { currentPage.value = "projects" },
|
||||||
onCodeToVerifyClick = { currentPage.value = "choixLangage" },
|
onCodeToVerifyClick = { currentPage.value = "choixLangage" },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -82,6 +90,8 @@ fun app() {
|
||||||
modifier = Modifier.padding(10.dp),
|
modifier = Modifier.padding(10.dp),
|
||||||
verticalArrangement = Arrangement.spacedBy(10.dp)
|
verticalArrangement = Arrangement.spacedBy(10.dp)
|
||||||
) {
|
) {
|
||||||
|
glossaries = loadGlossaries(appState.selectedProject!!)
|
||||||
|
println(glossaries)
|
||||||
items(glossaries) { glossary ->
|
items(glossaries) { glossary ->
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier.width(200.dp).fillMaxWidth(),
|
modifier = Modifier.width(200.dp).fillMaxWidth(),
|
||||||
|
@ -106,7 +116,7 @@ fun app() {
|
||||||
onClick = {
|
onClick = {
|
||||||
// Handle delete glossary action
|
// Handle delete glossary action
|
||||||
glossaries = glossaries.filterNot { it == glossary }
|
glossaries = glossaries.filterNot { it == glossary }
|
||||||
val file = File(glossary.jsonFilePath)
|
val file = File(glossaryPath + (appState.selectedProject?.name ) + "/" + glossary.jsonFilePath)
|
||||||
file.delete()
|
file.delete()
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
|
@ -208,10 +218,10 @@ fun app() {
|
||||||
val newGlossary = Glossary(nouveauGlossaireName, "$nouveauGlossaireName.json")
|
val newGlossary = Glossary(nouveauGlossaireName, "$nouveauGlossaireName.json")
|
||||||
glossaries = glossaries + newGlossary
|
glossaries = glossaries + newGlossary
|
||||||
//create new json file
|
//create new json file
|
||||||
val newFile = File(newGlossary.jsonFilePath)
|
val newFile = File(glossaryPath + (appState.selectedProject?.name ) + "/" + newGlossary.jsonFilePath)
|
||||||
newFile.createNewFile()
|
newFile.createNewFile()
|
||||||
//update glossaries list
|
//update glossaries list
|
||||||
glossaries = loadGlossaries()
|
glossaries = loadGlossaries(appState.selectedProject!!)
|
||||||
currentPage.value = "glossaires" // Revenir à la liste des glossaires
|
currentPage.value = "glossaires" // Revenir à la liste des glossaires
|
||||||
},
|
},
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
@ -240,6 +250,18 @@ fun app() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
"projects" -> {
|
||||||
|
projectsPage(
|
||||||
|
currentPage = currentPage
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
"nouveauProjet" ->{
|
||||||
|
newProject(
|
||||||
|
currentPage = currentPage
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
"glossaireOptions" -> {
|
"glossaireOptions" -> {
|
||||||
glossaryPage(
|
glossaryPage(
|
||||||
languageManager,
|
languageManager,
|
||||||
|
@ -398,10 +420,10 @@ fun app() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun loadGlossaries(): List<Glossary> {
|
fun loadGlossaries(project: Project): List<Glossary> {
|
||||||
val glossaries = mutableListOf<Glossary>()
|
val glossaries = mutableListOf<Glossary>()
|
||||||
//Récupérer tous les fichiers json à la racine du projet
|
//Récupérer tous les fichiers json à la racine du projet
|
||||||
val glossaryFiles = File(".").listFiles { file ->
|
val glossaryFiles = File(glossaryPath + project.name).listFiles { file ->
|
||||||
file.extension == "json"
|
file.extension == "json"
|
||||||
}
|
}
|
||||||
glossaryFiles?.forEach { file ->
|
glossaryFiles?.forEach { file ->
|
||||||
|
@ -413,6 +435,7 @@ fun loadGlossaries(): List<Glossary> {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fun main() = application {
|
fun main() = application {
|
||||||
val state = rememberWindowState(
|
val state = rememberWindowState(
|
||||||
placement = WindowPlacement.Floating,
|
placement = WindowPlacement.Floating,
|
||||||
|
|
|
@ -0,0 +1,198 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.*
|
||||||
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
|
import androidx.compose.foundation.lazy.items
|
||||||
|
import androidx.compose.material.*
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.filled.Delete
|
||||||
|
import androidx.compose.runtime.*
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
data class Project(val name: String)
|
||||||
|
|
||||||
|
fun loadProjects(): List<Project> {
|
||||||
|
val projectsDirectory = File("src/main/resources/projects/")
|
||||||
|
|
||||||
|
return projectsDirectory.listFiles()?.map { Project(it.name) } ?: emptyList()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun projectsPage(
|
||||||
|
currentPage: MutableState<String>
|
||||||
|
) {
|
||||||
|
val appState = AppState
|
||||||
|
var selectedProject: Project? by remember { mutableStateOf(null) }
|
||||||
|
var projects: List<Project> by remember { mutableStateOf(loadProjects()) }
|
||||||
|
|
||||||
|
Column(
|
||||||
|
modifier = Modifier.fillMaxSize(),
|
||||||
|
verticalArrangement = Arrangement.Center,
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally
|
||||||
|
) {
|
||||||
|
Text("Sélectionnez un projet", style = MaterialTheme.typography.h5)
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
|
||||||
|
LazyColumn(
|
||||||
|
modifier = Modifier.padding(10.dp),
|
||||||
|
verticalArrangement = Arrangement.spacedBy(10.dp)
|
||||||
|
) {
|
||||||
|
items(projects, key = { project -> project.name }) { project ->
|
||||||
|
Row(
|
||||||
|
modifier = Modifier.width(200.dp).fillMaxWidth(),
|
||||||
|
horizontalArrangement = Arrangement.SpaceBetween
|
||||||
|
) {
|
||||||
|
Button(
|
||||||
|
onClick = {
|
||||||
|
appState.selectedProject = project
|
||||||
|
currentPage.value = "glossaires"
|
||||||
|
|
||||||
|
},
|
||||||
|
modifier = Modifier
|
||||||
|
.width(150.dp),
|
||||||
|
colors = ButtonDefaults.buttonColors(
|
||||||
|
backgroundColor = customRedColor,
|
||||||
|
contentColor = Color.White
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Text(project.name)
|
||||||
|
}
|
||||||
|
|
||||||
|
IconButton(
|
||||||
|
onClick = {
|
||||||
|
// Handle delete project action
|
||||||
|
projects = projects.filterNot { it.name == project.name }
|
||||||
|
println(projects)
|
||||||
|
val directory = File("src/main/resources/projects/${project.name}/")
|
||||||
|
directory.deleteRecursively()
|
||||||
|
currentPage.value = "projects"
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
Icon(imageVector = Icons.Default.Delete, contentDescription = "Delete Project")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
|
||||||
|
Button(
|
||||||
|
onClick = {
|
||||||
|
currentPage.value = "nouveauProjet"
|
||||||
|
},
|
||||||
|
modifier = Modifier
|
||||||
|
.width(300.dp),
|
||||||
|
colors = ButtonDefaults.buttonColors(
|
||||||
|
backgroundColor = customRedColor,
|
||||||
|
contentColor = Color.White
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Text("Créer un nouveau project")
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(6.dp))
|
||||||
|
|
||||||
|
Button(
|
||||||
|
onClick = {
|
||||||
|
currentPage.value = "accueil"
|
||||||
|
},
|
||||||
|
modifier = Modifier
|
||||||
|
.width(250.dp),
|
||||||
|
colors = ButtonDefaults.buttonColors(
|
||||||
|
backgroundColor = customRedColor,
|
||||||
|
contentColor = Color.White
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Text("Retour")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun mySuperCoolButton(
|
||||||
|
project: Project,
|
||||||
|
){
|
||||||
|
var projects: List<Project> = loadProjects()
|
||||||
|
|
||||||
|
IconButton(
|
||||||
|
onClick = {
|
||||||
|
// Handle delete glossary action
|
||||||
|
projects = projects.filterNot { it == project }
|
||||||
|
val directory = File("src/main/resources/projects/${project.name}/")
|
||||||
|
directory.deleteRecursively()
|
||||||
|
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
Icon(imageVector = Icons.Default.Delete, contentDescription = "Delete Project")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun newProject(
|
||||||
|
currentPage: MutableState<String>
|
||||||
|
){
|
||||||
|
var projectName by remember { mutableStateOf("") }
|
||||||
|
|
||||||
|
Column(
|
||||||
|
modifier = Modifier.fillMaxSize(),
|
||||||
|
verticalArrangement = Arrangement.Center,
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally
|
||||||
|
){
|
||||||
|
Text("Nom du projet", style = MaterialTheme.typography.h5)
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
|
||||||
|
TextField(
|
||||||
|
value = projectName,
|
||||||
|
onValueChange = { projectName = it },
|
||||||
|
label = { Text("Nom du projet") },
|
||||||
|
modifier = Modifier
|
||||||
|
.width(300.dp)
|
||||||
|
.fillMaxWidth()
|
||||||
|
)
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
|
||||||
|
Button(
|
||||||
|
onClick = {
|
||||||
|
val directory = File("src/main/resources/projects/$projectName/")
|
||||||
|
directory.mkdirs()
|
||||||
|
println("Project $projectName created")
|
||||||
|
currentPage.value = "projects"
|
||||||
|
},
|
||||||
|
modifier = Modifier
|
||||||
|
.width(300.dp),
|
||||||
|
colors = ButtonDefaults.buttonColors(
|
||||||
|
backgroundColor = customRedColor,
|
||||||
|
contentColor = Color.White
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Text("Créer")
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(6.dp))
|
||||||
|
|
||||||
|
Button(
|
||||||
|
onClick = {
|
||||||
|
currentPage.value = "projects"
|
||||||
|
},
|
||||||
|
modifier = Modifier
|
||||||
|
.width(250.dp),
|
||||||
|
colors = ButtonDefaults.buttonColors(
|
||||||
|
backgroundColor = customRedColor,
|
||||||
|
contentColor = Color.White
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Text("Retour")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue