feat: add alignment property to fields and update related database and UI handling
This commit is contained in:
+10
-2
@@ -38,7 +38,7 @@ val migration2To3 =
|
|||||||
Item::class,
|
Item::class,
|
||||||
ItemValue::class,
|
ItemValue::class,
|
||||||
],
|
],
|
||||||
version = 4,
|
version = 5,
|
||||||
exportSchema = false,
|
exportSchema = false,
|
||||||
)
|
)
|
||||||
abstract class CollabTableDatabase : RoomDatabase() {
|
abstract class CollabTableDatabase : RoomDatabase() {
|
||||||
@@ -62,7 +62,7 @@ abstract class CollabTableDatabase : RoomDatabase() {
|
|||||||
context.applicationContext,
|
context.applicationContext,
|
||||||
CollabTableDatabase::class.java,
|
CollabTableDatabase::class.java,
|
||||||
"collab_table_database",
|
"collab_table_database",
|
||||||
).addMigrations(migration1To2, migration2To3, migration3To4)
|
).addMigrations(migration1To2, migration2To3, migration3To4, migration4To5)
|
||||||
.build()
|
.build()
|
||||||
dbInstance = instance
|
dbInstance = instance
|
||||||
instance
|
instance
|
||||||
@@ -85,3 +85,11 @@ val migration3To4 =
|
|||||||
database.execSQL("CREATE INDEX IF NOT EXISTS index_items_listId_createdAt ON items(listId, createdAt)")
|
database.execSQL("CREATE INDEX IF NOT EXISTS index_items_listId_createdAt ON items(listId, createdAt)")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add alignment column to fields with default 'start'
|
||||||
|
val migration4To5 =
|
||||||
|
object : Migration(4, 5) {
|
||||||
|
override fun migrate(database: SupportSQLiteDatabase) {
|
||||||
|
database.execSQL("ALTER TABLE fields ADD COLUMN alignment TEXT NOT NULL DEFAULT 'start'")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -63,6 +63,8 @@ data class Field(
|
|||||||
val fieldType: String = "TEXT",
|
val fieldType: String = "TEXT",
|
||||||
// JSON string for dropdown options, currency symbol, etc.
|
// JSON string for dropdown options, currency symbol, etc.
|
||||||
val fieldOptions: String = "",
|
val fieldOptions: String = "",
|
||||||
|
// Content alignment for cells in this column: start | center | end
|
||||||
|
val alignment: String = "start",
|
||||||
val order: Int,
|
val order: Int,
|
||||||
val createdAt: Long,
|
val createdAt: Long,
|
||||||
val updatedAt: Long,
|
val updatedAt: Long,
|
||||||
|
|||||||
+42
-38
@@ -162,16 +162,15 @@ fun ListDetailScreen(
|
|||||||
val widthDp = (savedWidth ?: 150f).dp
|
val widthDp = (savedWidth ?: 150f).dp
|
||||||
fieldWidths[field.id] = widthDp
|
fieldWidths[field.id] = widthDp
|
||||||
}
|
}
|
||||||
// Load saved alignments for this listId
|
// Initialize alignments from fields (server/DB source of truth); fallback to prefs if missing
|
||||||
val savedAlign = prefs.getColumnAlignments(listId)
|
val savedAlign = prefs.getColumnAlignments(listId)
|
||||||
stableFields.forEach { field ->
|
stableFields.forEach { field ->
|
||||||
val a = savedAlign[field.id]?.lowercase() ?: "start"
|
val raw = (field.alignment.ifBlank { savedAlign[field.id] ?: "start" }).lowercase()
|
||||||
columnAlignments[field.id] =
|
columnAlignments[field.id] = when (raw) {
|
||||||
when (a) {
|
"center" -> "center"
|
||||||
"center" -> "center"
|
"end", "right" -> "end"
|
||||||
"end", "right" -> "end"
|
else -> "start"
|
||||||
else -> "start"
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -556,7 +555,9 @@ fun ListDetailScreen(
|
|||||||
onHeaderClick = { showManageColumnsDialog = true },
|
onHeaderClick = { showManageColumnsDialog = true },
|
||||||
alignment = columnAlignments[field.id] ?: "start",
|
alignment = columnAlignments[field.id] ?: "start",
|
||||||
onAlignmentChange = { newAlign ->
|
onAlignmentChange = { newAlign ->
|
||||||
|
// Update local state and persist via ViewModel + cache to prefs for backward-compat
|
||||||
columnAlignments[field.id] = newAlign
|
columnAlignments[field.id] = newAlign
|
||||||
|
viewModel.updateFieldAlignment(field.id, newAlign)
|
||||||
prefs.setColumnAlignments(listId, columnAlignments.toMap())
|
prefs.setColumnAlignments(listId, columnAlignments.toMap())
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@@ -609,16 +610,14 @@ fun ListDetailScreen(
|
|||||||
fields = stableFields,
|
fields = stableFields,
|
||||||
onDismiss = {
|
onDismiss = {
|
||||||
showManageColumnsDialog = false
|
showManageColumnsDialog = false
|
||||||
// Refresh alignments from preferences in case they changed while editing columns
|
// Refresh alignments from current fields (DB-backed)
|
||||||
val savedAlign = prefs.getColumnAlignments(listId)
|
|
||||||
stableFields.forEach { field ->
|
stableFields.forEach { field ->
|
||||||
val a = savedAlign[field.id]?.lowercase() ?: columnAlignments[field.id] ?: "start"
|
val a = field.alignment.lowercase().ifBlank { columnAlignments[field.id] ?: "start" }
|
||||||
columnAlignments[field.id] =
|
columnAlignments[field.id] = when (a) {
|
||||||
when (a) {
|
"center" -> "center"
|
||||||
"center" -> "center"
|
"end", "right" -> "end"
|
||||||
"end", "right" -> "end"
|
else -> "start"
|
||||||
else -> "start"
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onAddField = { name, fieldType, fieldOptions ->
|
onAddField = { name, fieldType, fieldOptions ->
|
||||||
@@ -627,6 +626,9 @@ fun ListDetailScreen(
|
|||||||
onUpdateField = { fieldId, name, fieldType, fieldOptions ->
|
onUpdateField = { fieldId, name, fieldType, fieldOptions ->
|
||||||
viewModel.updateField(fieldId, name, fieldType, fieldOptions)
|
viewModel.updateField(fieldId, name, fieldType, fieldOptions)
|
||||||
},
|
},
|
||||||
|
onUpdateAlignment = { fieldId, alignment ->
|
||||||
|
viewModel.updateFieldAlignment(fieldId, alignment)
|
||||||
|
},
|
||||||
onDeleteField = { fieldId ->
|
onDeleteField = { fieldId ->
|
||||||
viewModel.deleteField(fieldId)
|
viewModel.deleteField(fieldId)
|
||||||
},
|
},
|
||||||
@@ -1852,7 +1854,7 @@ fun AddFieldDialog(
|
|||||||
fun EditFieldDialog(
|
fun EditFieldDialog(
|
||||||
field: Field,
|
field: Field,
|
||||||
onDismiss: () -> Unit,
|
onDismiss: () -> Unit,
|
||||||
onUpdate: (String, String, String) -> Unit,
|
onUpdate: (String, String, String, String) -> Unit,
|
||||||
) {
|
) {
|
||||||
var name by remember { mutableStateOf(field.name) }
|
var name by remember { mutableStateOf(field.name) }
|
||||||
var selectedFieldType by remember { mutableStateOf(field.fieldType.uppercase()) }
|
var selectedFieldType by remember { mutableStateOf(field.fieldType.uppercase()) }
|
||||||
@@ -2082,24 +2084,6 @@ fun EditFieldDialog(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Content alignment (single-select) using a connected Material3 SegmentedButton group
|
|
||||||
Text(
|
|
||||||
text = "Content Alignment",
|
|
||||||
style = MaterialTheme.typography.titleSmall,
|
|
||||||
)
|
|
||||||
val alignmentOptions = listOf("start" to "Left", "center" to "Center", "end" to "Right")
|
|
||||||
SingleChoiceSegmentedButtonRow(modifier = Modifier.padding(top = 4.dp)) {
|
|
||||||
alignmentOptions.forEachIndexed { index, (value, label) ->
|
|
||||||
SegmentedButton(
|
|
||||||
selected = selectedAlignment == value,
|
|
||||||
onClick = { selectedAlignment = value },
|
|
||||||
shape = SegmentedButtonDefaults.itemShape(index = index, count = alignmentOptions.size),
|
|
||||||
icon = { if (selectedAlignment == value) Icon(Icons.Default.Check, contentDescription = null) },
|
|
||||||
label = { Text(label) },
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Currency-specific options
|
// Currency-specific options
|
||||||
if (selectedFieldType == "CURRENCY" || selectedFieldType == "PRICE") {
|
if (selectedFieldType == "CURRENCY" || selectedFieldType == "PRICE") {
|
||||||
OutlinedTextField(
|
OutlinedTextField(
|
||||||
@@ -2148,6 +2132,24 @@ fun EditFieldDialog(
|
|||||||
supportingText = { Text("Maximum number of stars (default: 5)") },
|
supportingText = { Text("Maximum number of stars (default: 5)") },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Content alignment (single-select) using a connected Material3 SegmentedButton group
|
||||||
|
Text(
|
||||||
|
text = "Content Alignment",
|
||||||
|
style = MaterialTheme.typography.titleSmall,
|
||||||
|
)
|
||||||
|
val alignmentOptions = listOf("start" to "Left", "center" to "Center", "end" to "Right")
|
||||||
|
SingleChoiceSegmentedButtonRow(modifier = Modifier.padding(top = 4.dp)) {
|
||||||
|
alignmentOptions.forEachIndexed { index, (value, label) ->
|
||||||
|
SegmentedButton(
|
||||||
|
selected = selectedAlignment == value,
|
||||||
|
onClick = { selectedAlignment = value },
|
||||||
|
shape = SegmentedButtonDefaults.itemShape(index = index, count = alignmentOptions.size),
|
||||||
|
icon = { if (selectedAlignment == value) Icon(Icons.Default.Check, contentDescription = null) },
|
||||||
|
label = { Text(label) },
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
confirmButton = {
|
confirmButton = {
|
||||||
@@ -2172,7 +2174,7 @@ fun EditFieldDialog(
|
|||||||
"RATING" -> currency.trim().ifBlank { "5" }
|
"RATING" -> currency.trim().ifBlank { "5" }
|
||||||
else -> ""
|
else -> ""
|
||||||
}
|
}
|
||||||
onUpdate(name.trim(), normalizedType, options)
|
onUpdate(name.trim(), normalizedType, options, selectedAlignment)
|
||||||
// Persist alignment selection for this field
|
// Persist alignment selection for this field
|
||||||
val current = prefs.getColumnAlignments(field.listId).toMutableMap()
|
val current = prefs.getColumnAlignments(field.listId).toMutableMap()
|
||||||
current[field.id] =
|
current[field.id] =
|
||||||
@@ -2847,6 +2849,7 @@ fun ManageColumnsDialog(
|
|||||||
onDismiss: () -> Unit,
|
onDismiss: () -> Unit,
|
||||||
onAddField: (String, String, String) -> Unit,
|
onAddField: (String, String, String) -> Unit,
|
||||||
onUpdateField: (String, String, String, String) -> Unit,
|
onUpdateField: (String, String, String, String) -> Unit,
|
||||||
|
onUpdateAlignment: (String, String) -> Unit,
|
||||||
onDeleteField: (String) -> Unit,
|
onDeleteField: (String) -> Unit,
|
||||||
onReorderFields: (List<Field>) -> Unit,
|
onReorderFields: (List<Field>) -> Unit,
|
||||||
) {
|
) {
|
||||||
@@ -3034,8 +3037,9 @@ fun ManageColumnsDialog(
|
|||||||
EditFieldDialog(
|
EditFieldDialog(
|
||||||
field = field,
|
field = field,
|
||||||
onDismiss = { fieldToEdit = null },
|
onDismiss = { fieldToEdit = null },
|
||||||
onUpdate = { name, fieldType, fieldOptions ->
|
onUpdate = { name, fieldType, fieldOptions, selectedAlignment ->
|
||||||
onUpdateField(field.id, name, fieldType, fieldOptions)
|
onUpdateField(field.id, name, fieldType, fieldOptions)
|
||||||
|
onUpdateAlignment(field.id, selectedAlignment)
|
||||||
fieldToEdit = null
|
fieldToEdit = null
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|||||||
+26
@@ -254,6 +254,32 @@ class ListDetailViewModel(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun updateFieldAlignment(fieldId: String, alignment: String) {
|
||||||
|
viewModelScope.launch {
|
||||||
|
val field = database.fieldDao().getFieldById(fieldId)
|
||||||
|
if (field != null) {
|
||||||
|
val ts = System.currentTimeMillis()
|
||||||
|
val normalized = when (alignment.lowercase()) {
|
||||||
|
"center" -> "center"
|
||||||
|
"end", "right" -> "end"
|
||||||
|
else -> "start"
|
||||||
|
}
|
||||||
|
database.withTransaction {
|
||||||
|
database.fieldDao().updateField(
|
||||||
|
field.copy(
|
||||||
|
alignment = normalized,
|
||||||
|
updatedAt = ts,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
database.listDao().getListById(listId)?.let { l ->
|
||||||
|
database.listDao().updateList(l.copy(updatedAt = ts))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
performSync()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun addItem() {
|
fun addItem() {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
val timestamp = System.currentTimeMillis()
|
val timestamp = System.currentTimeMillis()
|
||||||
|
|||||||
@@ -65,6 +65,8 @@ class SqliteAdapter implements DBAdapter {
|
|||||||
name TEXT NOT NULL,
|
name TEXT NOT NULL,
|
||||||
fieldType TEXT NOT NULL,
|
fieldType TEXT NOT NULL,
|
||||||
fieldOptions TEXT,
|
fieldOptions TEXT,
|
||||||
|
alignment TEXT NOT NULL DEFAULT 'start',
|
||||||
|
alignment TEXT NOT NULL DEFAULT 'start',
|
||||||
listId TEXT NOT NULL,
|
listId TEXT NOT NULL,
|
||||||
"order" INTEGER NOT NULL,
|
"order" INTEGER NOT NULL,
|
||||||
createdAt INTEGER NOT NULL,
|
createdAt INTEGER NOT NULL,
|
||||||
@@ -97,6 +99,12 @@ class SqliteAdapter implements DBAdapter {
|
|||||||
CREATE INDEX IF NOT EXISTS idx_item_values_itemId ON item_values(itemId);
|
CREATE INDEX IF NOT EXISTS idx_item_values_itemId ON item_values(itemId);
|
||||||
CREATE INDEX IF NOT EXISTS idx_item_values_fieldId ON item_values(fieldId);
|
CREATE INDEX IF NOT EXISTS idx_item_values_fieldId ON item_values(fieldId);
|
||||||
`);
|
`);
|
||||||
|
// Attempt to add alignment column if upgrading an existing DB (ignore error if exists)
|
||||||
|
try {
|
||||||
|
this.db.exec(`ALTER TABLE fields ADD COLUMN alignment TEXT NOT NULL DEFAULT 'start'`);
|
||||||
|
} catch (e) {
|
||||||
|
// Column may already exist; ignore
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async queryAll(sql: string, params: Param[] = []): Promise<any[]> {
|
async queryAll(sql: string, params: Param[] = []): Promise<any[]> {
|
||||||
@@ -166,6 +174,7 @@ class PostgresAdapter implements DBAdapter {
|
|||||||
name TEXT NOT NULL,
|
name TEXT NOT NULL,
|
||||||
fieldType TEXT NOT NULL,
|
fieldType TEXT NOT NULL,
|
||||||
fieldOptions TEXT,
|
fieldOptions TEXT,
|
||||||
|
alignment TEXT NOT NULL DEFAULT 'start',
|
||||||
listId TEXT NOT NULL,
|
listId TEXT NOT NULL,
|
||||||
"order" INTEGER NOT NULL,
|
"order" INTEGER NOT NULL,
|
||||||
createdAt BIGINT NOT NULL,
|
createdAt BIGINT NOT NULL,
|
||||||
@@ -199,6 +208,8 @@ class PostgresAdapter implements DBAdapter {
|
|||||||
await client.query(`CREATE INDEX IF NOT EXISTS idx_items_listId ON items(listId);`);
|
await client.query(`CREATE INDEX IF NOT EXISTS idx_items_listId ON items(listId);`);
|
||||||
await client.query(`CREATE INDEX IF NOT EXISTS idx_item_values_itemId ON item_values(itemId);`);
|
await client.query(`CREATE INDEX IF NOT EXISTS idx_item_values_itemId ON item_values(itemId);`);
|
||||||
await client.query(`CREATE INDEX IF NOT EXISTS idx_item_values_fieldId ON item_values(fieldId);`);
|
await client.query(`CREATE INDEX IF NOT EXISTS idx_item_values_fieldId ON item_values(fieldId);`);
|
||||||
|
// Migrate existing DBs: ensure alignment column exists
|
||||||
|
await client.query(`ALTER TABLE fields ADD COLUMN IF NOT EXISTS alignment TEXT NOT NULL DEFAULT 'start';`);
|
||||||
await client.query('COMMIT');
|
await client.query('COMMIT');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
await client.query('ROLLBACK');
|
await client.query('ROLLBACK');
|
||||||
|
|||||||
@@ -17,10 +17,10 @@ router.get('/list/:listId', async (req: Request, res: Response) => {
|
|||||||
// Create field
|
// Create field
|
||||||
router.post('/', async (req: Request, res: Response) => {
|
router.post('/', async (req: Request, res: Response) => {
|
||||||
try {
|
try {
|
||||||
const { id, name, fieldType, fieldOptions, listId, order, createdAt, updatedAt, isDeleted } = req.body;
|
const { id, name, fieldType, fieldOptions, alignment, listId, order, createdAt, updatedAt, isDeleted } = req.body;
|
||||||
await dbAdapter.execute(
|
await dbAdapter.execute(
|
||||||
'INSERT INTO fields (id, name, fieldType, fieldOptions, listId, "order", createdAt, updatedAt, isDeleted) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)',
|
'INSERT INTO fields (id, name, fieldType, fieldOptions, alignment, listId, "order", createdAt, updatedAt, isDeleted) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)',
|
||||||
[id, name, fieldType, fieldOptions, listId, order, createdAt, updatedAt, isDeleted ? 1 : 0]
|
[id, name, fieldType, fieldOptions, alignment ?? 'start', listId, order, createdAt, updatedAt, isDeleted ? 1 : 0]
|
||||||
);
|
);
|
||||||
const field = await dbAdapter.queryOne('SELECT * FROM fields WHERE id = ?', [id]);
|
const field = await dbAdapter.queryOne('SELECT * FROM fields WHERE id = ?', [id]);
|
||||||
res.status(201).json({ ...(field as any), isDeleted: !!(field as any).isDeleted });
|
res.status(201).json({ ...(field as any), isDeleted: !!(field as any).isDeleted });
|
||||||
@@ -33,10 +33,10 @@ router.post('/', async (req: Request, res: Response) => {
|
|||||||
router.put('/:id', async (req: Request, res: Response) => {
|
router.put('/:id', async (req: Request, res: Response) => {
|
||||||
try {
|
try {
|
||||||
const updatedAt = Date.now();
|
const updatedAt = Date.now();
|
||||||
const { name, fieldType, fieldOptions, order } = req.body;
|
const { name, fieldType, fieldOptions, alignment, order } = req.body;
|
||||||
const result = await dbAdapter.execute(
|
const result = await dbAdapter.execute(
|
||||||
'UPDATE fields SET name = ?, fieldType = ?, fieldOptions = ?, "order" = ?, updatedAt = ? WHERE id = ?',
|
'UPDATE fields SET name = ?, fieldType = ?, fieldOptions = ?, alignment = ?, "order" = ?, updatedAt = ? WHERE id = ?',
|
||||||
[name, fieldType, fieldOptions, order, updatedAt, req.params.id]
|
[name, fieldType, fieldOptions, alignment ?? 'start', order, updatedAt, req.params.id]
|
||||||
);
|
);
|
||||||
|
|
||||||
if (result.changes === 0) {
|
if (result.changes === 0) {
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ setInterval(() => {
|
|||||||
// Helper function to get prepared statements (lazy initialization)
|
// Helper function to get prepared statements (lazy initialization)
|
||||||
// We'll perform upserts with positional params for cross-DB portability
|
// We'll perform upserts with positional params for cross-DB portability
|
||||||
const UPSERT_LIST = 'INSERT INTO lists (id, name, createdAt, updatedAt, isDeleted) VALUES (?, ?, ?, ?, ?) ON CONFLICT(id) DO UPDATE SET name = EXCLUDED.name, updatedAt = EXCLUDED.updatedAt, isDeleted = EXCLUDED.isDeleted';
|
const UPSERT_LIST = 'INSERT INTO lists (id, name, createdAt, updatedAt, isDeleted) VALUES (?, ?, ?, ?, ?) ON CONFLICT(id) DO UPDATE SET name = EXCLUDED.name, updatedAt = EXCLUDED.updatedAt, isDeleted = EXCLUDED.isDeleted';
|
||||||
const UPSERT_FIELD = 'INSERT INTO fields (id, name, fieldType, fieldOptions, listId, "order", createdAt, updatedAt, isDeleted) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT(id) DO UPDATE SET name = EXCLUDED.name, fieldType = EXCLUDED.fieldType, fieldOptions = EXCLUDED.fieldOptions, "order" = EXCLUDED."order", updatedAt = EXCLUDED.updatedAt, isDeleted = EXCLUDED.isDeleted';
|
const UPSERT_FIELD = 'INSERT INTO fields (id, name, fieldType, fieldOptions, alignment, listId, "order", createdAt, updatedAt, isDeleted) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT(id) DO UPDATE SET name = EXCLUDED.name, fieldType = EXCLUDED.fieldType, fieldOptions = EXCLUDED.fieldOptions, alignment = EXCLUDED.alignment, "order" = EXCLUDED."order", updatedAt = EXCLUDED.updatedAt, isDeleted = EXCLUDED.isDeleted';
|
||||||
const UPSERT_ITEM = 'INSERT INTO items (id, listId, createdAt, updatedAt, isDeleted) VALUES (?, ?, ?, ?, ?) ON CONFLICT(id) DO UPDATE SET updatedAt = EXCLUDED.updatedAt, isDeleted = EXCLUDED.isDeleted';
|
const UPSERT_ITEM = 'INSERT INTO items (id, listId, createdAt, updatedAt, isDeleted) VALUES (?, ?, ?, ?, ?) ON CONFLICT(id) DO UPDATE SET updatedAt = EXCLUDED.updatedAt, isDeleted = EXCLUDED.isDeleted';
|
||||||
const UPSERT_ITEM_VALUE = 'INSERT INTO item_values (id, itemId, fieldId, value, updatedAt) VALUES (?, ?, ?, ?, ?) ON CONFLICT(id) DO UPDATE SET value = EXCLUDED.value, updatedAt = EXCLUDED.updatedAt';
|
const UPSERT_ITEM_VALUE = 'INSERT INTO item_values (id, itemId, fieldId, value, updatedAt) VALUES (?, ?, ?, ?, ?) ON CONFLICT(id) DO UPDATE SET value = EXCLUDED.value, updatedAt = EXCLUDED.updatedAt';
|
||||||
|
|
||||||
@@ -144,6 +144,7 @@ router.post('/sync', async (req: Request, res: Response) => {
|
|||||||
field.name,
|
field.name,
|
||||||
field.fieldType,
|
field.fieldType,
|
||||||
field.fieldOptions,
|
field.fieldOptions,
|
||||||
|
(field.alignment ?? 'start'),
|
||||||
field.listId,
|
field.listId,
|
||||||
field.order,
|
field.order,
|
||||||
field.createdAt,
|
field.createdAt,
|
||||||
@@ -316,6 +317,7 @@ router.post('/sync', async (req: Request, res: Response) => {
|
|||||||
name: f.name,
|
name: f.name,
|
||||||
fieldType: f.fieldType ?? f.fieldtype,
|
fieldType: f.fieldType ?? f.fieldtype,
|
||||||
fieldOptions: f.fieldOptions ?? f.fieldoptions ?? '',
|
fieldOptions: f.fieldOptions ?? f.fieldoptions ?? '',
|
||||||
|
alignment: f.alignment ?? 'start',
|
||||||
order: f.order,
|
order: f.order,
|
||||||
createdAt: toMillis(pick(f, 'createdAt', 'createdat')),
|
createdAt: toMillis(pick(f, 'createdAt', 'createdat')),
|
||||||
updatedAt: toMillis(pick(f, 'updatedAt', 'updatedat')),
|
updatedAt: toMillis(pick(f, 'updatedAt', 'updatedat')),
|
||||||
|
|||||||
Reference in New Issue
Block a user