diff --git a/CHANGELOG.md b/CHANGELOG.md
index a4eb5da4c..0bdaab046 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,7 @@
- Tooltips to main side navigation.
- Location hash for tabs in borehole detail view.
- Language dropdown in the header.
+- Added health check endpoint for the .NET API.
### Changed
@@ -23,6 +24,7 @@
- Removed unused `IsViewer` flag from user.
- Removed unused `UserEvent` from user.
- Migrated `User` API endpoints to .NET API.
+- Migrated `Workgroup` API endpoints to .NET API.
- Use `filled` style for form components.
### Fixed
diff --git a/src/api-legacy/Dockerfile b/src/api-legacy/Dockerfile
index b283fe890..9246e6889 100644
--- a/src/api-legacy/Dockerfile
+++ b/src/api-legacy/Dockerfile
@@ -8,12 +8,12 @@ COPY . ./bms
ARG VERSION
ARG REVISION
-ENV APP_VERSION ${VERSION}
-ENV APP_REVISION ${REVISION}
+ENV APP_VERSION=${VERSION}
+ENV APP_REVISION=${REVISION}
-CMD python -u bms/main.py \
+CMD ["/bin/sh", "-c", "python -u bms/main.py \
--pg-host=${DB_HOST} \
--pg-port=${DB_PORT} \
--pg-database=${DB_DATABASE} \
--pg-user=${DB_USERNAME} \
- --pg-password=${DB_PASSWORD}
+ --pg-password=${DB_PASSWORD}"]
diff --git a/src/api-legacy/__init__.py b/src/api-legacy/__init__.py
index cbde09dff..78f5d9f9e 100644
--- a/src/api-legacy/__init__.py
+++ b/src/api-legacy/__init__.py
@@ -62,8 +62,3 @@
# User actions
from bms.v1.user.handler import UserHandler
-
-# Workgroup actions
-from bms.v1.user.workgrpup.admin import WorkgroupAdminHandler
-from bms.v1.user.workgrpup import ListWorkgroups
-from bms.v1.user.workgrpup import CreateWorkgroup
diff --git a/src/api-legacy/main.py b/src/api-legacy/main.py
index 6a1a4dcc5..aaf5f536e 100644
--- a/src/api-legacy/main.py
+++ b/src/api-legacy/main.py
@@ -88,7 +88,6 @@ async def close(application):
# user handlers
SettingHandler,
UserHandler,
- WorkgroupAdminHandler,
# Borehole handlers
BoreholeViewerHandler,
@@ -132,8 +131,6 @@ async def close(application):
# User handlers
(r'/api/v1/user', UserHandler),
- (r'/api/v1/user/workgroup/edit', WorkgroupAdminHandler),
-
# Borehole handlers
(r'/api/v1/borehole', BoreholeViewerHandler),
(r'/api/v1/borehole/edit', BoreholeProducerHandler),
diff --git a/src/api-legacy/v1/user/workgrpup/__init__.py b/src/api-legacy/v1/user/workgrpup/__init__.py
deleted file mode 100644
index 4d253e408..000000000
--- a/src/api-legacy/v1/user/workgrpup/__init__.py
+++ /dev/null
@@ -1,9 +0,0 @@
-# -*- coding: utf-8 -*-
-
-from bms.v1.user.workgrpup.create import CreateWorkgroup
-from bms.v1.user.workgrpup.delete import DeleteWorkgroup
-from bms.v1.user.workgrpup.disable import DisableWorkgroup
-from bms.v1.user.workgrpup.enable import EnableWorkgroup
-from bms.v1.user.workgrpup.list import ListWorkgroups
-from bms.v1.user.workgrpup.role import SetRole
-from bms.v1.user.workgrpup.update import UpdateWorkgroup
diff --git a/src/api-legacy/v1/user/workgrpup/admin.py b/src/api-legacy/v1/user/workgrpup/admin.py
deleted file mode 100644
index 3a0a70958..000000000
--- a/src/api-legacy/v1/user/workgrpup/admin.py
+++ /dev/null
@@ -1,75 +0,0 @@
-# -*- coding: utf-8 -*-
-from bms import (
- AuthorizationException
-)
-from bms.v1.handlers.admin import Admin
-from bms.v1.user.workgrpup import (
- CreateWorkgroup,
- DeleteWorkgroup,
- DisableWorkgroup,
- EnableWorkgroup,
- ListWorkgroups,
- CreateWorkgroup,
- SetRole,
- UpdateWorkgroup
-)
-
-
-class WorkgroupAdminHandler(Admin):
- async def execute(self, request):
-
- action = request.pop('action', None)
-
- if action in [
- 'CREATE',
- 'DISABLE',
- 'DELETE',
- 'ENABLE',
- 'LIST',
- 'SET',
- 'UPDATE'
- ]:
-
- async with self.pool.acquire() as conn:
-
- exe = None
-
- if action in [
- 'CREATE',
- 'DELETE',
- 'DISABLE',
- 'ENABLE',
- 'LIST',
- 'SET',
- 'UPDATE'
- ]:
- if self.user['admin'] is False:
- raise AuthorizationException()
-
- if action == 'LIST':
- exe = ListWorkgroups(conn)
-
- elif action == 'CREATE':
- exe = CreateWorkgroup(conn)
-
- elif action == 'SET':
- exe = SetRole(conn)
-
- elif action == 'DISABLE':
- exe = DisableWorkgroup(conn)
-
- elif action == 'ENABLE':
- exe = EnableWorkgroup(conn)
-
- elif action == 'DELETE':
- exe = DeleteWorkgroup(conn)
-
- elif action == 'UPDATE':
- exe = UpdateWorkgroup(conn)
-
- if exe is not None:
- return (
- await exe.execute(**request)
- )
-
- raise Exception("Action '%s' unknown" % action)
diff --git a/src/api-legacy/v1/user/workgrpup/create.py b/src/api-legacy/v1/user/workgrpup/create.py
deleted file mode 100644
index 828e5ad14..000000000
--- a/src/api-legacy/v1/user/workgrpup/create.py
+++ /dev/null
@@ -1,42 +0,0 @@
-# -*- coding: utf-8 -*-
-from bms import (
- DuplicateException
-)
-from bms.v1.action import Action
-
-
-class CreateWorkgroup(Action):
-
- async def execute(self, name, is_supplier = False):
- exists = await self.conn.fetchval(
- """
- SELECT EXISTS(
- SELECT 1
- FROM
- bdms.workgroups
- WHERE
- name_wgp = $1
- );
- """, name)
- if exists:
- raise DuplicateException()
-
- return {
- "id": (
- await self.conn.fetchval("""
- INSERT INTO bdms.workgroups(
- name_wgp,
- settings_wgp,
- supplier_wgp
- )
- VALUES (
- $1,
- '{}',
- $2
- )
- RETURNING id_wgp
- """,
- name, is_supplier
- )
- )
- }
diff --git a/src/api-legacy/v1/user/workgrpup/delete.py b/src/api-legacy/v1/user/workgrpup/delete.py
deleted file mode 100644
index 6c77e4232..000000000
--- a/src/api-legacy/v1/user/workgrpup/delete.py
+++ /dev/null
@@ -1,36 +0,0 @@
-# -*- coding: utf-8 -*-
-from bms.v1.action import Action
-
-
-class DeleteWorkgroup(Action):
-
- async def execute(self, id):
-
- # Check if user has done contributions
- boreholes = await self.conn.fetchval("""
- SELECT
- count(id_bho) as boreholes
-
- FROM bdms.workgroups
-
- LEFT JOIN bdms.borehole
- ON id_wgp = id_wgp_fk
-
- WHERE
- id_wgp = $1
-
- GROUP BY
- id_wgp
- """, id)
-
- if boreholes > 0:
- raise Exception(
- f"Workgroup cannot be deleted because of {boreholes} boreholes"
- )
-
- await self.conn.execute("""
- DELETE FROM bdms.workgroups
- WHERE id_wgp = $1
- """, id)
-
- return None
diff --git a/src/api-legacy/v1/user/workgrpup/disable.py b/src/api-legacy/v1/user/workgrpup/disable.py
deleted file mode 100644
index 174b01f55..000000000
--- a/src/api-legacy/v1/user/workgrpup/disable.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# -*- coding: utf-8 -*-
-from bms.v1.action import Action
-
-
-class DisableWorkgroup(Action):
-
- async def execute(self, id):
- return {
- "id": (
- await self.conn.fetchval("""
- UPDATE
- bdms.workgroups
-
- SET
- disabled_wgp = now()
-
- WHERE
- id_wgp = $1
- """,
- id
- )
- )
- }
diff --git a/src/api-legacy/v1/user/workgrpup/enable.py b/src/api-legacy/v1/user/workgrpup/enable.py
deleted file mode 100644
index cb770cf0c..000000000
--- a/src/api-legacy/v1/user/workgrpup/enable.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# -*- coding: utf-8 -*-
-from bms.v1.action import Action
-
-
-class EnableWorkgroup(Action):
-
- async def execute(self, id):
- return {
- "id": (
- await self.conn.fetchval("""
- UPDATE
- bdms.workgroups
-
- SET
- disabled_wgp = NULL
-
- WHERE
- id_wgp = $1
- """,
- id
- )
- )
- }
diff --git a/src/api-legacy/v1/user/workgrpup/list.py b/src/api-legacy/v1/user/workgrpup/list.py
deleted file mode 100644
index 47b1301ed..000000000
--- a/src/api-legacy/v1/user/workgrpup/list.py
+++ /dev/null
@@ -1,52 +0,0 @@
-# -*- coding: utf-8 -*-
-from bms.v1.action import Action
-import math
-
-
-class ListWorkgroups(Action):
-
- async def execute(self):
-
- val = await self.conn.fetchval(
- """
- SELECT
- array_to_json(
- array_agg(
- row_to_json(t)
- )
- )
- FROM (
- SELECT
- id_wgp as id,
- name_wgp as name,
- supplier_wgp as supplier,
- to_char(
- disabled_wgp,
- 'YYYY-MM-DD"T"HH24:MI:SSOF'
- ) as disabled,
- to_char(
- created_wgp,
- 'YYYY-MM-DD"T"HH24:MI:SSOF'
- ) as created,
- count(id_bho) as boreholes
-
- FROM bdms.workgroups
-
- LEFT JOIN bdms.borehole
- ON id_wgp = id_wgp_fk
-
- /*WHERE
- supplier_wgp IS FALSE*/
-
- GROUP BY
- id_wgp, name_wgp
-
- ORDER BY
- name_wgp
- ) as t
- """
- )
-
- return {
- "data": self.decode(val) if val is not None else []
- }
diff --git a/src/api-legacy/v1/user/workgrpup/role.py b/src/api-legacy/v1/user/workgrpup/role.py
deleted file mode 100644
index 6badff3ec..000000000
--- a/src/api-legacy/v1/user/workgrpup/role.py
+++ /dev/null
@@ -1,58 +0,0 @@
-# -*- coding: utf-8 -*-
-from bms.v1.action import Action
-
-
-class SetRole(Action):
-
- async def execute(
- self, user_id, workgroup_id, role_name, active = True
- ):
- id_rol = await self.conn.fetchval("""
- SELECT
- id_rol
- FROM
- bdms.roles
- WHERE
- name_rol = $1
- """, role_name)
-
- if id_rol is None:
- raise Exception(f"Not found {role_name}")
-
- if active is False:
- await self.conn.execute("""
- DELETE FROM
- bdms.users_roles
- WHERE
- id_usr_fk = $1
- AND
- id_rol_fk = $2
- AND
- id_wgp_fk = $3
- """, user_id, id_rol, workgroup_id)
-
- else:
- # Check if ROLE (role_name) already assigned
- val = await self.conn.fetchrow("""
- SELECT
- id_usr_fk,
- id_rol_fk,
- id_wgp_fk
- FROM
- bdms.users_roles
- WHERE
- id_usr_fk = $1
- AND
- id_rol_fk = $2
- AND
- id_wgp_fk = $3
- """, user_id, id_rol, workgroup_id)
-
- if val is None:
- await self.conn.execute("""
- INSERT INTO bdms.users_roles(
- id_usr_fk, id_rol_fk, id_wgp_fk)
- VALUES ($1, $2, $3);
- """, user_id, id_rol, workgroup_id)
-
- return None
diff --git a/src/api-legacy/v1/user/workgrpup/update.py b/src/api-legacy/v1/user/workgrpup/update.py
deleted file mode 100644
index ba9bc07c4..000000000
--- a/src/api-legacy/v1/user/workgrpup/update.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# -*- coding: utf-8 -*-
-from bms.v1.action import Action
-
-
-class UpdateWorkgroup(Action):
-
- async def execute(self, id, name):
- return {
- "id": (
- await self.conn.fetchval("""
- UPDATE
- bdms.workgroups
-
- SET
- name_wgp = $1
-
- WHERE
- id_wgp = $2
- """,
- name, id
- )
- )
- }
diff --git a/src/api/BDMS.csproj b/src/api/BDMS.csproj
index 4f9574205..3f6f80b9c 100644
--- a/src/api/BDMS.csproj
+++ b/src/api/BDMS.csproj
@@ -25,6 +25,7 @@
+
diff --git a/src/api/BdmsContext.cs b/src/api/BdmsContext.cs
index e700a9062..476fdb965 100644
--- a/src/api/BdmsContext.cs
+++ b/src/api/BdmsContext.cs
@@ -26,6 +26,10 @@ public class BdmsContext : DbContext
public DbSet UserWorkgroupRoles { get; set; }
public DbSet Workflows { get; set; }
public DbSet Workgroups { get; set; }
+
+ public IQueryable WorkgroupsWithIncludes => Workgroups
+ .Include(w => w.Boreholes);
+
public DbSet BoreholeFiles { get; set; }
public DbSet LithologicalDescriptions { get; set; }
public DbSet FaciesDescriptions { get; set; }
diff --git a/src/api/BdmsContextExtensions.cs b/src/api/BdmsContextExtensions.cs
index 783fce71b..dc6bd7864 100644
--- a/src/api/BdmsContextExtensions.cs
+++ b/src/api/BdmsContextExtensions.cs
@@ -45,8 +45,8 @@ public static void SeedData(this BdmsContext context)
.StrictMode(true)
.RuleFor(o => o.Id, f => workgroup_ids++)
.RuleFor(o => o.Name, f => f.Music.Genre())
- .RuleFor(o => o.Created, f => f.Date.Past().ToUniversalTime().OrNull(f, .1f))
- .RuleFor(o => o.Disabled, f => f.Date.Past().ToUniversalTime().OrNull(f, .1f))
+ .RuleFor(o => o.CreatedAt, f => f.Date.Past().ToUniversalTime().OrNull(f, .1f))
+ .RuleFor(o => o.DisabledAt, f => f.Date.Past().ToUniversalTime().OrNull(f, .1f))
.RuleFor(o => o.IsSupplier, f => f.Random.Bool().OrNull(f, .1f))
.RuleFor(o => o.Settings, f => null)
.RuleFor(o => o.Boreholes, _ => default!);
diff --git a/src/api/Controllers/BackfillController.cs b/src/api/Controllers/BackfillController.cs
index ba34baa30..f14e580f0 100644
--- a/src/api/Controllers/BackfillController.cs
+++ b/src/api/Controllers/BackfillController.cs
@@ -8,7 +8,7 @@ namespace BDMS.Controllers;
[ApiController]
[Route("api/v{version:apiVersion}/[controller]")]
-public class BackfillController : BdmsControllerBase
+public class BackfillController : BoreholeControllerBase
{
public BackfillController(BdmsContext context, ILogger logger, IBoreholeLockService boreholeLockService)
: base(context, logger, boreholeLockService)
diff --git a/src/api/Controllers/BdmsControllerBase.cs b/src/api/Controllers/BoreholeControllerBase.cs
similarity index 92%
rename from src/api/Controllers/BdmsControllerBase.cs
rename to src/api/Controllers/BoreholeControllerBase.cs
index 605adc8cb..9a44b4e3b 100644
--- a/src/api/Controllers/BdmsControllerBase.cs
+++ b/src/api/Controllers/BoreholeControllerBase.cs
@@ -3,9 +3,13 @@
namespace BDMS.Controllers;
+///
+/// Base controller for all borehole editing actions.
+///
+/// The controller to edit a borehole.
[ApiController]
[Route("api/v{version:apiVersion}/[controller]")]
-public abstract class BdmsControllerBase : ControllerBase
+public abstract class BoreholeControllerBase : ControllerBase
where TEntity : IIdentifyable, IChangeTracking, new()
{
private readonly BdmsContext context;
@@ -27,7 +31,7 @@ public abstract class BdmsControllerBase : ControllerBase
///
protected IBoreholeLockService BoreholeLockService => boreholeLockService;
- protected BdmsControllerBase(BdmsContext context, ILogger logger, IBoreholeLockService boreholeLockService)
+ protected BoreholeControllerBase(BdmsContext context, ILogger logger, IBoreholeLockService boreholeLockService)
{
this.context = context;
this.logger = logger;
diff --git a/src/api/Controllers/CasingController.cs b/src/api/Controllers/CasingController.cs
index 86d3d7e34..b28f08cb7 100644
--- a/src/api/Controllers/CasingController.cs
+++ b/src/api/Controllers/CasingController.cs
@@ -9,7 +9,7 @@ namespace BDMS.Controllers;
[ApiController]
[Route("api/v{version:apiVersion}/[controller]")]
-public class CasingController : BdmsControllerBase
+public class CasingController : BoreholeControllerBase
{
public CasingController(BdmsContext context, ILogger logger, IBoreholeLockService boreholeLockService)
: base(context, logger, boreholeLockService)
diff --git a/src/api/Controllers/ChronostratigraphyController.cs b/src/api/Controllers/ChronostratigraphyController.cs
index fed239ff7..60f8892f7 100644
--- a/src/api/Controllers/ChronostratigraphyController.cs
+++ b/src/api/Controllers/ChronostratigraphyController.cs
@@ -8,7 +8,7 @@ namespace BDMS.Controllers;
[ApiController]
[Route("api/v{version:apiVersion}/[controller]")]
-public class ChronostratigraphyController : BdmsControllerBase
+public class ChronostratigraphyController : BoreholeControllerBase
{
public ChronostratigraphyController(BdmsContext context, ILogger logger, IBoreholeLockService boreholeLockService)
: base(context, logger, boreholeLockService)
diff --git a/src/api/Controllers/CompletionController.cs b/src/api/Controllers/CompletionController.cs
index b6f99e99d..80cfd2cd0 100644
--- a/src/api/Controllers/CompletionController.cs
+++ b/src/api/Controllers/CompletionController.cs
@@ -10,7 +10,7 @@ namespace BDMS.Controllers;
[ApiController]
[Route("api/v{version:apiVersion}/[controller]")]
-public class CompletionController : BdmsControllerBase
+public class CompletionController : BoreholeControllerBase
{
public CompletionController(BdmsContext context, ILogger logger, IBoreholeLockService boreholeLockService)
: base(context, logger, boreholeLockService)
diff --git a/src/api/Controllers/FaciesDescriptionController.cs b/src/api/Controllers/FaciesDescriptionController.cs
index 491c22453..c61a3442f 100644
--- a/src/api/Controllers/FaciesDescriptionController.cs
+++ b/src/api/Controllers/FaciesDescriptionController.cs
@@ -8,7 +8,7 @@ namespace BDMS.Controllers;
[ApiController]
[Route("api/v{version:apiVersion}/[controller]")]
-public class FaciesDescriptionController : BdmsControllerBase
+public class FaciesDescriptionController : BoreholeControllerBase
{
public FaciesDescriptionController(BdmsContext context, ILogger logger, IBoreholeLockService boreholeLockService)
: base(context, logger, boreholeLockService)
diff --git a/src/api/Controllers/FieldMeasurementController.cs b/src/api/Controllers/FieldMeasurementController.cs
index 5c8ec9134..260cdeaed 100644
--- a/src/api/Controllers/FieldMeasurementController.cs
+++ b/src/api/Controllers/FieldMeasurementController.cs
@@ -8,7 +8,7 @@ namespace BDMS.Controllers;
[ApiController]
[Route("api/v{version:apiVersion}/[controller]")]
-public class FieldMeasurementController : BdmsControllerBase
+public class FieldMeasurementController : BoreholeControllerBase
{
public FieldMeasurementController(BdmsContext context, ILogger logger, IBoreholeLockService boreholeLockService)
: base(context, logger, boreholeLockService)
diff --git a/src/api/Controllers/GroundwaterLevelMeasurementController.cs b/src/api/Controllers/GroundwaterLevelMeasurementController.cs
index 89a9f1050..61def43c2 100644
--- a/src/api/Controllers/GroundwaterLevelMeasurementController.cs
+++ b/src/api/Controllers/GroundwaterLevelMeasurementController.cs
@@ -8,7 +8,7 @@ namespace BDMS.Controllers;
[ApiController]
[Route("api/v{version:apiVersion}/[controller]")]
-public class GroundwaterLevelMeasurementController : BdmsControllerBase
+public class GroundwaterLevelMeasurementController : BoreholeControllerBase
{
public GroundwaterLevelMeasurementController(BdmsContext context, ILogger logger, IBoreholeLockService boreholeLockService)
: base(context, logger, boreholeLockService)
diff --git a/src/api/Controllers/HydrotestController.cs b/src/api/Controllers/HydrotestController.cs
index 659b2d31e..e5834b3b6 100644
--- a/src/api/Controllers/HydrotestController.cs
+++ b/src/api/Controllers/HydrotestController.cs
@@ -8,7 +8,7 @@ namespace BDMS.Controllers;
[ApiController]
[Route("api/v{version:apiVersion}/[controller]")]
-public class HydrotestController : BdmsControllerBase
+public class HydrotestController : BoreholeControllerBase
{
public HydrotestController(BdmsContext context, ILogger logger, IBoreholeLockService boreholeLockService)
: base(context, logger, boreholeLockService)
diff --git a/src/api/Controllers/InstrumentationController.cs b/src/api/Controllers/InstrumentationController.cs
index 14792ecc3..645ba8499 100644
--- a/src/api/Controllers/InstrumentationController.cs
+++ b/src/api/Controllers/InstrumentationController.cs
@@ -8,7 +8,7 @@ namespace BDMS.Controllers;
[ApiController]
[Route("api/v{version:apiVersion}/[controller]")]
-public class InstrumentationController : BdmsControllerBase
+public class InstrumentationController : BoreholeControllerBase
{
public InstrumentationController(BdmsContext context, ILogger logger, IBoreholeLockService boreholeLockService)
: base(context, logger, boreholeLockService)
diff --git a/src/api/Controllers/LayerController.cs b/src/api/Controllers/LayerController.cs
index 02e4a15fe..f4da0cc68 100644
--- a/src/api/Controllers/LayerController.cs
+++ b/src/api/Controllers/LayerController.cs
@@ -8,7 +8,7 @@ namespace BDMS.Controllers;
[ApiController]
[Route("api/v{version:apiVersion}/[controller]")]
-public class LayerController : BdmsControllerBase
+public class LayerController : BoreholeControllerBase
{
public LayerController(BdmsContext context, ILogger logger, IBoreholeLockService boreholeLockService)
: base(context, logger, boreholeLockService)
diff --git a/src/api/Controllers/LithologicalDescriptionController.cs b/src/api/Controllers/LithologicalDescriptionController.cs
index bf0905a3d..281513a88 100644
--- a/src/api/Controllers/LithologicalDescriptionController.cs
+++ b/src/api/Controllers/LithologicalDescriptionController.cs
@@ -8,7 +8,7 @@ namespace BDMS.Controllers;
[ApiController]
[Route("api/v{version:apiVersion}/[controller]")]
-public class LithologicalDescriptionController : BdmsControllerBase
+public class LithologicalDescriptionController : BoreholeControllerBase
{
public LithologicalDescriptionController(BdmsContext context, ILogger logger, IBoreholeLockService boreholeLockService)
: base(context, logger, boreholeLockService)
diff --git a/src/api/Controllers/LithostratigraphyController.cs b/src/api/Controllers/LithostratigraphyController.cs
index ae9c66698..01546714e 100644
--- a/src/api/Controllers/LithostratigraphyController.cs
+++ b/src/api/Controllers/LithostratigraphyController.cs
@@ -8,7 +8,7 @@ namespace BDMS.Controllers;
[ApiController]
[Route("api/v{version:apiVersion}/[controller]")]
-public class LithostratigraphyController : BdmsControllerBase
+public class LithostratigraphyController : BoreholeControllerBase
{
public LithostratigraphyController(BdmsContext context, ILogger logger, IBoreholeLockService boreholeLockService)
: base(context, logger, boreholeLockService)
diff --git a/src/api/Controllers/SectionController.cs b/src/api/Controllers/SectionController.cs
index d0454a25a..abcc40751 100644
--- a/src/api/Controllers/SectionController.cs
+++ b/src/api/Controllers/SectionController.cs
@@ -8,7 +8,7 @@ namespace BDMS.Controllers;
[ApiController]
[Route("api/v{version:apiVersion}/[controller]")]
-public class SectionController : BdmsControllerBase
+public class SectionController : BoreholeControllerBase
{
public SectionController(BdmsContext context, ILogger logger, IBoreholeLockService boreholeLockService)
: base(context, logger, boreholeLockService)
diff --git a/src/api/Controllers/StratigraphyController.cs b/src/api/Controllers/StratigraphyController.cs
index 53db506f9..a0948f995 100644
--- a/src/api/Controllers/StratigraphyController.cs
+++ b/src/api/Controllers/StratigraphyController.cs
@@ -9,7 +9,7 @@ namespace BDMS.Controllers;
[ApiController]
[Route("api/v{version:apiVersion}/[controller]")]
-public class StratigraphyController : BdmsControllerBase
+public class StratigraphyController : BoreholeControllerBase
{
public StratigraphyController(BdmsContext context, ILogger logger, IBoreholeLockService boreholeLockService)
: base(context, logger, boreholeLockService)
diff --git a/src/api/Controllers/WaterIngressController.cs b/src/api/Controllers/WaterIngressController.cs
index c64e4a71d..beec526a1 100644
--- a/src/api/Controllers/WaterIngressController.cs
+++ b/src/api/Controllers/WaterIngressController.cs
@@ -9,7 +9,7 @@ namespace BDMS.Controllers;
[ApiController]
[Route("api/v{version:apiVersion}/[controller]")]
-public class WaterIngressController : BdmsControllerBase
+public class WaterIngressController : BoreholeControllerBase
{
public WaterIngressController(BdmsContext context, ILogger logger, IBoreholeLockService boreholeLockService)
: base(context, logger, boreholeLockService)
diff --git a/src/api/Controllers/WorkgroupController.cs b/src/api/Controllers/WorkgroupController.cs
new file mode 100644
index 000000000..6349e34c3
--- /dev/null
+++ b/src/api/Controllers/WorkgroupController.cs
@@ -0,0 +1,198 @@
+using BDMS.Models;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.EntityFrameworkCore;
+using Swashbuckle.AspNetCore.Annotations;
+
+namespace BDMS.Controllers;
+
+[ApiController]
+[Route("api/v{version:apiVersion}/[controller]")]
+public class WorkgroupController : ControllerBase
+{
+ private readonly BdmsContext context;
+ private ILogger logger;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The EF database context containing data for the BDMS application.
+ /// The logger used by the controller.
+ public WorkgroupController(BdmsContext context, ILogger logger)
+ {
+ this.context = context;
+ this.logger = logger;
+ }
+
+ ///
+ /// Gets a list of workgroups.
+ ///
+ [HttpGet]
+ [SwaggerResponse(StatusCodes.Status200OK, "Returns a list of workgroups.")]
+ public async Task> GetAll()
+ {
+ var workgroups = await context
+ .WorkgroupsWithIncludes
+ .AsNoTracking()
+ .ToListAsync()
+ .ConfigureAwait(false);
+
+ return workgroups;
+ }
+
+ ///
+ /// Create a new workgroup./>.
+ ///
+ [HttpPost]
+ [SwaggerResponse(StatusCodes.Status200OK, "The workgroup was created successfully.")]
+ [SwaggerResponse(StatusCodes.Status400BadRequest, "The workgroup could not be created due to invalid input.")]
+ [SwaggerResponse(StatusCodes.Status401Unauthorized, "The current user is not authorized to create workgroups.")]
+ [SwaggerResponse(StatusCodes.Status500InternalServerError, "The server encountered an unexpected condition that prevented it from fulfilling the request. ")]
+ public async Task Create(Workgroup workgroup)
+ {
+ try
+ {
+ if (workgroup == null)
+ {
+ return BadRequest();
+ }
+
+ var isDuplicate = await context.Workgroups.AnyAsync(w => w.Name == workgroup.Name).ConfigureAwait(false);
+ if (isDuplicate)
+ {
+ return Problem("A workgroup with the same name already exists.");
+ }
+
+ workgroup.Settings = "{}";
+ workgroup.CreatedAt = DateTime.UtcNow;
+ if (workgroup.IsSupplier == null)
+ {
+ workgroup.IsSupplier = false;
+ }
+
+ var enityEntry = await context.Workgroups.AddAsync(workgroup).ConfigureAwait(false);
+ await context.SaveChangesAsync().ConfigureAwait(false);
+
+ return Ok(enityEntry.Entity);
+ }
+ catch (Exception e)
+ {
+ var message = "Error while creating workgroup.";
+ logger.LogError(e, message);
+ return Problem(message);
+ }
+ }
+
+ ///
+ /// Updates the .
+ ///
+ [HttpPut]
+ [SwaggerResponse(StatusCodes.Status200OK, "The workgroup was updated successfully.")]
+ [SwaggerResponse(StatusCodes.Status400BadRequest, "The workgroup could not be updated due to invalid input.")]
+ [SwaggerResponse(StatusCodes.Status404NotFound, "The workgroup could not be found.")]
+ [SwaggerResponse(StatusCodes.Status401Unauthorized, "The current user is not authorized to update workgroups.")]
+ [SwaggerResponse(StatusCodes.Status500InternalServerError, "The server encountered an unexpected condition that prevented it from fulfilling the request. ")]
+ public async Task Edit(Workgroup workgroup)
+ {
+ try
+ {
+ if (workgroup == null)
+ {
+ return BadRequest();
+ }
+
+ var workgroupToEdit = await context.WorkgroupsWithIncludes.SingleOrDefaultAsync(w => w.Id == workgroup.Id).ConfigureAwait(false);
+ if (workgroupToEdit == null)
+ {
+ return NotFound();
+ }
+
+ workgroupToEdit.Name = workgroup.Name;
+ workgroupToEdit.DisabledAt = workgroup.DisabledAt;
+
+ await context.SaveChangesAsync().ConfigureAwait(false);
+ var updatedWorkgroup = await context.Workgroups.SingleOrDefaultAsync(w => w.Id == workgroup.Id).ConfigureAwait(false);
+ return Ok(updatedWorkgroup);
+ }
+ catch (Exception e)
+ {
+ var message = "Error while updating workgroup.";
+ logger.LogError(e, message);
+ return Problem(message);
+ }
+ }
+
+ ///
+ /// Deletes the workgroup with the specified .
+ ///
+ [HttpDelete("{id}")]
+ [SwaggerResponse(StatusCodes.Status200OK, "The workgroup was deleted successfully.")]
+ [SwaggerResponse(StatusCodes.Status400BadRequest, "The workgroup could not be updated due to invalid input.")]
+ [SwaggerResponse(StatusCodes.Status404NotFound, "The workgroup could not be found.")]
+ [SwaggerResponse(StatusCodes.Status401Unauthorized, "The current user is not authorized to delete workgroups.")]
+ [SwaggerResponse(StatusCodes.Status500InternalServerError, "The server encountered an unexpected condition that prevented it from fulfilling the request. ")]
+ public async Task Delete(int id)
+ {
+ try
+ {
+ var workgroup = await context.WorkgroupsWithIncludes.SingleOrDefaultAsync(w => w.Id == id).ConfigureAwait(false);
+ if (workgroup == null)
+ {
+ return NotFound();
+ }
+
+ if (workgroup.Boreholes?.Count > 0)
+ {
+ return Problem("The workgroup is associated with boreholes and cannot be deleted.");
+ }
+
+ context.Workgroups.Remove(workgroup);
+ await context.SaveChangesAsync().ConfigureAwait(false);
+ return Ok();
+ }
+ catch (Exception e)
+ {
+ var message = "Error while deleting workgroup.";
+ logger.LogError(e, message);
+ return Problem(message);
+ }
+ }
+
+ [HttpPost("setRole")]
+ [SwaggerResponse(StatusCodes.Status200OK, "The role was set successfully.")]
+ [SwaggerResponse(StatusCodes.Status400BadRequest, "The role could not be set due to invalid input.")]
+ [SwaggerResponse(StatusCodes.Status404NotFound, "The user or workgroup could not be found.")]
+ [SwaggerResponse(StatusCodes.Status401Unauthorized, "The current user is not authorized to set roles.")]
+ [SwaggerResponse(StatusCodes.Status500InternalServerError, "The server encountered an unexpected condition that prevented it from fulfilling the request. ")]
+ public async Task SetRole(UserWorkgroupRole userWorkgroupRole)
+ {
+ try
+ {
+ if (userWorkgroupRole == null)
+ {
+ return BadRequest();
+ }
+
+ var existingRole = await context.UserWorkgroupRoles
+ .SingleOrDefaultAsync(r => r.UserId == userWorkgroupRole.UserId && r.WorkgroupId == userWorkgroupRole.WorkgroupId && r.Role == userWorkgroupRole.Role)
+ .ConfigureAwait(false);
+
+ if (userWorkgroupRole.IsActive == true && existingRole == default)
+ {
+ await context.AddAsync(userWorkgroupRole).ConfigureAwait(false);
+ }
+ else if (userWorkgroupRole.IsActive == false && existingRole != default)
+ {
+ context.UserWorkgroupRoles.Remove(existingRole);
+ }
+
+ await context.SaveChangesAsync().ConfigureAwait(false);
+ return Ok();
+ }
+ catch (Exception e)
+ {
+ var message = "Error while setting role.";
+ logger.LogError(e, message);
+ return Problem(message);
+ }
+ }
+}
diff --git a/src/api/Dockerfile b/src/api/Dockerfile
index 0269582c1..73fda2052 100644
--- a/src/api/Dockerfile
+++ b/src/api/Dockerfile
@@ -6,13 +6,13 @@ WORKDIR /src
RUN apt-get -y update
RUN apt-get -y install git vim curl htop
RUN dotnet tool install --global dotnet-ef --version 8.0.0
-ENV PATH $PATH:/root/.dotnet/tools
+ENV PATH=$PATH:/root/.dotnet/tools
# Restore dependencies and tools
COPY BDMS.csproj .
RUN dotnet restore
-ENTRYPOINT dotnet watch run --no-launch-profile
+ENTRYPOINT ["dotnet", "watch", "run", "--no-launch-profile"]
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
ARG VERSION
@@ -51,8 +51,8 @@ ENV LC_ALL=C.UTF-8
COPY --from=build /app/publish .
-HEALTHCHECK CMD curl --fail http://localhost:8080/ || exit 1
+HEALTHCHECK CMD curl --fail http://localhost:8080/health || exit 1
# Switch to the non-root user 'app' defined in the base image
USER $APP_UID
-ENTRYPOINT dotnet "BDMS.dll"
+ENTRYPOINT ["dotnet", "BDMS.dll"]
diff --git a/src/api/Models/UserWorkgroupRole.cs b/src/api/Models/UserWorkgroupRole.cs
index 7d652846d..25b0e14dc 100644
--- a/src/api/Models/UserWorkgroupRole.cs
+++ b/src/api/Models/UserWorkgroupRole.cs
@@ -36,6 +36,12 @@ public class UserWorkgroupRole
[Column("id_rol_fk", TypeName = "int")]
public Role Role { get; set; }
+ ///
+ /// Gets or sets whether the role is active or not.
+ ///
+ [NotMapped]
+ public bool? IsActive { get; set; }
+
///
public override string ToString() => $"WorkgroupId: {WorkgroupId}, {Role}";
}
diff --git a/src/api/Models/Workgroup.cs b/src/api/Models/Workgroup.cs
index 720378188..edbdde12f 100644
--- a/src/api/Models/Workgroup.cs
+++ b/src/api/Models/Workgroup.cs
@@ -1,5 +1,6 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
+using System.Text.Json.Serialization;
namespace BDMS.Models;
@@ -24,13 +25,18 @@ public class Workgroup : IIdentifyable
/// Gets or sets the created date.
///
[Column("created_wgp")]
- public DateTime? Created { get; set; }
+ public DateTime? CreatedAt { get; set; }
///
/// Gets or sets the disabled date.
///
[Column("disabled_wgp")]
- public DateTime? Disabled { get; set; }
+ public DateTime? DisabledAt { get; set; }
+
+ ///
+ /// Gets the value whether the is disabled or not.
+ ///
+ public bool IsDisabled => DisabledAt.HasValue;
///
/// Gets or sets the Settings for the .
@@ -47,7 +53,13 @@ public class Workgroup : IIdentifyable
///
/// Gets the boreholes for the workgroup.
///
- public ICollection Boreholes { get; set; }
+ [JsonIgnore]
+ public ICollection? Boreholes { get; set; }
+
+ ///
+ /// Number of boreholes in the workgroup.
+ ///
+ public int BoreholeCount => Boreholes?.Count ?? 0;
///
public override string ToString() => Name;
diff --git a/src/api/Program.cs b/src/api/Program.cs
index 808d4c946..d1071c059 100644
--- a/src/api/Program.cs
+++ b/src/api/Program.cs
@@ -54,7 +54,7 @@
builder.Services.AddHttpContextAccessor();
builder.Services.AddHttpClient();
-var connectionString = builder.Configuration.GetConnectionString("BdmsContext");
+var connectionString = builder.Configuration.GetConnectionString(nameof(BdmsContext));
builder.Services.AddNpgsql(connectionString, options =>
{
options.UseQuerySplittingBehavior(QuerySplittingBehavior.SplitQuery);
@@ -73,7 +73,7 @@
options.SwaggerDoc("v2", new OpenApiInfo
{
Version = "v2",
- Title = "BDMS REST API v2",
+ Title = "Boreholes REST API v2",
});
options.AddSecurityDefinition("OpenIdConnect", new OpenApiSecurityScheme
{
@@ -139,6 +139,11 @@
builder.Services.AddScoped();
builder.Services.AddSingleton(TimeProvider.System);
+builder.Services
+ .AddHealthChecks()
+ .AddDbContextCheck("Database")
+ .AddCheck("S3");
+
var app = builder.Build();
// Migrate db changes on startup
@@ -166,5 +171,6 @@
app.MapControllers();
app.MapReverseProxy();
+app.MapHealthChecks("/health").AllowAnonymous();
app.Run();
diff --git a/src/api/S3HealthCheck.cs b/src/api/S3HealthCheck.cs
new file mode 100644
index 000000000..2c2b06030
--- /dev/null
+++ b/src/api/S3HealthCheck.cs
@@ -0,0 +1,38 @@
+using Amazon.S3;
+using Microsoft.Extensions.Diagnostics.HealthChecks;
+using System.Net;
+
+namespace BDMS;
+
+public class S3HealthCheck : IHealthCheck
+{
+ private readonly IAmazonS3 s3Client;
+
+ ///
+ /// Creates a new instance of .
+ ///
+ /// The client.
+ /// The object.
+ public S3HealthCheck(IAmazonS3 s3Client, IConfiguration configuration) => this.s3Client = s3Client;
+
+ ///
+ public async Task CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
+ {
+ var healthCheckResult = HealthCheckResult.Healthy();
+
+ try
+ {
+ var response = await s3Client.ListBucketsAsync(cancellationToken).ConfigureAwait(false);
+ if (response.HttpStatusCode != HttpStatusCode.OK)
+ {
+ healthCheckResult = HealthCheckResult.Unhealthy();
+ }
+ }
+ catch (Exception)
+ {
+ healthCheckResult = HealthCheckResult.Unhealthy();
+ }
+
+ return await Task.FromResult(healthCheckResult).ConfigureAwait(false);
+ }
+}
diff --git a/src/client/Dockerfile b/src/client/Dockerfile
index 7a0835f7d..807d22bd0 100644
--- a/src/client/Dockerfile
+++ b/src/client/Dockerfile
@@ -1,7 +1,7 @@
FROM node:20-buster-slim AS development
ARG VERSION
ARG REVISION
-ENV VITE_APP_VERSION ${VERSION}+${REVISION}
+ENV VITE_APP_VERSION=${VERSION}+${REVISION}
RUN apt-get -y update
RUN apt-get -y install git vim curl htop python3 python3-pip
RUN python3 -m pip install mkdocs
@@ -17,12 +17,12 @@ COPY ./docs ./docs
COPY ./mkdocs.yml ./
RUN mkdocs build -d ./public/help
-ENTRYPOINT npm run start -- --host
+ENTRYPOINT ["npm", "run", "start", "--", "--host"]
FROM node:20-buster-slim AS deploy
ARG VERSION
ARG REVISION
-ENV VITE_APP_VERSION ${VERSION}+${REVISION}
+ENV VITE_APP_VERSION=${VERSION}+${REVISION}
RUN apt-get -y update
RUN apt-get -y install git
diff --git a/src/client/src/api-lib/actions/workgroups.js b/src/client/src/api-lib/actions/workgroups.js
deleted file mode 100644
index e43c0afe3..000000000
--- a/src/client/src/api-lib/actions/workgroups.js
+++ /dev/null
@@ -1,53 +0,0 @@
-import { fetch } from "./index";
-
-export function createWorkgroup(name) {
- return fetch("/user/workgroup/edit", {
- action: "CREATE",
- name: name,
- });
-}
-
-export function enableWorkgroup(id) {
- return fetch("/user/workgroup/edit", {
- action: "ENABLE",
- id: id,
- });
-}
-
-export function disableWorkgroup(id) {
- return fetch("/user/workgroup/edit", {
- action: "DISABLE",
- id: id,
- });
-}
-
-export function deleteWorkgroup(id) {
- return fetch("/user/workgroup/edit", {
- action: "DELETE",
- id: id,
- });
-}
-
-export function updateWorkgroup(id, name) {
- return fetch("/user/workgroup/edit", {
- action: "UPDATE",
- id: id,
- name: name,
- });
-}
-
-export function listWorkgroups() {
- return fetch("/user/workgroup/edit", {
- type: "LIST",
- });
-}
-
-export function setRole(user_id, workgroup_id, role_name, activateRole = true) {
- return fetch("/user/workgroup/edit", {
- action: "SET",
- user_id: user_id,
- workgroup_id: workgroup_id,
- role_name: role_name,
- active: activateRole,
- });
-}
diff --git a/src/client/src/api-lib/index.js b/src/client/src/api-lib/index.js
index 612a288de..11a2d5b1a 100644
--- a/src/client/src/api-lib/index.js
+++ b/src/client/src/api-lib/index.js
@@ -6,16 +6,6 @@ import { acceptTerms, draftTerms, getTerms, getTermsDraft, publishTerms } from "
import { loadUser, setAuthentication, unsetAuthentication } from "./actions/user";
-import {
- createWorkgroup,
- deleteWorkgroup,
- disableWorkgroup,
- enableWorkgroup,
- listWorkgroups,
- setRole,
- updateWorkgroup,
-} from "./actions/workgroups";
-
import {
createBorehole,
deleteBorehole,
@@ -65,13 +55,6 @@ export {
setAuthentication,
unsetAuthentication,
loadUser,
- createWorkgroup,
- enableWorkgroup,
- disableWorkgroup,
- deleteWorkgroup,
- listWorkgroups,
- setRole,
- updateWorkgroup,
loadBorehole,
updateBorehole,
loadBoreholes,
diff --git a/src/client/src/api/apiInterfaces.ts b/src/client/src/api/apiInterfaces.ts
index 5552b554e..f0796550b 100644
--- a/src/client/src/api/apiInterfaces.ts
+++ b/src/client/src/api/apiInterfaces.ts
@@ -1,27 +1,29 @@
export enum Role {
- View,
- Editor,
- Controller,
- Validator,
- Publisher,
+ View = "View",
+ Editor = "Editor",
+ Controller = "Controller",
+ Validator = "Validator",
+ Publisher = "Publisher",
}
export interface Workgroup {
- // TODO: Add boreholes
id: number;
name: string;
- created?: Date;
- disabled?: Date;
+ isDisabled?: boolean;
+ disabledAt?: Date | string;
+ createdAt?: Date | string;
settings?: string;
isSupplier?: boolean;
+ boreholeCount: number;
}
export interface WorkgroupRole {
userId: number;
- user: User;
+ user?: User;
workgroupId: number;
- workgroup: Workgroup;
+ workgroup?: Workgroup;
role: Role;
+ isActive?: boolean;
}
export interface Term {
diff --git a/src/client/src/api/workgroup.ts b/src/client/src/api/workgroup.ts
new file mode 100644
index 000000000..dd68074f3
--- /dev/null
+++ b/src/client/src/api/workgroup.ts
@@ -0,0 +1,27 @@
+import { fetchApiV2 } from "./fetchApiV2";
+import { Role, Workgroup, WorkgroupRole } from "./apiInterfaces.ts";
+
+export const fetchWorkgroups = async () => await fetchApiV2("workgroup", "GET");
+
+export const createWorkgroup = async (workgroup: Workgroup) => await fetchApiV2("workgroup", "POST", workgroup);
+
+export const updateWorkgroup = async (workgroup: Workgroup) => {
+ if (workgroup.disabledAt) {
+ workgroup.disabledAt = new Date(workgroup.disabledAt).toISOString();
+ }
+ workgroup.isDisabled = undefined;
+
+ return await fetchApiV2("workgroup", "PUT", workgroup);
+};
+
+export const deleteWorkgroup = async (id: number) => await fetchApiV2(`workgroup/${id}`, "DELETE");
+
+export const setRole = async (userId: number, workgroupId: number, role: Role, isActive: boolean) => {
+ const workgroupRole: WorkgroupRole = {
+ workgroupId: workgroupId,
+ userId: userId,
+ role: role,
+ isActive: isActive,
+ };
+ return await fetchApiV2("workgroup/setRole", "POST", workgroupRole);
+};
diff --git a/src/client/src/pages/settings/admin/adminSettings.jsx b/src/client/src/pages/settings/admin/adminSettings.jsx
index b1b4e6ca9..c619ab834 100644
--- a/src/client/src/pages/settings/admin/adminSettings.jsx
+++ b/src/client/src/pages/settings/admin/adminSettings.jsx
@@ -7,19 +7,10 @@ import { deleteUser, fetchUser, fetchUsers, updateUser } from "../../../api/user
import { Button, Checkbox, Form, Icon, Input, Label, Loader, Modal, Table } from "semantic-ui-react";
-import {
- createWorkgroup,
- deleteWorkgroup,
- disableWorkgroup,
- enableWorkgroup,
- listWorkgroups,
- setRole,
- updateWorkgroup,
-} from "../../../api-lib/index";
-
import DateText from "../../../components/legacyComponents/dateText.js";
import TranslationText from "../../../components/legacyComponents/translationText.jsx";
import { WorkgroupRoleSettings } from "./workgroupRoleSettings";
+import { createWorkgroup, deleteWorkgroup, fetchWorkgroups, setRole, updateWorkgroup } from "../../../api/workgroup";
class AdminSettings extends React.Component {
static contextType = AlertContext;
@@ -34,8 +25,8 @@ class AdminSettings extends React.Component {
usersSearch: "",
workgroupFilter: "enabled", // 'all', 'enabled' or 'disabled',
workgroupsSearch: "",
- users: false,
- workgroups: false,
+ users: null,
+ workgroups: null,
roleUpdate: false,
@@ -54,11 +45,12 @@ class AdminSettings extends React.Component {
};
this.reset = this.reset.bind(this);
this.listUsers = this.listUsers.bind(this);
+ this.listWorkgroups = this.listWorkgroups.bind(this);
}
componentDidMount() {
this.listUsers();
- this.props.listWorkgroups();
+ this.listWorkgroups();
}
reset(state, andThen) {
@@ -98,6 +90,22 @@ class AdminSettings extends React.Component {
);
}
+ async listWorkgroups(reloadUser) {
+ const workgroups = await fetchWorkgroups();
+ this.setState({
+ workgroups: workgroups,
+ });
+
+ // immediately update currently selected workgroup.
+ if (reloadUser) {
+ await fetchUser(this.state.user.id).then(user => {
+ this.setState({
+ user: user,
+ });
+ });
+ }
+ }
+
async listUsers() {
const users = await fetchUsers();
this.setState({
@@ -118,9 +126,8 @@ class AdminSettings extends React.Component {
roleUpdate: true,
},
() => {
- let isRoleActive = uwg !== undefined && uwg.some(x => x.role.toLowerCase().startsWith(role.toLowerCase()));
-
- setRole(this.state.user.id, workgroup.id, role === "Publisher" ? "PUBLIC" : role, !isRoleActive).then(() => {
+ let isRoleActive = uwg !== undefined && uwg.some(x => x.role === role);
+ setRole(this.state.user.id, workgroup.id, role, !isRoleActive).then(() => {
this.listUsers();
});
},
@@ -342,7 +349,7 @@ class AdminSettings extends React.Component {
- ) : this.state.deleteUser !== null && this.state.deleteUser.deletable ? (
+ ) : this.state.deleteUser.deletable ? (
@@ -521,7 +528,7 @@ class AdminSettings extends React.Component {
{this.state.users &&
- this.state.users.map(currentUser =>
+ this.state.users?.map(currentUser =>
(this.state.usersSearch !== "" &&
(currentUser.name.toUpperCase().includes(this.state.usersSearch.toUpperCase()) ||
currentUser.firstName.toUpperCase().includes(this.state.usersSearch.toUpperCase()) ||
@@ -656,12 +663,14 @@ class AdminSettings extends React.Component {
label=" "
onClick={() => {
if (this.state.wId === null) {
- createWorkgroup(this.state.wName).then(() => {
- this.props.listWorkgroups(true);
+ createWorkgroup({ name: this.state.wName }).then(() => {
+ this.listWorkgroups(true);
});
} else {
- updateWorkgroup(this.state.wId, this.state.wName).then(() => {
- this.props.listWorkgroups(true);
+ const workgroup = this.state.workgroup;
+ workgroup.name = this.state.wName;
+ updateWorkgroup(workgroup).then(() => {
+ this.listWorkgroups(true);
});
}
}}>
@@ -752,14 +761,14 @@ class AdminSettings extends React.Component {
open={this.state.deleteWorkgroup !== null}
size="tiny">
- {this.state.deleteWorkgroup !== null && this.state.deleteWorkgroup.disabled !== null ? (
+ {this.state.deleteWorkgroup !== null && this.state.deleteWorkgroup.disabledAt !== null ? (
) : (
)}
- {this.state.deleteWorkgroup === null ? null : this.state.deleteWorkgroup.disabled !== null ? (
+ {this.state.deleteWorkgroup === null ? null : this.state.deleteWorkgroup.disabledAt !== null ? (
- ) : this.state.deleteWorkgroup !== null && this.state.deleteWorkgroup.boreholes === 0 ? (
+ ) : this.state.deleteWorkgroup.boreholeCount === 0 ? (
@@ -844,16 +853,18 @@ class AdminSettings extends React.Component {
- {this.state.deleteWorkgroup === null ? null : this.state.deleteWorkgroup.disabled !== null ? (
+ {this.state.deleteWorkgroup === null ? null : this.state.deleteWorkgroup.disabledAt !== null ? (