Lul
This commit is contained in:
@@ -6,13 +6,42 @@ import androidx.room.Index
|
|||||||
import androidx.room.PrimaryKey
|
import androidx.room.PrimaryKey
|
||||||
|
|
||||||
enum class FieldType {
|
enum class FieldType {
|
||||||
STRING,
|
// Text types
|
||||||
PRICE,
|
TEXT,
|
||||||
|
MULTILINE_TEXT,
|
||||||
|
|
||||||
|
// Number types
|
||||||
|
NUMBER,
|
||||||
|
CURRENCY,
|
||||||
|
PERCENTAGE,
|
||||||
|
|
||||||
|
// Selection types
|
||||||
DROPDOWN,
|
DROPDOWN,
|
||||||
|
AUTOCOMPLETE,
|
||||||
|
CHECKBOX,
|
||||||
|
SWITCH,
|
||||||
|
|
||||||
|
// Link types
|
||||||
URL,
|
URL,
|
||||||
|
EMAIL,
|
||||||
|
PHONE,
|
||||||
|
|
||||||
|
// Date/Time types
|
||||||
DATE,
|
DATE,
|
||||||
TIME,
|
TIME,
|
||||||
DATETIME
|
DATETIME,
|
||||||
|
DURATION,
|
||||||
|
|
||||||
|
// Media types
|
||||||
|
IMAGE,
|
||||||
|
FILE,
|
||||||
|
BARCODE,
|
||||||
|
SIGNATURE,
|
||||||
|
|
||||||
|
// Other types
|
||||||
|
RATING,
|
||||||
|
COLOR,
|
||||||
|
LOCATION
|
||||||
}
|
}
|
||||||
|
|
||||||
@Entity(
|
@Entity(
|
||||||
@@ -31,8 +60,8 @@ data class Field(
|
|||||||
@PrimaryKey val id: String,
|
@PrimaryKey val id: String,
|
||||||
val listId: String,
|
val listId: String,
|
||||||
val name: String,
|
val name: String,
|
||||||
val fieldType: String = "STRING", // STRING, PRICE, DROPDOWN
|
val fieldType: String = "TEXT",
|
||||||
val fieldOptions: String = "", // JSON string for dropdown options or currency for price
|
val fieldOptions: String = "", // JSON string for dropdown options, currency symbol, etc.
|
||||||
val order: Int,
|
val order: Int,
|
||||||
val createdAt: Long,
|
val createdAt: Long,
|
||||||
val updatedAt: Long,
|
val updatedAt: Long,
|
||||||
@@ -42,7 +71,14 @@ data class Field(
|
|||||||
return try {
|
return try {
|
||||||
FieldType.valueOf(fieldType)
|
FieldType.valueOf(fieldType)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
FieldType.STRING
|
// Handle legacy field types
|
||||||
|
when (fieldType) {
|
||||||
|
"STRING" -> FieldType.TEXT
|
||||||
|
"PRICE" -> FieldType.CURRENCY
|
||||||
|
"AMOUNT" -> FieldType.NUMBER
|
||||||
|
"SIZE" -> FieldType.TEXT
|
||||||
|
else -> FieldType.TEXT
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,10 +91,26 @@ data class Field(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun getCurrency(): String {
|
fun getCurrency(): String {
|
||||||
return if (fieldType == "PRICE" && fieldOptions.isNotBlank()) {
|
return if ((fieldType == "CURRENCY" || fieldType == "PRICE") && fieldOptions.isNotBlank()) {
|
||||||
fieldOptions
|
fieldOptions
|
||||||
} else {
|
} else {
|
||||||
"$"
|
"CHF"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getMaxRating(): Int {
|
||||||
|
return if (fieldType == "RATING" && fieldOptions.isNotBlank()) {
|
||||||
|
fieldOptions.toIntOrNull() ?: 5
|
||||||
|
} else {
|
||||||
|
5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getAutocompleteOptions(): List<String> {
|
||||||
|
return if (fieldType == "AUTOCOMPLETE" && fieldOptions.isNotBlank()) {
|
||||||
|
fieldOptions.split("|")
|
||||||
|
} else {
|
||||||
|
emptyList()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-1
@@ -57,15 +57,29 @@ class SyncRepository(context: Context) {
|
|||||||
|
|
||||||
// Log details of lists being received
|
// Log details of lists being received
|
||||||
syncResponse.lists.forEach { list ->
|
syncResponse.lists.forEach { list ->
|
||||||
Logger.d("Sync", " Inserting list: ${list.id} - ${list.name} (updated: ${list.updatedAt})")
|
Logger.d("Sync", " Received list: ${list.id} - ${list.name} (updated: ${list.updatedAt}, deleted: ${list.isDeleted})")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply server changes to local database
|
// Apply server changes to local database
|
||||||
|
Logger.d("Sync", "Inserting ${syncResponse.lists.size} lists into local database")
|
||||||
database.listDao().insertLists(syncResponse.lists)
|
database.listDao().insertLists(syncResponse.lists)
|
||||||
|
|
||||||
|
Logger.d("Sync", "Inserting ${syncResponse.fields.size} fields into local database")
|
||||||
database.fieldDao().insertFields(syncResponse.fields)
|
database.fieldDao().insertFields(syncResponse.fields)
|
||||||
|
|
||||||
|
Logger.d("Sync", "Inserting ${syncResponse.items.size} items into local database")
|
||||||
database.itemDao().insertItems(syncResponse.items)
|
database.itemDao().insertItems(syncResponse.items)
|
||||||
|
|
||||||
|
Logger.d("Sync", "Inserting ${syncResponse.itemValues.size} item values into local database")
|
||||||
database.itemValueDao().insertValues(syncResponse.itemValues)
|
database.itemValueDao().insertValues(syncResponse.itemValues)
|
||||||
|
|
||||||
|
// Verify what was actually saved
|
||||||
|
val savedLists = database.listDao().getListsUpdatedSince(0)
|
||||||
|
Logger.d("Sync", "After insert, total lists in DB: ${savedLists.size}")
|
||||||
|
savedLists.forEach { list ->
|
||||||
|
Logger.d("Sync", " DB list: ${list.id} - ${list.name} (deleted: ${list.isDeleted})")
|
||||||
|
}
|
||||||
|
|
||||||
// Update last sync timestamp
|
// Update last sync timestamp
|
||||||
setLastSyncTimestamp(syncResponse.serverTimestamp)
|
setLastSyncTimestamp(syncResponse.serverTimestamp)
|
||||||
|
|
||||||
|
|||||||
+943
-26
File diff suppressed because it is too large
Load Diff
+16
@@ -91,6 +91,22 @@ class ListDetailViewModel(
|
|||||||
updatedAt = timestamp
|
updatedAt = timestamp
|
||||||
)
|
)
|
||||||
database.fieldDao().insertField(newField)
|
database.fieldDao().insertField(newField)
|
||||||
|
|
||||||
|
// Create empty ItemValue entries for this new field for all existing items
|
||||||
|
val existingItems = _items.value
|
||||||
|
if (existingItems.isNotEmpty()) {
|
||||||
|
val newValues = existingItems.map { itemWithValues ->
|
||||||
|
ItemValue(
|
||||||
|
id = UUID.randomUUID().toString(),
|
||||||
|
itemId = itemWithValues.item.id,
|
||||||
|
fieldId = newField.id,
|
||||||
|
value = "",
|
||||||
|
updatedAt = timestamp
|
||||||
|
)
|
||||||
|
}
|
||||||
|
database.itemValueDao().insertValues(newValues)
|
||||||
|
}
|
||||||
|
|
||||||
performSync()
|
performSync()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import androidx.compose.foundation.lazy.items
|
|||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.Add
|
import androidx.compose.material.icons.filled.Add
|
||||||
import androidx.compose.material.icons.filled.Delete
|
import androidx.compose.material.icons.filled.Delete
|
||||||
|
import androidx.compose.material.icons.filled.Edit
|
||||||
import androidx.compose.material.icons.filled.List
|
import androidx.compose.material.icons.filled.List
|
||||||
import androidx.compose.material.icons.filled.Refresh
|
import androidx.compose.material.icons.filled.Refresh
|
||||||
import androidx.compose.material.icons.filled.Settings
|
import androidx.compose.material.icons.filled.Settings
|
||||||
@@ -39,6 +40,7 @@ fun ListsScreen(
|
|||||||
|
|
||||||
var showCreateDialog by remember { mutableStateOf(false) }
|
var showCreateDialog by remember { mutableStateOf(false) }
|
||||||
var listToDelete by remember { mutableStateOf<CollabList?>(null) }
|
var listToDelete by remember { mutableStateOf<CollabList?>(null) }
|
||||||
|
var listToEdit by remember { mutableStateOf<CollabList?>(null) }
|
||||||
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
topBar = {
|
topBar = {
|
||||||
@@ -94,6 +96,7 @@ fun ListsScreen(
|
|||||||
ListItem(
|
ListItem(
|
||||||
list = list,
|
list = list,
|
||||||
onListClick = { onNavigateToList(list.id) },
|
onListClick = { onNavigateToList(list.id) },
|
||||||
|
onEditClick = { listToEdit = list },
|
||||||
onDeleteClick = { listToDelete = list }
|
onDeleteClick = { listToDelete = list }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -111,6 +114,17 @@ fun ListsScreen(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
listToEdit?.let { list ->
|
||||||
|
RenameListDialog(
|
||||||
|
currentName = list.name,
|
||||||
|
onDismiss = { listToEdit = null },
|
||||||
|
onRename = { newName ->
|
||||||
|
viewModel.renameList(list.id, newName)
|
||||||
|
listToEdit = null
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
listToDelete?.let { list ->
|
listToDelete?.let { list ->
|
||||||
AlertDialog(
|
AlertDialog(
|
||||||
onDismissRequest = { listToDelete = null },
|
onDismissRequest = { listToDelete = null },
|
||||||
@@ -139,6 +153,7 @@ fun ListsScreen(
|
|||||||
fun ListItem(
|
fun ListItem(
|
||||||
list: CollabList,
|
list: CollabList,
|
||||||
onListClick: () -> Unit,
|
onListClick: () -> Unit,
|
||||||
|
onEditClick: () -> Unit,
|
||||||
onDeleteClick: () -> Unit
|
onDeleteClick: () -> Unit
|
||||||
) {
|
) {
|
||||||
Card(
|
Card(
|
||||||
@@ -165,6 +180,14 @@ fun ListItem(
|
|||||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
Row {
|
||||||
|
IconButton(onClick = onEditClick) {
|
||||||
|
Icon(
|
||||||
|
Icons.Default.Edit,
|
||||||
|
contentDescription = "Edit",
|
||||||
|
tint = MaterialTheme.colorScheme.primary
|
||||||
|
)
|
||||||
|
}
|
||||||
IconButton(onClick = onDeleteClick) {
|
IconButton(onClick = onDeleteClick) {
|
||||||
Icon(
|
Icon(
|
||||||
Icons.Default.Delete,
|
Icons.Default.Delete,
|
||||||
@@ -175,6 +198,7 @@ fun ListItem(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun CreateListDialog(
|
fun CreateListDialog(
|
||||||
@@ -210,6 +234,41 @@ fun CreateListDialog(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun RenameListDialog(
|
||||||
|
currentName: String,
|
||||||
|
onDismiss: () -> Unit,
|
||||||
|
onRename: (String) -> Unit
|
||||||
|
) {
|
||||||
|
var listName by remember { mutableStateOf(currentName) }
|
||||||
|
|
||||||
|
AlertDialog(
|
||||||
|
onDismissRequest = onDismiss,
|
||||||
|
title = { Text("Rename List") },
|
||||||
|
text = {
|
||||||
|
OutlinedTextField(
|
||||||
|
value = listName,
|
||||||
|
onValueChange = { listName = it },
|
||||||
|
label = { Text(stringResource(R.string.list_name)) },
|
||||||
|
singleLine = true
|
||||||
|
)
|
||||||
|
},
|
||||||
|
confirmButton = {
|
||||||
|
TextButton(
|
||||||
|
onClick = { if (listName.isNotBlank()) onRename(listName.trim()) },
|
||||||
|
enabled = listName.isNotBlank() && listName.trim() != currentName
|
||||||
|
) {
|
||||||
|
Text("Rename")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
dismissButton = {
|
||||||
|
TextButton(onClick = onDismiss) {
|
||||||
|
Text(stringResource(R.string.cancel))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private fun formatDate(timestamp: Long): String {
|
private fun formatDate(timestamp: Long): String {
|
||||||
val sdf = SimpleDateFormat("MMM dd, yyyy HH:mm", Locale.getDefault())
|
val sdf = SimpleDateFormat("MMM dd, yyyy HH:mm", Locale.getDefault())
|
||||||
return sdf.format(Date(timestamp))
|
return sdf.format(Date(timestamp))
|
||||||
|
|||||||
@@ -69,6 +69,23 @@ class ListsViewModel(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun renameList(listId: String, newName: String) {
|
||||||
|
viewModelScope.launch {
|
||||||
|
Logger.i("ListsViewModel", "Renaming list: $listId to $newName")
|
||||||
|
val list = database.listDao().getListById(listId)
|
||||||
|
if (list != null && newName.isNotBlank()) {
|
||||||
|
database.listDao().updateList(
|
||||||
|
list.copy(
|
||||||
|
name = newName.trim(),
|
||||||
|
updatedAt = System.currentTimeMillis()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
// Sync immediately after renaming
|
||||||
|
performSync()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun deleteList(listId: String) {
|
fun deleteList(listId: String) {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
Logger.i("ListsViewModel", "Deleting list: $listId")
|
Logger.i("ListsViewModel", "Deleting list: $listId")
|
||||||
|
|||||||
@@ -1,16 +1,57 @@
|
|||||||
Initialized native services in: C:\Users\gabri\.gradle\native
|
> Task :app:preBuild UP-TO-DATE
|
||||||
Initialized jansi services in: C:\Users\gabri\.gradle\native
|
> Task :app:preDebugBuild UP-TO-DATE
|
||||||
Received JVM installation metadata from 'C:\Programs\Java 22 JDK': {JAVA_HOME=C:\Programs\Java 22 JDK, JAVA_VERSION=22.0.1, JAVA_VENDOR=Oracle Corporation, RUNTIME_NAME=Java(TM) SE Runtime Environment, RUNTIME_VERSION=22.0.1+8-16, VM_NAME=Java HotSpot(TM) 64-Bit Server VM, VM_VERSION=22.0.1+8-16, VM_VENDOR=Oracle Corporation, OS_ARCH=amd64}
|
> Task :app:mergeDebugNativeDebugMetadata NO-SOURCE
|
||||||
Removing 0 daemon stop events from registry
|
> Task :app:checkKotlinGradlePluginConfigurationErrors
|
||||||
Starting a Gradle Daemon (subsequent builds will be faster)
|
> Task :app:checkDebugAarMetadata UP-TO-DATE
|
||||||
Starting process 'Gradle build daemon'. Working directory: C:\Users\gabri\.gradle\daemon\8.5 Command: C:\Programs\Java 22 JDK\bin\java.exe --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-opens=java.base/java.nio.charset=ALL-UNNAMED --add-opens=java.base/java.net=ALL-UNNAMED --add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED -Xmx2048m -Dfile.encoding=UTF-8 -Duser.country=GB -Duser.language=en -Duser.variant -cp C:\Users\gabri\.gradle\wrapper\dists\gradle-8.5-bin\5t9huq95ubn472n8rpzujfbqh\gradle-8.5\lib\gradle-launcher-8.5.jar -javaagent:C:\Users\gabri\.gradle\wrapper\dists\gradle-8.5-bin\5t9huq95ubn472n8rpzujfbqh\gradle-8.5\lib\agents\gradle-instrumentation-agent-8.5.jar org.gradle.launcher.daemon.bootstrap.GradleDaemon 8.5
|
> Task :app:generateDebugResValues UP-TO-DATE
|
||||||
Successfully started process 'Gradle build daemon'
|
> Task :app:mapDebugSourceSetPaths UP-TO-DATE
|
||||||
An attempt to start the daemon took 8.895 secs.
|
> Task :app:generateDebugResources UP-TO-DATE
|
||||||
The client will now receive all logging from the daemon (pid: 35040). The daemon log file: C:\Users\gabri\.gradle\daemon\8.5\daemon-35040.out.log
|
> Task :app:mergeDebugResources UP-TO-DATE
|
||||||
Starting build in new daemon [memory: 2 GiB]
|
> Task :app:packageDebugResources UP-TO-DATE
|
||||||
Using 16 worker leases.
|
> Task :app:parseDebugLocalResources UP-TO-DATE
|
||||||
Received JVM installation metadata from 'C:\Programs\Java 22 JDK': {JAVA_HOME=C:\Programs\Java 22 JDK, JAVA_VERSION=22.0.1, JAVA_VENDOR=Oracle Corporation, RUNTIME_NAME=Java(TM) SE Runtime Environment, RUNTIME_VERSION=22.0.1+8-16, VM_NAME=Java HotSpot(TM) 64-Bit Server VM, VM_VERSION=22.0.1+8-16, VM_VENDOR=Oracle Corporation, OS_ARCH=amd64}
|
> Task :app:createDebugCompatibleScreenManifests UP-TO-DATE
|
||||||
Watching the file system is configured to be enabled if available
|
> Task :app:extractDeepLinksDebug UP-TO-DATE
|
||||||
Now considering [C:\Users\gabri\VSCode Projects\CollabTable\CollabTableAndroid] as hierarchies to watch
|
> Task :app:processDebugMainManifest UP-TO-DATE
|
||||||
File system watching is active
|
> Task :app:processDebugManifest UP-TO-DATE
|
||||||
Terminate batch job (Y/N)?
|
> Task :app:processDebugManifestForPackage UP-TO-DATE
|
||||||
|
> Task :app:processDebugResources UP-TO-DATE
|
||||||
|
> Task :app:javaPreCompileDebug UP-TO-DATE
|
||||||
|
> Task :app:mergeDebugShaders UP-TO-DATE
|
||||||
|
> Task :app:compileDebugShaders NO-SOURCE
|
||||||
|
> Task :app:generateDebugAssets UP-TO-DATE
|
||||||
|
> Task :app:mergeDebugAssets UP-TO-DATE
|
||||||
|
> Task :app:compressDebugAssets UP-TO-DATE
|
||||||
|
> Task :app:desugarDebugFileDependencies UP-TO-DATE
|
||||||
|
> Task :app:checkDebugDuplicateClasses UP-TO-DATE
|
||||||
|
> Task :app:mergeExtDexDebug UP-TO-DATE
|
||||||
|
> Task :app:mergeLibDexDebug UP-TO-DATE
|
||||||
|
> Task :app:mergeDebugJniLibFolders UP-TO-DATE
|
||||||
|
> Task :app:mergeDebugNativeLibs NO-SOURCE
|
||||||
|
> Task :app:stripDebugDebugSymbols NO-SOURCE
|
||||||
|
> Task :app:validateSigningDebug UP-TO-DATE
|
||||||
|
> Task :app:writeDebugAppMetadata UP-TO-DATE
|
||||||
|
> Task :app:writeDebugSigningConfigVersions UP-TO-DATE
|
||||||
|
> Task :app:kspDebugKotlin
|
||||||
|
|
||||||
|
> Task :app:compileDebugKotlin
|
||||||
|
w: file:///C:/Users/gabri/VSCode%20Projects/CollabTable/CollabTableAndroid/app/src/main/java/com/collabtable/app/ui/screens/ListDetailScreen.kt:1336:72 Elvis operator (?:) always returns the left operand of non-nullable type String
|
||||||
|
w: file:///C:/Users/gabri/VSCode%20Projects/CollabTable/CollabTableAndroid/app/src/main/java/com/collabtable/app/ui/screens/ListDetailScreen.kt:2126:28 The expression is unused
|
||||||
|
|
||||||
|
> Task :app:compileDebugJavaWithJavac
|
||||||
|
> Task :app:dexBuilderDebug
|
||||||
|
> Task :app:mergeDebugGlobalSynthetics UP-TO-DATE
|
||||||
|
> Task :app:processDebugJavaRes UP-TO-DATE
|
||||||
|
> Task :app:mergeDebugJavaResource UP-TO-DATE
|
||||||
|
> Task :app:mergeProjectDexDebug
|
||||||
|
> Task :app:packageDebug
|
||||||
|
> Task :app:createDebugApkListingFileRedirect UP-TO-DATE
|
||||||
|
> Task :app:assembleDebug
|
||||||
|
|
||||||
|
Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0.
|
||||||
|
|
||||||
|
You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins.
|
||||||
|
|
||||||
|
For more on this, please refer to https://docs.gradle.org/8.10/userguide/command_line_interface.html#sec:command_line_warnings in the Gradle documentation.
|
||||||
|
|
||||||
|
BUILD SUCCESSFUL in 38s
|
||||||
|
36 actionable tasks: 7 executed, 29 up-to-date
|
||||||
|
|||||||
Binary file not shown.
@@ -177,13 +177,14 @@ router.post('/sync', async (req: Request, res: Response) => {
|
|||||||
|
|
||||||
transaction({ lastSyncTimestamp, lists, fields, items, itemValues });
|
transaction({ lastSyncTimestamp, lists, fields, items, itemValues });
|
||||||
|
|
||||||
// Get updates from server since last sync
|
// IMPORTANT: Get updates from server AFTER saving incoming data
|
||||||
|
// This ensures clients receive back any data they just sent (for confirmation)
|
||||||
// If lastSyncTimestamp is 0, get all data (initial sync)
|
// If lastSyncTimestamp is 0, get all data (initial sync)
|
||||||
// IMPORTANT: Include deleted items so clients can sync deletions
|
// IMPORTANT: Include deleted items so clients can sync deletions
|
||||||
let serverLists, serverFields, serverItems, serverItemValues;
|
let serverLists, serverFields, serverItems, serverItemValues;
|
||||||
|
|
||||||
if (lastSyncTimestamp === 0) {
|
if (lastSyncTimestamp === 0) {
|
||||||
// Initial sync: send all non-deleted items
|
// Initial sync: send all non-deleted items (AFTER processing incoming data)
|
||||||
serverLists = db.prepare('SELECT * FROM lists WHERE isDeleted = 0').all();
|
serverLists = db.prepare('SELECT * FROM lists WHERE isDeleted = 0').all();
|
||||||
serverFields = db.prepare('SELECT * FROM fields WHERE isDeleted = 0').all();
|
serverFields = db.prepare('SELECT * FROM fields WHERE isDeleted = 0').all();
|
||||||
serverItems = db.prepare('SELECT * FROM items WHERE isDeleted = 0').all();
|
serverItems = db.prepare('SELECT * FROM items WHERE isDeleted = 0').all();
|
||||||
|
|||||||
Reference in New Issue
Block a user