Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
25098ae
Add call for project info v2
MarcelGeo May 18, 2026
6d321d9
Add tests for project version created
MarcelGeo May 19, 2026
581b8e7
Merge pull request #627 from MerginMaps/initial-v2-project-info-integ…
MarcelGeo May 21, 2026
9dc818e
Add a signal for soft-deleted projects
varmar05 May 22, 2026
c3b0222
Merge pull request #631 from MerginMaps/disable_maplink_for_removed_p…
MarcelGeo May 25, 2026
b034f2a
Remove header responsive slot when menu is used
MarcelGeo Jun 16, 2026
1c83a26
Add new color
MarcelGeo Jun 19, 2026
56e867c
Merge pull request #642 from MerginMaps/develop
MarcelGeo Jun 23, 2026
f533e33
Merge pull request #644 from MerginMaps/master
MarcelGeo Jun 23, 2026
959afd4
bump server version to 2026.5.0
harminius Jun 23, 2026
26be3fa
Merge pull request #645 from MerginMaps/bump_version_202650
MarcelGeo Jun 23, 2026
544b835
Add resource with pid to OTEL metrics
varmar05 Jul 1, 2026
aaedf9c
Merge pull request #648 from MerginMaps/fix_metrics_missing_pid
MarcelGeo Jul 1, 2026
6bbf245
Merge remote-tracking branch 'origin/master' into dev-r117-maps-app
MarcelGeo Jul 14, 2026
373123a
Added blue avatar
MarcelGeo Jul 17, 2026
ee7d445
Merge pull request #651 from MerginMaps/redesign-maps-flow
MarcelGeo Jul 17, 2026
f29f482
Promote purple color
MarcelGeo Jul 21, 2026
38f11bf
add avatar color
MarcelGeo Jul 22, 2026
882ed68
Merge pull request #652 from MerginMaps/dev-r117-maps-app
MarcelGeo Jul 22, 2026
c57d2e7
Merge branch 'master' into backport_master
varmar05 Jul 23, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 12 additions & 7 deletions server/mergin/otel/instrument.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,21 @@
from .config import Configuration


def setup_otel_provider():
"""
Initializes the Tracer Engine. Call this Gunicorn in post_fork or in Celery worker_process_init.
"""
resource = Resource.create(
def create_resource():
return Resource.create(
{
"service.name": Configuration.OTEL_SERVICE_NAME,
"process.pid": os.getpid(), # useful for debugging forks
"process.pid": os.getpid(),
}
)


def setup_otel_provider():
"""
Initializes the Tracer Engine. Call this Gunicorn in post_fork or in Celery worker_process_init.
"""
resource = create_resource()

sampler = ParentBased(root=TraceIdRatioBased(Configuration.OTEL_TRACES_SAMPLER_ARG))
provider = TracerProvider(resource=resource, sampler=sampler)

Expand All @@ -46,12 +50,13 @@ def setup_otel_provider():

def setup_otel_metrics():
"""Initializes the Metrics Engine. Call this in post_fork."""
resource = create_resource()
exporter = OTLPMetricExporter(
endpoint=Configuration.OTEL_EXPORTER_OTLP_ENDPOINT, insecure=True
)
reader = PeriodicExportingMetricReader(exporter)

provider = MeterProvider(metric_readers=[reader])
provider = MeterProvider(resource=resource, metric_readers=[reader])
metrics.set_meter_provider(provider)


Expand Down
4 changes: 1 addition & 3 deletions server/mergin/sync/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,7 @@ def remove(project_name):
if not project:
click.secho("ERROR: Project does not exist", fg="red", err=True)
sys.exit(1)
project.removed_at = datetime.utcnow()
project.removed_by = None
db.session.commit()
project.schedule_deletion()
click.secho("Project removed", fg="green")

@project.command()
Expand Down
11 changes: 11 additions & 0 deletions server/mergin/sync/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@

Storages = {"local": DiskStorage}
project_deleted = signal("project_deleted")
project_soft_deleted = signal("project_soft_deleted")
project_access_granted = signal("project_access_granted")
push_finished = signal("push_finished")
project_version_created = signal("project_version_created")
Expand Down Expand Up @@ -295,6 +296,16 @@ def expiration(self) -> timedelta:
initial = timedelta(days=current_app.config["DELETED_PROJECT_EXPIRATION"])
return initial - (datetime.utcnow() - self.removed_at)

def schedule_deletion(self, removed_by: int = None):
"""Schedule project for removal (soft-delete).
Sets removed_at so the project is hidden from users but kept in db
until a background job permanently deletes it.
"""
self.removed_at = datetime.utcnow()
self.removed_by = removed_by
db.session.commit()
project_soft_deleted.send(self)

def delete(self, removed_by: int = None):
"""Mark project as permanently deleted (but keep in db)
- rename (to free up the same name)
Expand Down
4 changes: 1 addition & 3 deletions server/mergin/sync/public_api_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -285,9 +285,7 @@ def delete_project(namespace, project_name): # noqa: E501
:rtype: None
"""
project = require_project(namespace, project_name, ProjectPermissions.Delete)
project.removed_at = datetime.utcnow()
project.removed_by = current_user.id
db.session.commit()
project.schedule_deletion(removed_by=current_user.id)
return NoContent, 200


Expand Down
4 changes: 1 addition & 3 deletions server/mergin/sync/public_api_v2_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,7 @@ def schedule_delete_project(id):
rest.
"""
project = require_project_by_uuid(id, ProjectPermissions.Delete)
project.removed_at = datetime.utcnow()
project.removed_by = current_user.id
db.session.commit()
project.schedule_deletion(removed_by=current_user.id)

return NoContent, 204

Expand Down
22 changes: 21 additions & 1 deletion server/mergin/tests/test_project_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
FileHistory,
PushChangeType,
ProjectFilePath,
project_soft_deleted,
)
from ..sync.storages.disk import copy_file as real_copy_file
from ..sync.files import files_changes_from_upload
Expand Down Expand Up @@ -2571,9 +2572,28 @@ def test_signals(client):
project = create_project("test-project", workspace, user)
with patch(
"mergin.sync.public_api_controller.push_finished.send"
) as push_finished_mock:
) as push_finished_mock, patch(
"mergin.sync.public_api_controller.project_version_created.send"
) as project_version_created_mock:
upload_file_to_project(project, "test.txt", client)
push_finished_mock.assert_called_once()
project_version_created_mock.assert_called_once()


def test_project_soft_delete(client):
"""project.schedule_deletion() sets removed_at/removed_by and fires project_soft_deleted signal"""
workspace = create_workspace()
user = User.query.filter_by(username="mergin").first()
project = create_project("remove-test", workspace, user)

with patch("mergin.sync.models.project_soft_deleted.send") as signal_mock:
project.schedule_deletion(removed_by=user.id)
signal_mock.assert_called_once_with(project)

assert project.removed_at is not None
assert project.removed_by == user.id
# project storage params is still present (soft delete)
assert project.storage_params is not None


def test_filepath_manipulation(client):
Expand Down
2 changes: 1 addition & 1 deletion server/mergin/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@


def get_version():
return "2026.4.0"
return "2026.5.0"
2 changes: 1 addition & 1 deletion server/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

setup(
name="mergin",
version="2026.4.0",
version="2026.5.0",
url="https://github.com/MerginMaps/mergin",
license="AGPL-3.0-only",
author="Lutra Consulting Limited",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
shape="circle"
:pt="{
root: {
class: 'font-semibold text-color-forest'
class: 'font-semibold'
}
}"
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<h1 class="headline-h3">Project details</h1>
</template>
<template #headerActions>
<slot name="action-button"></slot>
<PButton
severity="secondary"
@click="downloadArchive"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,10 @@ img {
color: map-get($colors, 'dark-gray');
}

.text-color-medium-gray {
color: map-get($colors, 'medium-gray');
}

.overflow-wrap-anywhere {
overflow-wrap: anywhere;
}
Expand Down Expand Up @@ -151,7 +155,11 @@ img {

// Font size in avatar
.p-avatar:not(.p-avatar-lg):not(.p-avatar-xl) {
font-size: 0.857rem;
font-size: 0.75rem;
}

.p-avatar-text {
color: map-get($map: $colors, $key: deep-ocean)
}

.tooltip {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ $colors: (
"sky": #A6CBF4,
"informative": #BEDAF0,
"dark-gray": #41464C,
"medium-gray": #A0A3A5
"medium-gray": #A0A3A5,
"secondary-gray": #E2E2E2
);

// Mandatory Designer Variables
Expand Down Expand Up @@ -119,5 +120,7 @@ $colors: (
--earth-color: #{map-get($colors, "earth")};
--dark-gray-color: #{map-get($colors, "dark-gray")};
--medium-gray-color: #{map-get($colors, "medium-gray")};
--secondary-gray-color: #{map-get($colors, "secondary-gray")};
--purple-color: #{map-get($colors, "purple")};
color-scheme: light;
}
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,11 @@ $progressSpinnerColorFour:$warningMessageTextColor !default;

/// Background of an avatar
/// @group misc
$avatarBg: map-get($map: $colors, $key: medium-green);
$avatarBg: map-get($map: $colors, $key: informative);

/// Text color of an avatar
/// @group misc
$avatarTextColor:$textColor;
$avatarTextColor: map-get($map: $colors, $key: deep-ocean);

/// Background of a chip
/// @group misc
Expand Down
2 changes: 1 addition & 1 deletion web-app/packages/lib/src/common/components/UserSummary.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
:size="avatarSize"
:pt="{
root: {
class: 'mr-1 text-color-forest font-semibold flex-shrink-0',
class: 'mr-1 font-semibold flex-shrink-0',
style: { borderRadius: '50%' }
}
}"
Expand Down
Loading
Loading