diff --git a/pydatalab/schemas/cell.json b/pydatalab/schemas/cell.json
index 94dbbb862..ec4347a65 100644
--- a/pydatalab/schemas/cell.json
+++ b/pydatalab/schemas/cell.json
@@ -215,6 +215,11 @@
"title": "Block Id",
"type": "string"
},
+ "created_at": {
+ "title": "Created At",
+ "type": "string",
+ "format": "date-time"
+ },
"item_id": {
"title": "Item Id",
"type": "string"
diff --git a/pydatalab/schemas/equipment.json b/pydatalab/schemas/equipment.json
index d8c82722a..db1965de1 100644
--- a/pydatalab/schemas/equipment.json
+++ b/pydatalab/schemas/equipment.json
@@ -179,6 +179,11 @@
"title": "Block Id",
"type": "string"
},
+ "created_at": {
+ "title": "Created At",
+ "type": "string",
+ "format": "date-time"
+ },
"item_id": {
"title": "Item Id",
"type": "string"
diff --git a/pydatalab/schemas/sample.json b/pydatalab/schemas/sample.json
index 92488c652..cb50cc6fd 100644
--- a/pydatalab/schemas/sample.json
+++ b/pydatalab/schemas/sample.json
@@ -307,6 +307,11 @@
"title": "Block Id",
"type": "string"
},
+ "created_at": {
+ "title": "Created At",
+ "type": "string",
+ "format": "date-time"
+ },
"item_id": {
"title": "Item Id",
"type": "string"
diff --git a/pydatalab/schemas/startingmaterial.json b/pydatalab/schemas/startingmaterial.json
index b51586d6b..bc70a510b 100644
--- a/pydatalab/schemas/startingmaterial.json
+++ b/pydatalab/schemas/startingmaterial.json
@@ -344,6 +344,11 @@
"title": "Block Id",
"type": "string"
},
+ "created_at": {
+ "title": "Created At",
+ "type": "string",
+ "format": "date-time"
+ },
"item_id": {
"title": "Item Id",
"type": "string"
diff --git a/pydatalab/src/pydatalab/blocks/base.py b/pydatalab/src/pydatalab/blocks/base.py
index 258afd826..35f63b2fa 100644
--- a/pydatalab/src/pydatalab/blocks/base.py
+++ b/pydatalab/src/pydatalab/blocks/base.py
@@ -1,3 +1,4 @@
+import datetime
import functools
import pprint
import random
@@ -183,6 +184,9 @@ def __init__(
**self.defaults,
}
+ if "created_at" not in self.data:
+ self.data["created_at"] = datetime.datetime.now(tz=datetime.timezone.utc)
+
# convert ObjectId file_ids to string to make handling them easier when sending to and from web
if "file_id" in self.data:
self.data["file_id"] = str(self.data["file_id"])
diff --git a/pydatalab/src/pydatalab/models/blocks.py b/pydatalab/src/pydatalab/models/blocks.py
index 9e33aec65..b0a4f169a 100644
--- a/pydatalab/src/pydatalab/models/blocks.py
+++ b/pydatalab/src/pydatalab/models/blocks.py
@@ -1,3 +1,5 @@
+import datetime
+
from pydantic import BaseModel, Field
from pydatalab.models.utils import JSON_ENCODERS, PyObjectId
@@ -17,6 +19,9 @@ class DataBlockResponse(BaseModel):
block_id: str
"""A shorthand random ID for the block."""
+ created_at: datetime.datetime | None = None
+ """When the block was created, in UTC."""
+
item_id: str | None = None
"""The item that the block is attached to, if any."""
diff --git a/pydatalab/tasks.py b/pydatalab/tasks.py
index 3ee818dff..4d8008f17 100644
--- a/pydatalab/tasks.py
+++ b/pydatalab/tasks.py
@@ -7,7 +7,6 @@
import time
import typing
-import tomlkit
from invoke import Collection, task
if typing.TYPE_CHECKING:
@@ -173,6 +172,8 @@ def install(_, dev=True):
"""
+ import tomlkit
+
plugin_cfg = PLUGINS_TOML_PATH
deps: list[str] = []
diff --git a/webapp/src/components/SampleInformation.vue b/webapp/src/components/SampleInformation.vue
index d47c8b8f1..9602ff35a 100644
--- a/webapp/src/components/SampleInformation.vue
+++ b/webapp/src/components/SampleInformation.vue
@@ -63,6 +63,10 @@