diff --git a/backend/src/baserow/contrib/database/api/fields/errors.py b/backend/src/baserow/contrib/database/api/fields/errors.py index 5cdf8eff3a..8741adbd29 100644 --- a/backend/src/baserow/contrib/database/api/fields/errors.py +++ b/backend/src/baserow/contrib/database/api/fields/errors.py @@ -219,3 +219,9 @@ HTTP_400_BAD_REQUEST, "Cannot use the view type.", ) +ERROR_INVALID_DEFAULT_VALUE_FUNCTION = ( + "ERROR_INVALID_DEFAULT_VALUE_FUNCTION", + HTTP_400_BAD_REQUEST, + "The provided default value function `{e.unsupported_function}` is not supported " + "for the given field type `{e.field_type}`.", +) diff --git a/backend/src/baserow/contrib/database/api/views/errors.py b/backend/src/baserow/contrib/database/api/views/errors.py index 230ee9e787..d5f729a17e 100644 --- a/backend/src/baserow/contrib/database/api/views/errors.py +++ b/backend/src/baserow/contrib/database/api/views/errors.py @@ -129,3 +129,8 @@ HTTP_400_BAD_REQUEST, "This view type does not support listing rows.", ) +ERROR_VIEW_DOES_NOT_SUPPORT_DEFAULT_VALUES = ( + "ERROR_VIEW_DOES_NOT_SUPPORT_DEFAULT_VALUES", + HTTP_400_BAD_REQUEST, + "This view type does not support setting default row values.", +) diff --git a/backend/src/baserow/contrib/database/api/views/serializers.py b/backend/src/baserow/contrib/database/api/views/serializers.py index c9d7163fe1..62954978d4 100644 --- a/backend/src/baserow/contrib/database/api/views/serializers.py +++ b/backend/src/baserow/contrib/database/api/views/serializers.py @@ -25,6 +25,7 @@ OWNERSHIP_TYPE_COLLABORATIVE, View, ViewDecoration, + ViewDefaultValue, ViewFilter, ViewFilterGroup, ViewGroupBy, @@ -388,6 +389,24 @@ class Meta: } +class ViewDefaultValueSerializer(serializers.ModelSerializer): + class Meta: + model = ViewDefaultValue + fields = ( + "id", + "field", + "enabled", + "value", + "field_type", + "function", + ) + extra_kwargs = { + "id": {"read_only": True}, + "field_type": {"read_only": True}, + "enabled": {"default": True}, + } + + class ViewSerializer(serializers.ModelSerializer): type = serializers.SerializerMethodField() table = TableWithoutDataSyncSerializer() @@ -400,6 +419,9 @@ class ViewSerializer(serializers.ModelSerializer): decorations = ViewDecorationSerializer( many=True, source="viewdecoration_set", required=False ) + default_row_values = ViewDefaultValueSerializer( + many=True, source="view_default_values", required=False + ) show_logo = serializers.BooleanField(required=False) ownership_type = serializers.CharField() owned_by_id = serializers.IntegerField(required=False) @@ -419,6 +441,7 @@ class Meta: "sortings", "group_bys", "decorations", + "default_row_values", "filters_disabled", "public_view_has_password", "show_logo", @@ -440,6 +463,7 @@ def __init__(self, instance=None, *args, **kwargs): context["include_sortings"] = kwargs.pop("sortings", False) context["include_decorations"] = kwargs.pop("decorations", False) context["include_group_bys"] = kwargs.pop("group_bys", False) + context["include_default_row_values"] = kwargs.pop("default_row_values", False) enhance_objects_by_view_ownership = kwargs.pop( "enhance_objects_by_view_ownership", True ) @@ -449,14 +473,33 @@ def __init__(self, instance=None, *args, **kwargs): # makes sure that the user only receives data about the view that they are # permitted to see, according to the ownership type. if enhance_objects_by_view_ownership and "user" in context: + # Build a set of field names that will actually appear in the + # response so that ownership types can skip unnecessary work (and + # queries) for fields that are not included. + includes = set() + if context.get("include_filters"): + includes.add("filters") + if context.get("include_sortings"): + includes.add("sortings") + if context.get("include_decorations"): + includes.add("decorations") + if context.get("include_group_bys"): + includes.add("group_bys") + if context.get("include_default_row_values"): + includes.add("default_row_values") + if isinstance(instance, list): instance = view_ownership_type_registry.prepare_views_of_different_types_for_user( - context["user"], instance + context["user"], + instance, + includes=includes, ) else: instance = ( view_ownership_type_registry.prepare_views_of_different_types_for_user( - context["user"], [instance] + context["user"], + [instance], + includes=includes, ) )[0] super().__init__(instance, *args, **kwargs) @@ -480,6 +523,9 @@ def to_representation(self, instance): if not self.context["include_group_bys"]: self.fields.pop("group_bys", None) + if not self.context.get("include_default_row_values"): + self.fields.pop("default_row_values", None) + return super().to_representation(instance) @extend_schema_field(OpenApiTypes.STR) diff --git a/backend/src/baserow/contrib/database/api/views/urls.py b/backend/src/baserow/contrib/database/api/views/urls.py index c3c1416473..87320998c1 100644 --- a/backend/src/baserow/contrib/database/api/views/urls.py +++ b/backend/src/baserow/contrib/database/api/views/urls.py @@ -12,6 +12,7 @@ RotateViewSlugView, ViewDecorationsView, ViewDecorationView, + ViewDefaultValuesView, ViewFieldOptionsView, ViewFilterGroupsView, ViewFilterGroupView, @@ -89,6 +90,11 @@ ViewDecorationsView.as_view(), name="list_decorations", ), + re_path( + r"(?P[0-9]+)/default-values/$", + ViewDefaultValuesView.as_view(), + name="default_values", + ), re_path( r"(?P[0-9]+)/field-options/$", ViewFieldOptionsView.as_view(), diff --git a/backend/src/baserow/contrib/database/api/views/views.py b/backend/src/baserow/contrib/database/api/views/views.py index af1c229d2f..42841dfa91 100644 --- a/backend/src/baserow/contrib/database/api/views/views.py +++ b/backend/src/baserow/contrib/database/api/views/views.py @@ -3,6 +3,7 @@ from django.conf import settings from django.contrib.contenttypes.models import ContentType +from django.core.exceptions import ValidationError from django.db import transaction from django.db.models import ObjectDoesNotExist @@ -23,6 +24,7 @@ validate_query_parameters, ) from baserow.api.errors import ERROR_USER_NOT_IN_GROUP +from baserow.api.exceptions import RequestBodyValidationException from baserow.api.pagination import PageNumberPagination from baserow.api.schemas import ( CLIENT_SESSION_ID_SCHEMA_PARAMETER, @@ -41,6 +43,7 @@ from baserow.contrib.database.api.fields.errors import ( ERROR_FIELD_DOES_NOT_EXIST, ERROR_FIELD_NOT_IN_TABLE, + ERROR_INVALID_DEFAULT_VALUE_FUNCTION, ) from baserow.contrib.database.api.fields.serializers import LinkRowValueSerializer from baserow.contrib.database.api.rows.errors import ERROR_ROW_DOES_NOT_EXIST @@ -54,11 +57,13 @@ CreateViewGroupBySerializer, PublicViewInfoSerializer, UpdateViewGroupBySerializer, + ViewDefaultValueSerializer, ViewGroupBySerializer, ) from baserow.contrib.database.fields.exceptions import ( FieldDoesNotExist, FieldNotInTable, + InvalidDefaultValueFunction, ) from baserow.contrib.database.fields.handler import FieldHandler from baserow.contrib.database.fields.models import Field, LinkRowField @@ -83,6 +88,7 @@ RotateViewSlugActionType, UpdateDecorationActionType, UpdateViewActionType, + UpdateViewDefaultValuesActionType, UpdateViewFieldOptionsActionType, UpdateViewFilterActionType, UpdateViewFilterGroupActionType, @@ -97,6 +103,7 @@ ViewDecorationDoesNotExist, ViewDecorationNotSupported, ViewDoesNotExist, + ViewDoesNotSupportDefaultValues, ViewDoesNotSupportFieldOptions, ViewDoesNotSupportListingRows, ViewFilterDoesNotExist, @@ -144,6 +151,7 @@ ERROR_VIEW_DECORATION_NOT_SUPPORTED, ERROR_VIEW_DECORATION_VALUE_PROVIDER_NOT_COMPATIBLE, ERROR_VIEW_DOES_NOT_EXIST, + ERROR_VIEW_DOES_NOT_SUPPORT_DEFAULT_VALUES, ERROR_VIEW_DOES_NOT_SUPPORT_FIELD_OPTIONS, ERROR_VIEW_DOES_NOT_SUPPORT_LISTING_ROWS, ERROR_VIEW_FILTER_DOES_NOT_EXIST, @@ -245,7 +253,7 @@ def get_permissions(self): description=( "A comma separated list of extra attributes to include on each " "view in the response. The supported attributes are `filters`, " - "`sortings` and `decorations`. " + "`sortings`, `decorations`, `group_bys` and `default_row_values`. " "For example `include=filters,sortings` will add the " "attributes `filters` and `sortings` to every returned view, " "containing a list of the views filters and sortings respectively." @@ -278,9 +286,19 @@ def get_permissions(self): } ) @validate_query_parameters(ListQueryParamatersSerializer) - @allowed_includes("filters", "sortings", "decorations", "group_bys") + @allowed_includes( + "filters", "sortings", "decorations", "group_bys", "default_row_values" + ) def get( - self, request, table_id, query_params, filters, sortings, decorations, group_bys + self, + request, + table_id, + query_params, + filters, + sortings, + decorations, + group_bys, + default_row_values, ): """ Responds with a list of serialized views that belong to the table if the user @@ -303,6 +321,7 @@ def get( sortings, decorations, group_bys, + default_row_values, query_params["limit"], ) @@ -320,6 +339,7 @@ def get( sortings=sortings, decorations=decorations, group_bys=group_bys, + default_row_values=default_row_values, many=True, ).data return Response(serialized_views) @@ -466,8 +486,19 @@ class ViewView(APIView): UserNotInWorkspace: ERROR_USER_NOT_IN_GROUP, } ) - @allowed_includes("filters", "sortings", "decorations", "group_bys") - def get(self, request, view_id, filters, sortings, decorations, group_bys): + @allowed_includes( + "filters", "sortings", "decorations", "group_bys", "default_row_values" + ) + def get( + self, + request, + view_id, + filters, + sortings, + decorations, + group_bys, + default_row_values, + ): """Selects a single view and responds with a serialized version.""" view = ViewHandler().get_view_as_user(request.user, view_id) @@ -479,6 +510,7 @@ def get(self, request, view_id, filters, sortings, decorations, group_bys): sortings=sortings, decorations=decorations, group_bys=group_bys, + default_row_values=default_row_values, context={"user": request.user}, ) return Response(serializer.data) @@ -676,6 +708,7 @@ def post(self, request, view_id): sortings=True, decorations=True, group_bys=True, + default_row_values=True, context={"user": request.user}, ) return Response(serializer.data) @@ -2455,3 +2488,86 @@ def get(self, request: Request, slug: str, row_id: int) -> Response: row._meta.model, RowSerializer, is_response=True, field_ids=field_ids ) return Response(serializer_class(row).data) + + +class ViewDefaultValuesView(APIView): + permission_classes = (IsAuthenticated,) + + @extend_schema( + parameters=[ + OpenApiParameter( + name="view_id", + location=OpenApiParameter.PATH, + type=OpenApiTypes.INT, + description="Updates the default row values for the view with " + "the given id.", + ), + CLIENT_SESSION_ID_SCHEMA_PARAMETER, + ], + tags=["Database table views"], + operation_id="update_view_default_values", + description=( + "Updates the default row values for the specified view. Accepts a list of " + "default value objects, each specifying the field, whether the default is " + "enabled, an optional raw value, and an optional function name (e.g. " + "'now') for dynamic defaults." + ), + request=ViewDefaultValueSerializer(many=True), + responses={ + 200: ViewDefaultValueSerializer(many=True), + 400: get_error_schema( + [ + "ERROR_USER_NOT_IN_GROUP", + "ERROR_VIEW_DOES_NOT_SUPPORT_DEFAULT_VALUES", + "ERROR_INVALID_DEFAULT_VALUE_FUNCTION", + "ERROR_FIELD_NOT_IN_TABLE", + ] + ), + 404: get_error_schema(["ERROR_VIEW_DOES_NOT_EXIST"]), + }, + ) + @map_exceptions( + { + ViewDoesNotExist: ERROR_VIEW_DOES_NOT_EXIST, + ViewDoesNotSupportDefaultValues: ERROR_VIEW_DOES_NOT_SUPPORT_DEFAULT_VALUES, + InvalidDefaultValueFunction: ERROR_INVALID_DEFAULT_VALUE_FUNCTION, + FieldNotInTable: ERROR_FIELD_NOT_IN_TABLE, + UserNotInWorkspace: ERROR_USER_NOT_IN_GROUP, + } + ) + @transaction.atomic + def patch(self, request, view_id): + """Updates the default row values for the given view.""" + + items = validate_data(ViewDefaultValueSerializer, request.data, many=True) + + handler = ViewHandler() + view = handler.get_view(view_id).specific + + # Validate field values through the row serializer to ensure they are valid + # for the respective field types. + table = view.table + model = table.get_model() + validation_serializer = get_row_serializer_class(model) + + raw_values = {} + for item in items: + field_id = item.get("field") + if field_id and item.get("value") is not None: + raw_values[f"field_{field_id}"] = item["value"] + + if raw_values: + validate_data(validation_serializer, raw_values) + + try: + records = action_type_registry.get( + UpdateViewDefaultValuesActionType.type + ).do( + user=request.user, + view=view, + items=items, + ) + except ValidationError as e: + raise RequestBodyValidationException(detail=e.message) + + return Response(ViewDefaultValueSerializer(records, many=True).data) diff --git a/backend/src/baserow/contrib/database/application_types.py b/backend/src/baserow/contrib/database/application_types.py index a01b6719db..18ef724015 100755 --- a/backend/src/baserow/contrib/database/application_types.py +++ b/backend/src/baserow/contrib/database/application_types.py @@ -246,6 +246,7 @@ def export_serialized( "view_set__viewsort_set", "view_set__viewgroupby_set", "view_set__viewdecoration_set", + "view_set__view_default_values", "data_sync__synced_properties", Prefetch( "field_rules", queryset=specific_queryset(FieldRule.objects.all()) diff --git a/backend/src/baserow/contrib/database/apps.py b/backend/src/baserow/contrib/database/apps.py index 8c76bcee61..9b80adc638 100755 --- a/backend/src/baserow/contrib/database/apps.py +++ b/backend/src/baserow/contrib/database/apps.py @@ -119,6 +119,7 @@ def ready(self): SubmitFormActionType, UpdateDecorationActionType, UpdateViewActionType, + UpdateViewDefaultValuesActionType, UpdateViewFieldOptionsActionType, UpdateViewFilterActionType, UpdateViewFilterGroupActionType, @@ -144,6 +145,7 @@ def ready(self): action_type_registry.register(EditFormRowActionType()) action_type_registry.register(RotateViewSlugActionType()) action_type_registry.register(UpdateViewFieldOptionsActionType()) + action_type_registry.register(UpdateViewDefaultValuesActionType()) action_type_registry.register(CreateDecorationActionType()) action_type_registry.register(UpdateDecorationActionType()) action_type_registry.register(DeleteDecorationActionType()) @@ -774,6 +776,8 @@ def ready(self): from baserow.contrib.database.views.operations import ( CanReceiveNotificationOnSubmitFormViewOperationType, + ReadViewDefaultValuesOperationType, + UpdateViewDefaultValuesOperationType, UpdateViewFieldOptionsOperationType, ) @@ -917,6 +921,8 @@ def ready(self): operation_type_registry.register(DeleteRelatedLinkRowFieldOperationType()) operation_type_registry.register(DuplicateFieldOperationType()) operation_type_registry.register(UpdateViewFieldOptionsOperationType()) + operation_type_registry.register(ReadViewDefaultValuesOperationType()) + operation_type_registry.register(UpdateViewDefaultValuesOperationType()) operation_type_registry.register(WriteFieldValuesOperationType()) operation_type_registry.register(SubmitAnonymousFieldValuesOperationType()) operation_type_registry.register(DeleteViewSortOperationType()) diff --git a/backend/src/baserow/contrib/database/fields/dependencies/dependency_rebuilder.py b/backend/src/baserow/contrib/database/fields/dependencies/dependency_rebuilder.py index ba8e9973b2..7abf95fd48 100644 --- a/backend/src/baserow/contrib/database/fields/dependencies/dependency_rebuilder.py +++ b/backend/src/baserow/contrib/database/fields/dependencies/dependency_rebuilder.py @@ -1,7 +1,7 @@ from collections import defaultdict from typing import TYPE_CHECKING, List -from django.db.models import Q +from django.db.models import Case, Q, Value, When if TYPE_CHECKING: from baserow.contrib.database.fields import models as field_models @@ -16,20 +16,39 @@ from baserow.contrib.database.fields.field_cache import FieldCache -def break_dependencies_for_field(field): +def break_dependencies_for_fields(fields: List["field_models.Field"]) -> None: """ - Given a specific field ensures no fields depend on it any more, and if they do - those dependencies are set to be broken and only reference the field name. + Given a list of fields, ensures no fields depend on them any more, and if they + do those dependencies are set to be broken and only reference the field name. + Batches the queries so that the number of queries is constant regardless of the + number of fields. - :param field: The field whose dependants will have their relationships broken for. + :param fields: The fields whose dependants will have their relationships broken. """ from baserow.contrib.database.fields.models import LinkRowField - FieldDependency.objects.filter(dependant=field).delete() - field.dependants.update(dependency=None, broken_reference_field_name=field.name) - if isinstance(field, LinkRowField): - field.vias.all().delete() + if not fields: + return + + field_ids = [f.id for f in fields] + + # Remove all dependencies where these fields are the dependant. + FieldDependency.objects.filter(dependant_id__in=field_ids).delete() + + # Mark all dependants of these fields as broken references, preserving the + # per-field name via Case/When so each broken reference records the correct + # field name. + cases = [When(dependency_id=f.id, then=Value(f.name)) for f in fields] + FieldDependency.objects.filter(dependency_id__in=field_ids).update( + dependency=None, + broken_reference_field_name=Case(*cases), + ) + + # Remove via dependencies for any LinkRowFields. + link_row_field_ids = [f.id for f in fields if isinstance(f, LinkRowField)] + if link_row_field_ids: + FieldDependency.objects.filter(via_id__in=link_row_field_ids).delete() def update_fields_with_broken_references(fields: List["field_models.Field"]): diff --git a/backend/src/baserow/contrib/database/fields/dependencies/handler.py b/backend/src/baserow/contrib/database/fields/dependencies/handler.py index 256fb185df..208d7a2467 100644 --- a/backend/src/baserow/contrib/database/fields/dependencies/handler.py +++ b/backend/src/baserow/contrib/database/fields/dependencies/handler.py @@ -8,7 +8,7 @@ from django.db.models import Q, QuerySet from baserow.contrib.database.fields.dependencies.dependency_rebuilder import ( - break_dependencies_for_field, + break_dependencies_for_fields, rebuild_fields_dependencies, update_fields_with_broken_references, ) @@ -63,15 +63,18 @@ def rebuild_dependencies( return rebuild_fields_dependencies(fields, field_cache) @classmethod - def break_dependencies_delete_dependants(cls, field): + def break_dependencies_delete_dependants(cls, fields): """ - Breaks any dependant relationships to the field. + Breaks any dependant relationships to the provided field(s). - :param field: The field to break all dependant relations onto the field and all - dependencies + :param fields: A single field or list of fields to break all dependant + relations onto and all dependencies. """ - break_dependencies_for_field(field) + if not isinstance(fields, (list, tuple)): + fields = [fields] + + break_dependencies_for_fields(fields) @classmethod def _get_all_dependent_fields( diff --git a/backend/src/baserow/contrib/database/fields/exceptions.py b/backend/src/baserow/contrib/database/fields/exceptions.py index e7cfd5942b..0615a70699 100644 --- a/backend/src/baserow/contrib/database/fields/exceptions.py +++ b/backend/src/baserow/contrib/database/fields/exceptions.py @@ -355,3 +355,20 @@ def __init__(self, field_type=None, constraint_type=None, *args, **kwargs): class InvalidPasswordFieldPassword(Exception): """Raised when the provided password field is invalid.""" + + +class InvalidDefaultValueFunction(Exception): + """Raised when an unsupported function is used for a default value.""" + + def __init__(self, unsupported_function=None, field_type=None, *args, **kwargs): + self.unsupported_function = unsupported_function + self.field_type = field_type + msg = ( + f"Function '{unsupported_function}' is not supported by field type " + f"'{field_type}'." + ) + super().__init__( + msg, + *args, + **kwargs, + ) diff --git a/backend/src/baserow/contrib/database/fields/field_types.py b/backend/src/baserow/contrib/database/fields/field_types.py index 40876c1dc7..285f478444 100755 --- a/backend/src/baserow/contrib/database/fields/field_types.py +++ b/backend/src/baserow/contrib/database/fields/field_types.py @@ -1129,6 +1129,14 @@ class DateFieldType(FieldType): _can_have_db_index = True can_upsert = True + def get_supported_default_value_functions(self): + return ["now"] + + def resolve_default_value_function(self, function_name, field): + if function_name == "now": + return datetime.now(tz=timezone.utc) + return super().resolve_default_value_function(function_name, field) + def can_represent_date(self, field): return True @@ -4385,6 +4393,12 @@ def get_internal_value_from_db( ) -> int: return getattr(row, f"{field_name}_id") + def import_serialized_default_value(self, value, id_mapping): + if isinstance(value, int): + option_mapping = id_mapping.get("database_field_select_options", {}) + return option_mapping.get(value, value) + return value + def get_search_expression( self, field: SingleSelectField, queryset: QuerySet ) -> Expression: @@ -4752,6 +4766,14 @@ class MultipleSelectFieldType( ), } + def import_serialized_default_value(self, value, id_mapping): + if isinstance(value, list): + option_mapping = id_mapping.get("database_field_select_options", {}) + return [ + option_mapping.get(v, v) if isinstance(v, int) else v for v in value + ] + return value + def init_field_data(self, field, model): if field.multiple_select_default: through_model = model._meta.get_field(field.db_column).remote_field.through diff --git a/backend/src/baserow/contrib/database/fields/registries.py b/backend/src/baserow/contrib/database/fields/registries.py index 613b251510..ae8673d05b 100644 --- a/backend/src/baserow/contrib/database/fields/registries.py +++ b/backend/src/baserow/contrib/database/fields/registries.py @@ -69,6 +69,7 @@ FieldTypeAlreadyRegistered, FieldTypeDoesNotExist, IncompatibleField, + InvalidDefaultValueFunction, ReadOnlyFieldHasNoInternalDbValueError, ) from .fields import DurationFieldUsingPostgresFormatting @@ -237,6 +238,31 @@ def db_column_fields(self) -> Set[str]: return self._db_column_fields return set(self.allowed_fields) + def get_supported_default_value_functions(self) -> list: + """ + Returns a list of function names that this field type supports for view default + values. For example, a date field might support "now" to insert the current + timestamp at row creation time. + + :return: A list of supported function name strings. + """ + + return [] + + def resolve_default_value_function(self, function_name: str, field: Field) -> Any: + """ + Resolves a default value function to an actual value at row creation time. The + function_name must be one of the strings returned by + get_supported_default_value_functions(). + + :param function_name: The function name to resolve (e.g. "now"). + :param field: The field instance. + :return: The resolved value. + :raises InvalidDefaultValueFunction: If the function is not supported. + """ + + raise InvalidDefaultValueFunction(function_name, self.type) + def prepare_value_for_db(self, instance: Field, value: Any) -> Any: """ When a row is created or updated all the values are going to be prepared for the @@ -1227,6 +1253,23 @@ def set_import_serialized_value( setattr(row, field_name, value) + def import_serialized_default_value( + self, + value: Any, + id_mapping: Dict[str, Any], + ) -> Any: + """ + Hook that is called just before the ViewDefaultValue.value is set when doing a + serialized import. Can be used to potentially remap IDs like for example with a + single select field. + + :param value: The raw JSON default value to remap. + :param id_mapping: The map of exported ids to newly created ids. + :return: The value with remapped IDs. + """ + + return value + def get_export_value( self, value: Any, field_object: "FieldObject", rich_value: bool = False ) -> Any: diff --git a/backend/src/baserow/contrib/database/migrations/0207_add_view_default_values.py b/backend/src/baserow/contrib/database/migrations/0207_add_view_default_values.py new file mode 100644 index 0000000000..647998561d --- /dev/null +++ b/backend/src/baserow/contrib/database/migrations/0207_add_view_default_values.py @@ -0,0 +1,35 @@ +# Generated by Django 5.2.12 on 2026-03-31 20:25 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('database', '0206_rowhistory_database_ro_action__6ea699_idx'), + ] + + operations = [ + migrations.CreateModel( + name='ViewDefaultValue', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('enabled', models.BooleanField(default=True, help_text='Whether this default value is active.')), + ('value', models.JSONField(default=None, help_text='The raw default value in API request format.', null=True)), + ('field_type', models.CharField(help_text='The field type identifier at the time the value was stored. Used to detect incompatibility when the field type changes.', max_length=64, null=True)), + ('function', models.CharField(help_text="Optional function name (e.g. 'now') to resolve the default value dynamically at row creation time instead of using the stored value.", max_length=64, null=True)), + ('field', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='database.field')), + ('view', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='view_default_values', to='database.view')), + ], + options={ + 'ordering': ('id',), + 'constraints': [ + models.UniqueConstraint( + fields=['view', 'field'], + name='unique_view_field_default_value', + ) + ], + }, + ), + ] diff --git a/backend/src/baserow/contrib/database/rows/handler.py b/backend/src/baserow/contrib/database/rows/handler.py index 40ad3c30fa..89e265cc62 100644 --- a/backend/src/baserow/contrib/database/rows/handler.py +++ b/backend/src/baserow/contrib/database/rows/handler.py @@ -855,6 +855,18 @@ def create_row( self._raise_if_values_contain_hidden_fields(user, view, [values]) self._check_write_fields_values_permissions(user, model, [values]) + # Apply view default values for fields not explicitly provided by the + # user. View defaults take priority over field-level defaults. + if view is not None: + from baserow.contrib.database.views.handler import ViewHandler + + view_defaults = ViewHandler().get_view_default_values_for_row_creation( + view, model=model + ) + for field_name, default_value in view_defaults.items(): + if field_name not in values: + values[field_name] = default_value + return self.force_create_row( user, table, @@ -1559,6 +1571,20 @@ def create_rows( self._raise_if_values_contain_hidden_fields(user, view, rows_values) self._check_write_fields_values_permissions(user, model, rows_values) + # Apply view default values for fields not explicitly provided by the user. + # View defaults take priority over field-level defaults. + if view is not None: + from baserow.contrib.database.views.handler import ViewHandler + + view_defaults = ViewHandler().get_view_default_values_for_row_creation( + view, model=model + ) + if view_defaults: + for row_values in rows_values: + for field_name, default_value in view_defaults.items(): + if field_name not in row_values: + row_values[field_name] = default_value + return self.force_create_rows( user, table, @@ -2677,7 +2703,9 @@ def get_rows( return model.objects.filter(id__in=row_ids).enhance_by_fields() def get_rows_for_update( - self, model: GeneratedTableModel, row_ids: List[int] + self, + model: GeneratedTableModel, + row_ids: List[int], ) -> RowsForUpdate: """ Get the rows to update. This method doesn't guarantee that the rows diff --git a/backend/src/baserow/contrib/database/trash/trash_types.py b/backend/src/baserow/contrib/database/trash/trash_types.py index 15abf7abf7..7d07ba8fa8 100644 --- a/backend/src/baserow/contrib/database/trash/trash_types.py +++ b/backend/src/baserow/contrib/database/trash/trash_types.py @@ -5,6 +5,9 @@ from django.db import connection, router from baserow.contrib.database.db.schema import safe_django_schema_editor +from baserow.contrib.database.fields.dependencies.handler import ( + FieldDependencyHandler, +) from baserow.contrib.database.fields.dependencies.update_collector import ( FieldUpdateCollector, ) @@ -160,28 +163,77 @@ def trash( field_cache = FieldCache() handler = FieldHandler() - for field in model._field_objects.values(): - field = field["field"] - # One of the previously deleted fields might have cached this field we - # now want to delete, ensure it is gone from the cache as presence in the - # cache is treated as the field not being trashed in other code. - field_cache.uncache_field(field) - handler.delete_field( - requesting_user, - field, - existing_trash_entry=trash_entry, - apply_and_send_updates=False, - update_collector=update_collector, - field_cache=field_cache, - allow_deleting_primary=True, + fields = [fo["field"] for fo in model._field_objects.values()] + all_field_ids = {f.id for f in fields} + + # Pre-compute cross-table dependents per field. Intra-table fields are + # all being trashed together and don't need individual updates. + per_field_deps: Dict[int, list] = {} + for field in fields: + deps = list( + FieldDependencyHandler.group_all_dependent_fields_by_level( + table_to_trash.id, + [field.id], + field_cache, + associated_relations_changed=True, + database_id_prefilter=table_to_trash.database_id, + ) ) + filtered = [] + for group in deps: + cross_table = [ + (dep_field, dep_type, path) + for dep_field, dep_type, path in group + if dep_field.table_id != table_to_trash.id + ] + if cross_table: + filtered.append(cross_table) + if filtered: + per_field_deps[field.id] = filtered + + FieldDependencyHandler.break_dependencies_delete_dependants(fields) + + # Update cross-table dependents before trashing the fields because the + # formula recalculation engine needs the fields to still be present. + for field in fields: + if field.id in per_field_deps: + handler._update_dependencies_of_field_deleted( + field, + update_collector, + field_cache, + per_field_deps[field.id], + ) + + # Batch trash all fields in this table and make sure to invalidate the + # table model cache for this table so that if any field operations + # happen after the table is trashed we don't use the cached model. + Field.objects_and_trash.filter(id__in=all_field_ids).update(trashed=True) + if fields: + fields[0].invalidate_table_model_cache() + + # Trash related fields in other tables (e.g. reverse link row fields). + field_cache.reset_cache() + for field in fields: + field_type = field_type_registry.get_by_model(field) + for ( + related_field + ) in field_type.get_other_fields_to_trash_restore_always_together(field): + if not related_field.trashed: + handler.delete_field( + requesting_user, + related_field, + existing_trash_entry=trash_entry, + apply_and_send_updates=False, + update_collector=update_collector, + field_cache=field_cache, + ) update_collector.send_additional_field_updated_signals() super().trash(table_to_trash, requesting_user, trash_entry) - # Since link_row can link this table without creating the reverse relation, - # we need to be sure to trash that fields manually. + # Trash link_row fields that point at this table without a reverse + # relation, since they won't be caught by the loop above. related_fields_to_trash: List[int] = [] for field in table_to_trash.linkrowfield_set.filter(trashed=False): if ( diff --git a/backend/src/baserow/contrib/database/views/actions.py b/backend/src/baserow/contrib/database/views/actions.py index 7d856e155c..097c4f81c7 100755 --- a/backend/src/baserow/contrib/database/views/actions.py +++ b/backend/src/baserow/contrib/database/views/actions.py @@ -2556,3 +2556,70 @@ def do( @classmethod def scope(cls, view_id: int) -> ActionScopeStr: return ViewActionScopeType.value(view_id) + + +class UpdateViewDefaultValuesActionType(ActionType): + type = "update_view_default_values" + description = ActionTypeDescription( + _("Update view default values"), + _("Default row values updated for view (%(view_name)s)"), + VIEW_ACTION_CONTEXT, + ) + analytics_params = [ + "view_id", + "table_id", + "database_id", + ] + + @dataclasses.dataclass + class Params: + view_id: int + view_name: str + table_id: int + table_name: str + database_id: int + database_name: str + new_values: Dict[str, Any] + + @classmethod + def do(cls, user: AbstractUser, view: View, items: List[Dict[str, Any]]): + """ + Updates the default row values for the given view. + """ + + table = view.table + result = ViewHandler().update_view_default_values( + user=user, + view=view, + items=items, + ) + + # Capture the saved state analogously to get_row_values in row actions — + # evaluate the queryset once so we record what was actually persisted. + new_values = { + str(record.field_id): { + "enabled": record.enabled, + "value": record.value, + "function": record.function, + "field_type": record.field_type, + } + for record in result + } + + workspace = table.database.workspace + params = cls.Params( + view.id, + view.name, + table.id, + table.name, + table.database.id, + table.database.name, + new_values=new_values, + ) + cls.register_action(user, params, scope=cls.scope(view.id), workspace=workspace) + + return result + + @classmethod + def scope(cls, view_id: int) -> ActionScopeStr: + return ViewActionScopeType.value(view_id) diff --git a/backend/src/baserow/contrib/database/views/exceptions.py b/backend/src/baserow/contrib/database/views/exceptions.py index 40d0e07f55..8b064ebde3 100644 --- a/backend/src/baserow/contrib/database/views/exceptions.py +++ b/backend/src/baserow/contrib/database/views/exceptions.py @@ -218,6 +218,10 @@ class ViewOwnershipTypeDoesNotExist(InstanceTypeDoesNotExist): """ +class ViewDoesNotSupportDefaultValues(Exception): + """Raised when trying to set default values on a view that doesn't support it.""" + + class InvalidAPIGroupedFiltersFormatException(ValueError): """ Raised when the provided view filters format is invalid. diff --git a/backend/src/baserow/contrib/database/views/handler.py b/backend/src/baserow/contrib/database/views/handler.py index 82f314fe58..3427851cbe 100644 --- a/backend/src/baserow/contrib/database/views/handler.py +++ b/backend/src/baserow/contrib/database/views/handler.py @@ -14,7 +14,7 @@ from django.core.exceptions import FieldDoesNotExist, ValidationError from django.db import connection from django.db import models as django_models -from django.db.models import Count, Q +from django.db.models import Count, Q, prefetch_related_objects from django.db.models.expressions import OrderBy from django.db.models.query import QuerySet @@ -25,7 +25,10 @@ from baserow.contrib.database.api.utils import get_include_exclude_field_ids from baserow.contrib.database.db.schema import safe_django_schema_editor -from baserow.contrib.database.fields.exceptions import FieldNotInTable +from baserow.contrib.database.fields.exceptions import ( + FieldNotInTable, + InvalidDefaultValueFunction, +) from baserow.contrib.database.fields.field_filters import ( AdvancedFilterBuilder, FilterBuilder, @@ -38,7 +41,9 @@ from baserow.contrib.database.search.handler import SearchMode from baserow.contrib.database.table.cache import invalidate_table_in_model_cache from baserow.contrib.database.table.models import GeneratedTableModel, Table -from baserow.contrib.database.views.exceptions import ViewOwnershipTypeDoesNotExist +from baserow.contrib.database.views.exceptions import ( + ViewOwnershipTypeDoesNotExist, +) from baserow.contrib.database.views.filters import AdHocFilters from baserow.contrib.database.views.operations import ( CreatePublicViewOperationType, @@ -71,6 +76,7 @@ ReadViewsOrderOperationType, ReadViewSortOperationType, UpdateViewDecorationOperationType, + UpdateViewDefaultValuesOperationType, UpdateViewFieldOptionsOperationType, UpdateViewFilterGroupOperationType, UpdateViewFilterOperationType, @@ -111,6 +117,7 @@ ViewDecorationDoesNotExist, ViewDecorationNotSupported, ViewDoesNotExist, + ViewDoesNotSupportDefaultValues, ViewDoesNotSupportFieldOptions, ViewDoesNotSupportListingRows, ViewFilterDoesNotExist, @@ -134,6 +141,7 @@ FormViewFieldOptions, View, ViewDecoration, + ViewDefaultValue, ViewFilter, ViewFilterGroup, ViewGroupBy, @@ -586,18 +594,20 @@ def list_views( sortings: bool = True, decorations: bool = True, group_bys: bool = True, + default_row_values: bool = False, limit: int | None = None, ) -> Iterable[View]: """ Lists available views for a user/table combination. - :user: The user on whose behalf we want to return views. - :table: The table for which the views should be returned. - :_type: The view type to get. - :filters: If filters should be prefetched. - :sortings: If sorts should be prefetched. - :decorations: If view decorations should be prefetched. - :limit: To limit the number of returned views. + :param user: The user on whose behalf we want to return views. + :param table: The table for which the views should be returned. + :param _type: The view type to get. + :param filters: If filters should be prefetched. + :param sortings: If sorts should be prefetched. + :param decorations: If view decorations should be prefetched. + :param default_row_values: If default row values should be prefetched. + :param limit: To limit the number of returned views. :return: Iterator over returned views. """ @@ -630,6 +640,9 @@ def list_views( if group_bys: views = views.prefetch_related("viewgroupby_set") + if default_row_values: + views = views.prefetch_related("view_default_values") + if limit: views = views[:limit] @@ -955,6 +968,8 @@ def duplicate_view(self, user: AbstractUser, original_view: View) -> View: "workspace_id": workspace.id, } + prefetch_related_objects([original_view], "view_default_values") + # Use export/import to duplicate the view easily serialized = view_type.export_serialized(original_view, config, cache) @@ -3775,6 +3790,193 @@ def _get_prepared_values_for_data( if key in changed_allowed_keys } + def get_view_default_values(self, view): + """ + Returns the ViewDefaultValue queryset for the given view. + + :param view: The view to get default values for. + :return: QuerySet of ViewDefaultValue records. + :raises ViewDoesNotSupportDefaultValues: If the view type doesn't + support default values. + """ + + view_type = view_type_registry.get_by_model(view.specific_class) + if not view_type.can_set_default_values: + raise ViewDoesNotSupportDefaultValues( + f"The view type {view_type.type} does not support default values." + ) + + return ViewDefaultValue.objects.filter(view_id=view.id) + + def update_view_default_values(self, user, view, items, model=None): + """ + Updates the default values for the given view from a list of item + dicts. Each item should contain ``field`` (field ID) and optionally + ``enabled``, ``value``, ``function``. + + :param user: The user performing the update. + :param view: The view to update default values for. + :param items: List of dicts with field, enabled, value, function. + :param model: Optional pre-generated table model. + :return: QuerySet of updated ViewDefaultValue records. + """ + + view_type = view_type_registry.get_by_model(view.specific_class) + if not view_type.can_set_default_values: + raise ViewDoesNotSupportDefaultValues( + f"The view type {view_type.type} does not support default values." + ) + + table = view.table + workspace = table.database.workspace + + CoreHandler().check_permissions( + user, + UpdateViewDefaultValuesOperationType.type, + workspace=workspace, + context=view, + ) + + View.objects.select_for_update(of=("self",)).get(id=view.id) + + if model is None: + model = table.get_model() + + # Run the same prepare_values step used during row creation so that + # field types can perform additional validation (e.g. + # NumberFieldType rejecting negative values, SingleSelectFieldType + # rejecting unknown option IDs) that the serializer alone does not + # catch. + raw_values = {} + for item in items: + field_id = item.get("field") + if field_id and item.get("value") is not None: + raw_values[f"field_{field_id}"] = item["value"] + if raw_values: + RowHandler().prepare_values(model._field_objects, raw_values) + + existing_by_field = { + default_value.field_id: default_value + for default_value in ViewDefaultValue.objects.filter(view_id=view.id) + } + + to_create = [] + to_update = [] + seen_field_ids = set() + + for item in items: + field_id = int(item["field"]) + + if field_id not in model._field_objects: + raise FieldNotInTable( + f"Field {field_id} does not belong to table {table.id}." + ) + + seen_field_ids.add(field_id) + + enabled = item.get("enabled", True) + value = item.get("value") + func_name = item.get("function") + + # Validate function against field type. + field_obj = model._field_objects[field_id] + if func_name: + supported = field_obj["type"].get_supported_default_value_functions() + if func_name not in supported: + raise InvalidDefaultValueFunction(func_name, field_obj["type"].type) + + field_type_str = field_obj["type"].type + + if field_id in existing_by_field: + record = existing_by_field[field_id] + record.enabled = enabled + record.function = func_name + if value is not None or "value" in item: + record.value = value + record.field_type = field_type_str + to_update.append(record) + else: + to_create.append( + ViewDefaultValue( + view_id=view.id, + field_id=field_id, + enabled=enabled, + function=func_name, + value=value, + field_type=field_type_str, + ) + ) + + if to_create: + ViewDefaultValue.objects.bulk_create(to_create) + + if to_update: + ViewDefaultValue.objects.bulk_update( + to_update, ["enabled", "function", "value", "field_type"] + ) + + to_delete = [fid for fid in existing_by_field if fid not in seen_field_ids] + if to_delete: + ViewDefaultValue.objects.filter( + view_id=view.id, field_id__in=to_delete + ).delete() + + old_view = deepcopy(view) + view_updated.send(self, view=view, user=user, old_view=old_view) + + return ViewDefaultValue.objects.filter(view_id=view.id) + + def get_view_default_values_for_row_creation(self, view, model=None): + """ + Lightweight method for the row creation path. Returns a dict of + {field_name: resolved_value} for all enabled default fields. + Functions like 'now' are resolved to actual values. Stored raw + values are used directly since they were validated at save time. + + :param view: The view whose defaults to resolve. + :param model: Optional pre-generated table model. + :return: Dict mapping field_name to resolved default value. + """ + + view_type = view_type_registry.get_by_model(view.specific_class) + if not view_type.can_set_default_values: + return {} + + if model is None: + model = view.table.get_model() + + default_values = list( + ViewDefaultValue.objects.filter(view_id=view.id, enabled=True) + ) + if not default_values: + return {} + + result = {} + for default_value in default_values: + field_id = default_value.field_id + if field_id not in model._field_objects: + continue + + field_obj = model._field_objects[field_id] + field = field_obj["field"] + field_type = field_obj["type"] + field_name = field_obj["name"] + supported_functions = field_type.get_supported_default_value_functions() + + if default_value.function and default_value.function in supported_functions: + result[field_name] = field_type.resolve_default_value_function( + default_value.function, field + ) + elif default_value.value is not None: + if ( + default_value.field_type + and default_value.field_type != field_type.type + ): + continue + result[field_name] = default_value.value + + return result + class ViewSubscriptionHandler: @classmethod diff --git a/backend/src/baserow/contrib/database/views/models.py b/backend/src/baserow/contrib/database/views/models.py index e331abd04f..b119b3dffe 100644 --- a/backend/src/baserow/contrib/database/views/models.py +++ b/backend/src/baserow/contrib/database/views/models.py @@ -1005,3 +1005,52 @@ class ViewSubscription(models.Model): class Meta: unique_together = ("view", "subscriber_content_type", "subscriber_id") + + +class ViewDefaultValue(HierarchicalModelMixin, models.Model): + """ + Stores a default value for a specific field in a view. When ``enabled`` is + True and the field type still matches ``field_type``, the value is applied + to new rows created in the context of that view. + """ + + view = models.ForeignKey( + View, on_delete=models.CASCADE, related_name="view_default_values" + ) + field = models.ForeignKey( + "database.Field", + on_delete=models.CASCADE, + ) + enabled = models.BooleanField( + default=True, + help_text="Whether this default value is active.", + ) + value = models.JSONField( + null=True, + default=None, + help_text="The raw default value in API request format.", + ) + field_type = models.CharField( + max_length=64, + null=True, + help_text="The field type identifier at the time the value was stored. " + "Used to detect incompatibility when the field type changes.", + ) + function = models.CharField( + max_length=64, + null=True, + help_text="Optional function name (e.g. 'now') to resolve the default " + "value dynamically at row creation time instead of using the " + "stored value.", + ) + + class Meta: + constraints = [ + models.UniqueConstraint( + fields=["view", "field"], name="unique_view_field_default_value" + ) + ] + ordering = ("id",) + + def get_parent(self): + return self.view diff --git a/backend/src/baserow/contrib/database/views/operations.py b/backend/src/baserow/contrib/database/views/operations.py index a6cc0d334c..46a5a31422 100644 --- a/backend/src/baserow/contrib/database/views/operations.py +++ b/backend/src/baserow/contrib/database/views/operations.py @@ -148,6 +148,14 @@ class UpdateViewFieldOptionsOperationType(ViewOperationType): type = "database.table.view.update_field_options" +class ReadViewDefaultValuesOperationType(ViewOperationType): + type = "database.table.view.read_default_values" + + +class UpdateViewDefaultValuesOperationType(ViewOperationType): + type = "database.table.view.update_default_values" + + class UpdateViewOperationType(ViewOperationType): type = "database.table.view.update" diff --git a/backend/src/baserow/contrib/database/views/registries.py b/backend/src/baserow/contrib/database/views/registries.py index 981fad26bb..122f2ef444 100644 --- a/backend/src/baserow/contrib/database/views/registries.py +++ b/backend/src/baserow/contrib/database/views/registries.py @@ -151,6 +151,12 @@ def get_api_urls(self): fetch rows from the view. """ + can_set_default_values = True + """ + Indicates if the view supports setting default row values. If not, it will not + be possible to configure default values for rows created in this view. + """ + has_public_info = False """ Indicates if the view supports public information being returned by @@ -306,6 +312,13 @@ def export_serialized( if self.can_share: serialized["public"] = view.public + if self.can_set_default_values and view.table_id is not None: + default_row_values = self._export_default_row_values( + view, cache, files_zip, storage + ) + if default_row_values: + serialized["default_row_values"] = default_row_values + # It could be that there is no `table` related to the view when doing an # Airtable export, for example. That means it's not part of a workspace, so we # can't enhance the export with the `serialization_processor_registry`. @@ -421,6 +434,11 @@ def import_serialized( decorations = ( serialized_copy.pop("decorations", []) if self.can_decorate else [] ) + default_row_values_data = ( + serialized_copy.pop("default_row_values", None) + if self.can_set_default_values + else None + ) view = self.model_class(table=table) # Only set the properties that are actually accepted by the view type's model @@ -523,6 +541,16 @@ def import_serialized( view_decoration_object.id ) + if self.can_set_default_values and default_row_values_data: + self._import_default_row_values( + table, + view, + default_row_values_data, + id_mapping, + files_zip, + storage, + ) + for ( serialized_structure_processor ) in serialization_processor_registry.get_all(): @@ -532,6 +560,83 @@ def import_serialized( return view + def _export_default_row_values(self, view, cache, files_zip, storage): + """ + Exports the default row values for the given view as a serialized dict. + Uses the prefetched ``view_default_values`` related manager when + available to avoid extra queries during batch exports. The raw JSON + value is exported as-is since it is already serializable. + """ + + default_values = view.view_default_values.all() + if not default_values: + return None + + serialized_values = {} + for default_value in default_values: + serialized_values[str(default_value.field_id)] = { + "field_id": default_value.field_id, + "enabled": default_value.enabled, + "value": default_value.value, + "function": default_value.function, + "field_type": default_value.field_type, + } + + return serialized_values + + def _import_default_row_values( + self, + table, + view, + default_row_values, + id_mapping, + files_zip, + storage, + ): + """ + Imports the default row values from a serialized dict using + ``bulk_create`` for efficiency. Values are remapped through + the field type's ``import_serialized_default_value`` hook so + that IDs (e.g. select option IDs) point to the newly created + objects. + """ + + from baserow.contrib.database.views.models import ViewDefaultValue + + model = table.get_model() + records = [] + + for _old_field_id, default_value_data in default_row_values.items(): + old_field_id = default_value_data["field_id"] + new_field_id = id_mapping["database_fields"].get(old_field_id) + if new_field_id is None: + continue + + if new_field_id not in model._field_objects: + continue + + field_obj = model._field_objects[new_field_id] + field_type = field_obj["type"] + field_type_str = field_type.type + + value = default_value_data.get("value") + if value is not None: + value = field_type.import_serialized_default_value(value, id_mapping) + + records.append( + ViewDefaultValue( + view_id=view.id, + field_id=new_field_id, + enabled=default_value_data.get("enabled", True), + function=default_value_data.get("function"), + value=value, + field_type=default_value_data.get("field_type", field_type_str), + ) + ) + + if records: + ViewDefaultValue.objects.bulk_create(records) + def get_visible_fields_and_model( self, view: "View" ) -> Tuple[List["FieldObject"], django_models.Model]: @@ -1467,7 +1572,10 @@ def enforce_apply_filters(self, user: Optional[AbstractUser], view: "View") -> b return False def prepare_views_for_user( - self, user: Optional[AbstractUser], views: List["View"] + self, + user: Optional[AbstractUser], + views: List["View"], + includes: Optional[Set[str]] = None, ) -> List["View"]: """ A hook that can be used to make changes to the provided view objects `views` if @@ -1477,6 +1585,11 @@ def prepare_views_for_user( :param user: The user on whose behalf the view objects are enhanced. Can be used for permission checking. Note that it's not always provided. :param views: The views to enhance. + :param includes: Optional set of field names that the serializer will + include in the response (e.g. ``{"filters", "sortings", + "default_row_values"}``). When provided, implementations should + skip work for fields that are not in the set so that no unnecessary + queries are executed. ``None`` means "unknown / include everything". :return: The enhanced views. """ @@ -1537,7 +1650,10 @@ class ViewOwnershipTypeRegistry(Registry): does_not_exist_exception_class = ViewOwnershipTypeDoesNotExist def prepare_views_of_different_types_for_user( - self, user: AbstractUser, views: List["View"] + self, + user: AbstractUser, + views: List["View"], + includes: Optional[Set[str]] = None, ) -> List["View"]: """ Loops over the provided views and per ownership type, calls the @@ -1546,6 +1662,9 @@ def prepare_views_of_different_types_for_user( :param user: The user on whose behalf the views are requested. Can be used for permission checks. :param views: The views that must be enhanced. + :param includes: Optional set of field names that will be included in the + response. Passed through to each ownership type's + ``prepare_views_for_user`` so it can skip unnecessary work. :return: The enhanced views. """ @@ -1556,7 +1675,7 @@ def prepare_views_of_different_types_for_user( if view.ownership_type == view_ownership_type.type ] views_of_type = view_ownership_type.prepare_views_for_user( - user, views_of_type + user, views_of_type, includes=includes ) # Put the enhanced view back into the original list at the right index so # that the order is not changed. diff --git a/backend/src/baserow/contrib/database/views/view_ownership_types.py b/backend/src/baserow/contrib/database/views/view_ownership_types.py index e016092fe8..fce3a0e5e9 100644 --- a/backend/src/baserow/contrib/database/views/view_ownership_types.py +++ b/backend/src/baserow/contrib/database/views/view_ownership_types.py @@ -1,7 +1,12 @@ +from typing import List, Optional, Set + from django.contrib.auth.models import AbstractUser from baserow.contrib.database.views.models import View -from baserow.contrib.database.views.operations import UpdateViewOperationType +from baserow.contrib.database.views.operations import ( + ReadViewDefaultValuesOperationType, + UpdateViewOperationType, +) from baserow.contrib.database.views.registries import ViewOwnershipType from baserow.core.handler import CoreHandler @@ -27,3 +32,37 @@ def change_ownership_type(self, user: AbstractUser, view: View) -> View: ) view.owned_by = user return view + + def prepare_views_for_user( + self, + user: Optional[AbstractUser], + views: List[View], + includes: Optional[Set[str]] = None, + ) -> List[View]: + if not views or user is None: + return views + + # Skip work entirely when default_row_values is not requested. + if includes is not None and "default_row_values" not in includes: + return views + + # All collaborative views in the same table share the same permissions, + # so a single check using the first view is sufficient. + can_read_default_values = CoreHandler().check_permissions( + user, + ReadViewDefaultValuesOperationType.type, + workspace=views[0].table.database.workspace, + context=views[0], + raise_permission_exceptions=False, + ) + for view in views: + if not hasattr(view, "_prefetched_objects_cache"): + view._prefetched_objects_cache = {} + if not can_read_default_values: + view._prefetched_objects_cache["view_default_values"] = [] + elif "view_default_values" not in view._prefetched_objects_cache: + view._prefetched_objects_cache["view_default_values"] = list( + view.view_default_values.all() + ) + + return views diff --git a/backend/src/baserow/contrib/database/views/view_types.py b/backend/src/baserow/contrib/database/views/view_types.py index c916466dc0..7d26811ced 100644 --- a/backend/src/baserow/contrib/database/views/view_types.py +++ b/backend/src/baserow/contrib/database/views/view_types.py @@ -584,6 +584,7 @@ class FormViewType(ViewType): can_sort = False can_share = True can_list_rows = False + can_set_default_values = False restrict_link_row_public_view_sharing = False when_shared_publicly_requires_realtime_events = False field_options_model_class = FormViewFieldOptions diff --git a/backend/src/baserow/contrib/database/ws/public/fields/signals.py b/backend/src/baserow/contrib/database/ws/public/fields/signals.py index a918b68a54..42dd35b2a6 100644 --- a/backend/src/baserow/contrib/database/ws/public/fields/signals.py +++ b/backend/src/baserow/contrib/database/ws/public/fields/signals.py @@ -10,6 +10,7 @@ from baserow.contrib.database.views.models import View from baserow.contrib.database.views.registries import view_type_registry from baserow.contrib.database.ws.fields.signals import RealtimeFieldMessages +from baserow.core.cache import local_cache from baserow.core.db import specific_iterator from baserow.ws.registries import page_registry @@ -47,57 +48,90 @@ def _send_payload_to_public_views_where_field_not_hidden( ) +def _get_public_views_with_hidden_fields( + table_id: int, + field_ids: Optional[List[int]] = None, +) -> List[Tuple[View, Set[int]]]: + """ + Returns the public views for a table with their hidden field sets. Results + are cached in the request-scoped local_cache so that repeated calls for the + same table within a single request don't re-query. + + :param table_id: The id of the table to get the views for. + :param field_ids: When provided, only calculate the hidden fields for these + field ids, otherwise calculate for all fields in the table. + :return: A list of (view, hidden_field_ids) tuples for all public views of the + """ + + def _fetch() -> List[Tuple[View, Set[int]]]: + nonlocal field_ids + + views_qs = ( + View.objects.filter(public=True, table_id=table_id) + .select_related("table__database__workspace") + .prefetch_related("table__field_set") + ) + + specific_views = specific_iterator( + views_qs, + per_content_type_queryset_hook=( + lambda model, queryset: view_type_registry.get_by_model( + model + ).enhance_queryset(queryset) + ), + ) + if not specific_views: + return [] + elif not field_ids: + table = specific_views[0].table + field_ids = [f.id for f in table.field_set.all()] + + result = [] + for view in specific_views: + view = view.specific + view_type = view_type_registry.get_by_model(view) + if not view_type.when_shared_publicly_requires_realtime_events: + continue + + hidden_field_ids = view_type.get_hidden_fields(view, field_ids) + result.append((view, hidden_field_ids)) + + return result + + return local_cache.get( + f"public_views_with_hidden_fields_{table_id}_{field_ids}", + default=_fetch, + ) + + def _get_views_where_field_visible_and_hidden_fields_in_view( field: Field, hidden_fields_field_ids_filter: Optional[Iterable[int]] = None, ) -> List[Tuple[View, Set[int]]]: """ - Finds all views where field is visible and also attaches the set of fields which - are hidden in said view. - - :param field: All views where this field is visible will be returned. - :param hidden_fields_field_ids_filter: An optional filter which restricts the - calculation of whether a field is hidden or not in a returned view down to just - checking the fields in this iterable. - :return: A list of tuples where the first value is a view where field is visible - and the second is the set of field ids which are hidden in said view. + Finds all public views where field is visible, along with the set of hidden + field ids in each view. + + :param field: The field to check visibility for. + :param hidden_fields_field_ids_filter: When provided, restricts hidden field + calculation to just these field ids plus the field itself. + :return: A list of (view, hidden_field_ids) tuples for views where field is + visible. """ - views_with_prefetched_fields = View.objects.filter( - public=True, table_id=field.table_id - ).prefetch_related("table__field_set") - - specific_views = specific_iterator( - views_with_prefetched_fields, - per_content_type_queryset_hook=( - lambda model, queryset: view_type_registry.get_by_model( - model - ).enhance_queryset(queryset) - ), + field_ids = ( + list({field.id, *hidden_fields_field_ids_filter}) + if hidden_fields_field_ids_filter + else None ) - if len(specific_views) == 0: - return [] - - if hidden_fields_field_ids_filter is None: - table = specific_views[0].table - all_field_ids = table.field_set.values_list("id", flat=True) - restrict_hidden_check_to_field_ids = all_field_ids - else: - restrict_hidden_check_to_field_ids = [field.id, *hidden_fields_field_ids_filter] - - views_where_field_was_visible = [] - for view in specific_views: - view = view.specific - view_type = view_type_registry.get_by_model(view) - if not view_type.when_shared_publicly_requires_realtime_events: - continue - - hidden_field_ids = view_type.get_hidden_fields( - view, restrict_hidden_check_to_field_ids - ) - if field.id not in hidden_field_ids: - views_where_field_was_visible.append((view, hidden_field_ids)) - return views_where_field_was_visible + views_with_hidden = _get_public_views_with_hidden_fields( + field.table_id, field_ids=field_ids + ) + return [ + (view, hidden_field_ids) + for view, hidden_field_ids in views_with_hidden + if field.id not in hidden_field_ids + ] @receiver(field_signals.field_created) diff --git a/backend/src/baserow/contrib/database/ws/public/rows/view_realtime_rows.py b/backend/src/baserow/contrib/database/ws/public/rows/view_realtime_rows.py index a7ce3901f0..4191f6796f 100644 --- a/backend/src/baserow/contrib/database/ws/public/rows/view_realtime_rows.py +++ b/backend/src/baserow/contrib/database/ws/public/rows/view_realtime_rows.py @@ -13,7 +13,7 @@ class PublicViewRealtimeRowsType(ViewRealtimeRowsType): def get_views_filter(self) -> Q: return Q(public=True) - def broadcast(self, view, payload): + def broadcast(self, view, payload, user=None): view_page_type = page_registry.get("view") payload = deepcopy(payload) payload["table_id"] = PUBLIC_PLACEHOLDER_ENTITY_ID diff --git a/backend/src/baserow/contrib/database/ws/views/rows/handler.py b/backend/src/baserow/contrib/database/ws/views/rows/handler.py index c7d9c8c16b..6b43e05405 100644 --- a/backend/src/baserow/contrib/database/ws/views/rows/handler.py +++ b/backend/src/baserow/contrib/database/ws/views/rows/handler.py @@ -69,15 +69,17 @@ def get_views_row_checker( updated_field_ids, ) - def broadcast_to_types(self, view: View, payload: Dict): + def broadcast_to_types(self, view: View, payload: Dict, user=None): """ Helper method that broadcasts the provided payload using the ViewRealtimeRows type, if the view matches the filter. :param view: The view object where to broadcast the payload to. :param payload: The payload that must be broadcasted. + :param user: The user that triggered the event. Passed through to the + broadcast method so that the original sender can be excluded. """ for t in view_realtime_rows_registry.get_all(): if getattr(view, self._is_name(t.type), False): - t.broadcast(view, payload) + t.broadcast(view, payload, user=user) diff --git a/backend/src/baserow/contrib/database/ws/views/rows/registries.py b/backend/src/baserow/contrib/database/ws/views/rows/registries.py index ceb4da3f56..830e3214b5 100644 --- a/backend/src/baserow/contrib/database/ws/views/rows/registries.py +++ b/backend/src/baserow/contrib/database/ws/views/rows/registries.py @@ -24,7 +24,7 @@ def get_views_filter(self) -> Q: "instance." ) - def broadcast(self, view, payload): + def broadcast(self, view, payload, user=None): """ Called when a payload must be broadcasted to a view. The code should look like: @@ -39,6 +39,8 @@ def broadcast(self, view, payload): :param view: The view where to broadcast to. :param payload: The row created, updated, or deleted payload that must be broadcasted. + :param user: The user that triggered the event. When provided, the broadcast + can exclude the original sender so they don't receive their own event. """ raise NotImplementedError( diff --git a/backend/src/baserow/contrib/database/ws/views/rows/signals.py b/backend/src/baserow/contrib/database/ws/views/rows/signals.py index f98c27417a..a23256abf3 100644 --- a/backend/src/baserow/contrib/database/ws/views/rows/signals.py +++ b/backend/src/baserow/contrib/database/ws/views/rows/signals.py @@ -25,6 +25,7 @@ def _send_rows_created_event_to_views( serialized_rows: List[Dict[Any, Any]], before: Optional[GeneratedTableModel], views: List[FilteredViewRows], + user=None, ): view_handler = ViewHandler() view_realtime_rows_handler = ViewRealtimeRowsHandler() @@ -43,13 +44,14 @@ def _send_rows_created_event_to_views( metadata={}, before=before, ) - view_realtime_rows_handler.broadcast_to_types(view, payload) + view_realtime_rows_handler.broadcast_to_types(view, payload, user=user) @baserow_trace(tracer) def _send_rows_deleted_event_to_views( serialized_deleted_rows: List[Dict[Any, Any]], views: List[FilteredViewRows], + user=None, ): view_handler = ViewHandler() view_realtime_rows_handler = ViewRealtimeRowsHandler() @@ -66,7 +68,7 @@ def _send_rows_deleted_event_to_views( table_id=view.table_id, serialized_rows=restricted_serialized_deleted_rows, ) - view_realtime_rows_handler.broadcast_to_types(view, payload) + view_realtime_rows_handler.broadcast_to_types(view, payload, user=user) @receiver(row_signals.rows_created) @@ -93,6 +95,7 @@ def views_rows_created( serialize_rows_for_response(rows, model), before, row_checker.get_filtered_views_where_rows_are_visible(rows), + user=user, ), ) @@ -124,7 +127,9 @@ def views_rows_deleted( "deleted_rows" ] transaction.on_commit( - lambda: _send_rows_deleted_event_to_views(serialized_deleted_rows, views) + lambda: _send_rows_deleted_event_to_views( + serialized_deleted_rows, views, user=user + ) ) @@ -235,12 +240,13 @@ def views_rows_updated( @baserow_trace(tracer) def _send_created_updated_deleted_row_signals_to_views(): _send_rows_deleted_event_to_views( - serialized_old_rows, views_where_rows_were_deleted + serialized_old_rows, views_where_rows_were_deleted, user=user ) _send_rows_created_event_to_views( serialized_updated_rows, before=None, views=views_where_rows_were_created, + user=user, ) view_handler = ViewHandler() @@ -260,6 +266,6 @@ def _send_created_updated_deleted_row_signals_to_views(): updated_field_ids=list(updated_field_ids), metadata={}, ) - view_realtime_rows_handler.broadcast_to_types(view, payload) + view_realtime_rows_handler.broadcast_to_types(view, payload, user=user) transaction.on_commit(_send_created_updated_deleted_row_signals_to_views) diff --git a/backend/src/baserow/contrib/database/ws/views/signals.py b/backend/src/baserow/contrib/database/ws/views/signals.py index 656bf72b07..0880f5d5ee 100644 --- a/backend/src/baserow/contrib/database/ws/views/signals.py +++ b/backend/src/baserow/contrib/database/ws/views/signals.py @@ -1,4 +1,5 @@ from django.db import transaction +from django.db.models import prefetch_related_objects from django.dispatch import receiver from baserow.contrib.database.api.views.serializers import ( @@ -18,7 +19,18 @@ from baserow.ws.tasks import broadcast_to_users +def _prefetch_view_default_values(view): + """Prefetches view_default_values for efficient serialization.""" + + if ( + not hasattr(view, "_prefetched_objects_cache") + or "view_default_values" not in view._prefetched_objects_cache + ): + prefetch_related_objects([view], "view_default_values") + + def generate_view_created_payload(user, view): + _prefetch_view_default_values(view) payload = { "type": "view_created", "view": view_type_registry.get_serializer( @@ -28,6 +40,7 @@ def generate_view_created_payload(user, view): sortings=True, decorations=True, group_bys=True, + default_row_values=True, context={"user": user}, ).data, } @@ -148,6 +161,7 @@ def broadcast_to_users_ownership_change(user, new_view, old_view, payload): @receiver(view_signals.view_updated) def view_updated(sender, view, old_view, user, **kwargs): + _prefetch_view_default_values(view) payload = { "type": "view_updated", "view_id": view.id, @@ -162,6 +176,7 @@ def view_updated(sender, view, old_view, user, **kwargs): sortings=False, decorations=False, group_bys=False, + default_row_values=True, context={"user": user}, ).data, } diff --git a/backend/templates/project-management.json b/backend/templates/project-management.json index c7f1469caf..cdfb3a15ba 100644 --- a/backend/templates/project-management.json +++ b/backend/templates/project-management.json @@ -17,740 +17,10154 @@ "Project Management", "🔥 Most Popular" ], + "open_application": 343, "export": [ { - "id": 94962, + "id": 342, "name": "Project Management", "order": 1, "type": "database", "tables": [ { - "id": 261761, - "name": "Projects", - "order": 2, + "id": 954, + "name": "Users", + "order": 1, "fields": [ { - "id": 1859518, + "id": 8966, "type": "text", "name": "Name", + "description": null, "order": 0, "primary": true, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], "text_default": "" }, { - "id": 1859519, - "type": "single_select", - "name": "Category", + "id": 8967, + "type": "email", + "name": "Email", + "description": null, "order": 1, "primary": false, - "select_options": [ - { - "id": 1386715, - "value": "Design", - "color": "blue", - "order": 0 - }, - { - "id": 1386716, - "value": "Development", - "color": "red", - "order": 1 - }, - { - "id": 1386717, - "value": "Research", - "color": "orange", - "order": 2 - }, - { - "id": 1386718, - "value": "Marketing", - "color": "green", - "order": 3 - } - ] + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [] }, { - "id": 1859521, - "type": "link_row", - "name": "Client", - "order": 3, + "id": 8968, + "type": "phone_number", + "name": "Phone", + "description": null, + "order": 2, "primary": false, - "link_row_table_id": 261763, - "link_row_related_field_id": 1859536, - "has_related_field": true + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [] }, { - "id": 1859522, - "type": "link_row", - "name": "Project lead", - "order": 4, + "id": 8969, + "type": "file", + "name": "Picture", + "description": null, + "order": 3, "primary": false, - "link_row_table_id": 261764, - "link_row_related_field_id": 1859542, - "has_related_field": true + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [] }, { - "id": 1859523, + "id": 8970, "type": "link_row", - "name": "Project team", - "order": 5, - "primary": false, - "link_row_table_id": 261764, - "link_row_related_field_id": 1859543, - "has_related_field": true - }, - { - "id": 1859524, - "type": "rollup", - "name": "Start", + "name": "Projects - Owner", + "description": null, "order": 6, "primary": false, - "date_time_format": "24", - "duration_format": null, - "nullable": true, - "error": null, - "date_include_time": false, - "date_show_tzinfo": false, - "date_force_timezone": null, - "number_decimal_places": null, - "array_formula_type": null, - "date_format": "ISO", - "through_field_id": 1859527, - "target_field_id": 1859559, - "rollup_function": "min" - }, - { - "id": 1859525, - "type": "rollup", - "name": "End", - "order": 7, - "primary": false, - "date_time_format": "24", - "duration_format": null, - "nullable": true, - "error": null, - "date_include_time": false, - "date_show_tzinfo": false, - "date_force_timezone": null, - "number_decimal_places": null, - "array_formula_type": null, - "date_format": "ISO", - "through_field_id": 1859527, - "target_field_id": 1859562, - "rollup_function": "max" - }, - { - "id": 1859526, - "type": "long_text", - "name": "Description", - "order": 8, - "primary": false, - "long_text_enable_rich_text": false + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "link_row_table_id": 955, + "link_row_related_field_id": 8974, + "link_row_limit_selection_view_id": null, + "has_related_field": true, + "link_row_multiple_relationships": true }, { - "id": 1859527, + "id": 8971, "type": "link_row", - "name": "Tasks", + "name": "Tasks - Assignee", + "description": null, "order": 9, "primary": false, - "link_row_table_id": 261762, - "link_row_related_field_id": 1859530, - "has_related_field": true - }, - { - "id": 1859528, - "type": "number", - "name": "Budget", - "order": 10, - "primary": false, - "number_decimal_places": 0, - "number_negative": false - }, - { - "id": 1859556, - "type": "file", - "name": "Contract", - "order": 11, - "primary": false - }, - { - "id": 1859557, - "type": "lookup", - "name": "Client contact", - "order": 12, - "primary": false, - "date_time_format": null, - "duration_format": null, - "nullable": true, - "error": null, - "date_include_time": null, - "date_show_tzinfo": null, - "date_force_timezone": null, - "number_decimal_places": null, - "array_formula_type": "char", - "date_format": null, - "through_field_id": 1859521, - "through_field_name": "Client", - "target_field_id": 1859539, - "target_field_name": "Contact email" - }, - { - "id": 1859572, - "type": "count", - "name": "Tasks count", - "order": 13, - "primary": false, - "date_time_format": null, - "duration_format": null, - "nullable": false, - "error": null, - "date_include_time": null, - "date_show_tzinfo": null, - "date_force_timezone": null, - "number_decimal_places": 0, - "array_formula_type": null, - "date_format": null, - "through_field_id": 1859527 + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "link_row_table_id": 957, + "link_row_related_field_id": 8987, + "link_row_limit_selection_view_id": null, + "has_related_field": true, + "link_row_multiple_relationships": true }, { - "id": 1859573, + "id": 9005, "type": "formula", - "name": "Tasks completed", - "order": 14, + "name": "Open workload", + "description": null, + "order": 10, "primary": false, - "date_time_format": null, - "duration_format": null, - "nullable": false, - "error": null, - "date_include_time": null, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], "date_show_tzinfo": null, - "date_force_timezone": null, + "number_prefix": "", + "number_separator": "", "number_decimal_places": 0, - "array_formula_type": null, - "date_format": null, - "formula": "count(filter(lookup('Tasks','Status'),lookup('Tasks','Status') = 'Completed'))", - "formula_type": "number" - }, - { - "id": 1859574, - "type": "formula", - "name": "Completion ratio %", - "order": 15, - "primary": false, - "date_time_format": null, + "number_suffix": "hours", "duration_format": null, "nullable": false, - "error": null, - "date_include_time": null, - "date_show_tzinfo": null, - "date_force_timezone": null, - "number_decimal_places": 0, - "array_formula_type": null, - "date_format": null, - "formula": "round(field('Tasks completed') / field('Tasks count') * 100,0)", - "formula_type": "number" - }, - { - "id": 1859575, - "type": "formula", - "name": "Completed", - "order": 16, - "primary": false, "date_time_format": null, - "duration_format": null, - "nullable": false, - "error": null, - "date_include_time": null, - "date_show_tzinfo": null, "date_force_timezone": null, - "number_decimal_places": null, "array_formula_type": null, - "date_format": null, - "formula": "field('Completion ratio %') = 100", - "formula_type": "boolean" - }, - { - "id": 1859586, - "type": "formula", - "name": "Client name", - "order": 17, - "primary": false, - "date_time_format": null, - "duration_format": null, - "nullable": false, "error": null, - "date_include_time": null, - "date_show_tzinfo": null, - "date_force_timezone": null, - "number_decimal_places": null, - "array_formula_type": null, "date_format": null, - "formula": "join(lookup('Client','Company name'),'')", - "formula_type": "text" - }, - { - "id": 1859644, - "type": "formula", - "name": "Active", - "order": 18, - "primary": false, - "date_time_format": null, - "duration_format": null, - "nullable": false, - "error": null, "date_include_time": null, - "date_show_tzinfo": null, - "date_force_timezone": null, - "number_decimal_places": null, - "array_formula_type": null, - "date_format": null, - "formula": "and(field('Start') < now(),or(not(field('Completed')),field('End') > now()))", - "formula_type": "boolean" + "formula": "sum(filter(lookup('Tasks - Assignee','Estimated workload'),lookup('Tasks - Assignee','Status') != 'Done'))", + "formula_type": "number" } ], "views": [ { - "id": 437938, + "id": 3987, "type": "grid", - "name": "All projects", + "name": "All users", "order": 1, "ownership_type": "collaborative", - "owned_by": null, + "owned_by": "frederik@baserow.io", "filter_type": "AND", "filters_disabled": false, "filters": [], "filter_groups": [], - "sortings": [ - { - "id": 162272, - "field_id": 1859525, - "order": "ASC" - } - ], + "sortings": [], "group_bys": [], "decorations": [], "public": false, "row_identifier_type": "id", + "row_height_size": "small", "field_options": [ { - "id": 3032696, - "field_id": 1859526, - "width": 238, + "id": 33070, + "field_id": 8966, + "width": 214, "hidden": false, "order": 0, "aggregation_type": "", "aggregation_raw_type": "" }, { - "id": 3032689, - "field_id": 1859519, - "width": 137, + "id": 33071, + "field_id": 8967, + "width": 261, "hidden": false, "order": 1, "aggregation_type": "", "aggregation_raw_type": "" }, { - "id": 3032698, - "field_id": 1859528, - "width": 118, - "hidden": false, - "order": 2, - "aggregation_type": "sum", - "aggregation_raw_type": "sum" - }, - { - "id": 3032694, - "field_id": 1859524, - "width": 110, + "id": 33072, + "field_id": 8968, + "width": 141, "hidden": false, "order": 3, - "aggregation_type": "min_date", - "aggregation_raw_type": "min" - }, - { - "id": 3032695, - "field_id": 1859525, - "width": 129, - "hidden": false, - "order": 4, - "aggregation_type": "max_date", - "aggregation_raw_type": "max" - }, - { - "id": 3032776, - "field_id": 1859556, - "width": 126, - "hidden": false, - "order": 5, "aggregation_type": "", "aggregation_raw_type": "" }, { - "id": 3032691, - "field_id": 1859521, - "width": 165, + "id": 33073, + "field_id": 8969, + "width": 108, "hidden": false, - "order": 6, + "order": 4, "aggregation_type": "", "aggregation_raw_type": "" }, { - "id": 3032777, - "field_id": 1859557, - "width": 168, + "id": 33074, + "field_id": 8970, + "width": 200, "hidden": false, "order": 7, "aggregation_type": "", "aggregation_raw_type": "" }, { - "id": 3032692, - "field_id": 1859522, - "width": 146, + "id": 33075, + "field_id": 8971, + "width": 177, "hidden": false, - "order": 8, + "order": 11, "aggregation_type": "", "aggregation_raw_type": "" }, { - "id": 3032693, - "field_id": 1859523, - "width": 149, + "id": 33076, + "field_id": 9005, + "width": 157, "hidden": false, - "order": 9, + "order": 32767, "aggregation_type": "", "aggregation_raw_type": "" - }, + } + ] + }, + { + "id": 3988, + "type": "grid", + "name": "Team leaders", + "order": 2, + "ownership_type": "collaborative", + "owned_by": "frederik@baserow.io", + "filter_type": "AND", + "filters_disabled": false, + "filters": [], + "filter_groups": [], + "sortings": [], + "group_bys": [], + "decorations": [], + "public": false, + "row_identifier_type": "id", + "row_height_size": "small", + "field_options": [ { - "id": 3032688, - "field_id": 1859518, - "width": 292, + "id": 33077, + "field_id": 8966, + "width": 172, "hidden": false, - "order": 10, + "order": 0, "aggregation_type": "", "aggregation_raw_type": "" }, { - "id": 3032697, - "field_id": 1859527, - "width": 200, - "hidden": true, - "order": 11, + "id": 33078, + "field_id": 8967, + "width": 260, + "hidden": false, + "order": 1, "aggregation_type": "", "aggregation_raw_type": "" }, { - "id": 3032788, - "field_id": 1859572, - "width": 158, + "id": 33079, + "field_id": 8968, + "width": 141, "hidden": false, - "order": 12, + "order": 3, "aggregation_type": "", "aggregation_raw_type": "" }, { - "id": 3032789, - "field_id": 1859573, - "width": 178, + "id": 33080, + "field_id": 8969, + "width": 108, "hidden": false, - "order": 13, + "order": 4, "aggregation_type": "", "aggregation_raw_type": "" }, { - "id": 3032790, - "field_id": 1859574, - "width": 197, + "id": 33081, + "field_id": 8970, + "width": 200, "hidden": false, - "order": 14, + "order": 7, "aggregation_type": "", "aggregation_raw_type": "" }, { - "id": 3032791, - "field_id": 1859575, - "width": 143, + "id": 33082, + "field_id": 8971, + "width": 200, "hidden": false, - "order": 32767, + "order": 11, "aggregation_type": "", "aggregation_raw_type": "" - }, - { - "id": 3032861, - "field_id": 1859586, + } + ] + } + ], + "rows": [ + { + "id": 1, + "order": "1.00000000000000000000", + "created_on": "2026-01-13T13:14:45.548642+00:00", + "updated_on": "2026-01-14T10:16:45.770425+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8966": "Allie Ecker", + "field_8967": "allie.ecker@example.com", + "field_8968": "(949) 873-7292", + "field_8969": [ + { + "name": "kLWDrhYrAqVTdm4bN3nfAvOfC7Ilmi0f_87342f8e2a009873f0cf6cbf8b480d495c898a19238d60b3d6fb81efa41c9883.jpg", + "visible_name": "Woman.12.jpg", + "original_name": "kLWDrhYrAqVTdm4bN3nfAvOfC7Ilmi0f_87342f8e2a009873f0cf6cbf8b480d495c898a19238d60b3d6fb81efa41c9883.jpg", + "size": 46504 + } + ], + "field_8970": [], + "field_8971": [ + 30, + 28, + 26, + 18 + ], + "field_9005": null + }, + { + "id": 2, + "order": "2.00000000000000000000", + "created_on": "2026-01-13T13:14:45.548714+00:00", + "updated_on": "2026-01-30T16:08:25.538032+00:00", + "created_by": "frederik@baserow.io", + "field_8966": "Bran Lopez", + "field_8967": "bran.lopez@example.com", + "field_8968": "(650) 869-3623", + "field_8969": [ + { + "name": "vLs95KtwlBaxTku2uV6I4QNvkMz9YARa_d022b4d76cc31161673cb1f62b4d1984dc8db57d5d7b62b46ff73de4fde45cfd.jpg", + "visible_name": "Man.20.jpg", + "original_name": "vLs95KtwlBaxTku2uV6I4QNvkMz9YARa_d022b4d76cc31161673cb1f62b4d1984dc8db57d5d7b62b46ff73de4fde45cfd.jpg", + "size": 42815 + } + ], + "field_8970": [ + 1 + ], + "field_8971": [ + 1, + 2, + 3 + ], + "field_9005": null + }, + { + "id": 3, + "order": "3.00000000000000000000", + "created_on": "2026-01-13T13:16:49.251170+00:00", + "updated_on": "2026-01-14T10:16:48.709438+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8966": "Cinda Pullen", + "field_8967": "cinda.pullen@example.com", + "field_8968": "(213) 743-1636", + "field_8969": [ + { + "name": "crdLECtmaJUsIG2AP16rpuRjbDahswwt_32a0bb1e8cd43f9a27f05e95039ad44b606915d94c3f6ac8aa9359a5d66d0e40.jpg", + "visible_name": "Woman.36.jpg", + "original_name": "crdLECtmaJUsIG2AP16rpuRjbDahswwt_32a0bb1e8cd43f9a27f05e95039ad44b606915d94c3f6ac8aa9359a5d66d0e40.jpg", + "size": 40189 + } + ], + "field_8970": [ + 3 + ], + "field_8971": [ + 32, + 38 + ], + "field_9005": null + }, + { + "id": 4, + "order": "4.00000000000000000000", + "created_on": "2026-01-13T13:16:49.251250+00:00", + "updated_on": "2026-01-14T10:16:49.884015+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8966": "Clayton Best", + "field_8967": "clayton.best@example.com", + "field_8968": "(916) 478-0153", + "field_8969": [ + { + "name": "vvFlrceI4CIgDdGrKA1UGd1yfBIpfY1S_636d58571a3d01fad628780775449b7c9fe67e40a5d2154ffeed3cccec5bd2f0.jpg", + "visible_name": "Man.33.jpg", + "original_name": "vvFlrceI4CIgDdGrKA1UGd1yfBIpfY1S_636d58571a3d01fad628780775449b7c9fe67e40a5d2154ffeed3cccec5bd2f0.jpg", + "size": 30280 + } + ], + "field_8970": [], + "field_8971": [], + "field_9005": null + }, + { + "id": 5, + "order": "5.00000000000000000000", + "created_on": "2026-01-13T13:16:49.251293+00:00", + "updated_on": "2026-01-14T10:16:51.178046+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8966": "Donald Johns", + "field_8967": "donald.johns@example.com", + "field_8968": "(805) 367-1199", + "field_8969": [ + { + "name": "jSvWQ7liY4LPZkWbf0Bn4k0gs6IPvCTN_8bf30a876d0d0082aac1b41058c42c8ff2ab323e25afc56b9f5b9bab76cf3ea9.jpg", + "visible_name": "Man.48.jpg", + "original_name": "jSvWQ7liY4LPZkWbf0Bn4k0gs6IPvCTN_8bf30a876d0d0082aac1b41058c42c8ff2ab323e25afc56b9f5b9bab76cf3ea9.jpg", + "size": 44078 + } + ], + "field_8970": [], + "field_8971": [ + 19, + 20, + 21, + 24 + ], + "field_9005": null + }, + { + "id": 6, + "order": "6.00000000000000000000", + "created_on": "2026-01-13T13:16:49.251332+00:00", + "updated_on": "2026-01-14T10:16:52.409376+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8966": "Donald Wright", + "field_8967": "donald.wright@example.com", + "field_8968": "(925) 413-4033", + "field_8969": [ + { + "name": "gQ13I0YdSWa2oCyygMS6C96J61xP4GZR_706cb9712f46ff3654d0a1b873f9d20934da457ae1545f1bfdcfcc4f75c4f0fa.jpg", + "visible_name": "Man.09.jpg", + "original_name": "gQ13I0YdSWa2oCyygMS6C96J61xP4GZR_706cb9712f46ff3654d0a1b873f9d20934da457ae1545f1bfdcfcc4f75c4f0fa.jpg", + "size": 47186 + } + ], + "field_8970": [], + "field_8971": [], + "field_9005": null + }, + { + "id": 7, + "order": "7.00000000000000000000", + "created_on": "2026-01-13T13:16:49.251371+00:00", + "updated_on": "2026-01-14T10:16:53.962407+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8966": "Elizabeth Cunningham", + "field_8967": "elizabeth.cunningham@example.com", + "field_8968": "(323) 930-9329", + "field_8969": [ + { + "name": "bFkd4i1auIRx3BTmc9GaRY1qyy0wYI6B_6ad39d6d65565870ad02632ebc8f3103ef36c0004f787bc43df882383912bcf1.jpg", + "visible_name": "Woman.27.jpg", + "original_name": "bFkd4i1auIRx3BTmc9GaRY1qyy0wYI6B_6ad39d6d65565870ad02632ebc8f3103ef36c0004f787bc43df882383912bcf1.jpg", + "size": 61085 + } + ], + "field_8970": [ + 2 + ], + "field_8971": [], + "field_9005": null + }, + { + "id": 10, + "order": "10.00000000000000000000", + "created_on": "2026-01-13T13:16:49.251485+00:00", + "updated_on": "2026-01-14T10:16:55.299244+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8966": "Janice Fitzpatrick", + "field_8967": "janice.fitzpatrick@example.com", + "field_8968": "(510) 476-1189", + "field_8969": [ + { + "name": "ezXIA4yDZxdoMmMzPfJHp8LT1dqQ2pY8_6033c389c7b9a28b3f4d1ad791cd071bb18d341fb50ca862338d0688129b1d93.jpg", + "visible_name": "Woman.16.jpg", + "original_name": "ezXIA4yDZxdoMmMzPfJHp8LT1dqQ2pY8_6033c389c7b9a28b3f4d1ad791cd071bb18d341fb50ca862338d0688129b1d93.jpg", + "size": 67980 + } + ], + "field_8970": [], + "field_8971": [], + "field_9005": null + }, + { + "id": 11, + "order": "11.00000000000000000000", + "created_on": "2026-01-13T13:16:49.251521+00:00", + "updated_on": "2026-01-14T10:16:56.759160+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8966": "John Marshall", + "field_8967": "john.marshall@example.com", + "field_8968": "(323) 207-7576", + "field_8969": [ + { + "name": "tpR9K5hyGWdGRNHh1Iff07zyI0qF267n_5b771a1ce64c7ccb1b909d679a9a9cab06d2563777570d6990b609608a526283.jpg", + "visible_name": "Man.03.jpg", + "original_name": "tpR9K5hyGWdGRNHh1Iff07zyI0qF267n_5b771a1ce64c7ccb1b909d679a9a9cab06d2563777570d6990b609608a526283.jpg", + "size": 47886 + } + ], + "field_8970": [], + "field_8971": [ + 31, + 37 + ], + "field_9005": null + }, + { + "id": 12, + "order": "12.00000000000000000000", + "created_on": "2026-01-13T13:16:49.251558+00:00", + "updated_on": "2026-01-14T10:16:58.076364+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8966": "Jonathan Castillo", + "field_8967": "jonathan.castillo@example.com", + "field_8968": "(714) 674-5259", + "field_8969": [ + { + "name": "Rx6F1rjpaXPvzHKuVuuMbxzobiwx4a2P_3e4ea491bc171831d98bd16209e167056256efec656b03792cc985f56c52d625.jpg", + "visible_name": "Man.27.jpg", + "original_name": "Rx6F1rjpaXPvzHKuVuuMbxzobiwx4a2P_3e4ea491bc171831d98bd16209e167056256efec656b03792cc985f56c52d625.jpg", + "size": 37008 + } + ], + "field_8970": [], + "field_8971": [ + 17, + 27, + 23, + 22 + ], + "field_9005": null + }, + { + "id": 13, + "order": "13.00000000000000000000", + "created_on": "2026-01-13T13:16:49.251596+00:00", + "updated_on": "2026-01-14T10:16:59.061160+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8966": "Judith Triplett", + "field_8967": "judith.triplett@example.com", + "field_8968": "(323) 762-0628", + "field_8969": [ + { + "name": "O404Ff1TawAfAKvYWgOOp4hWaKSW15og_84455edcdf85e5bbcf4ea2c2e53253a70d2dc5003170a2bcb7adb2e06d319885.jpg", + "visible_name": "Woman.38.jpg", + "original_name": "O404Ff1TawAfAKvYWgOOp4hWaKSW15og_84455edcdf85e5bbcf4ea2c2e53253a70d2dc5003170a2bcb7adb2e06d319885.jpg", + "size": 54546 + } + ], + "field_8970": [], + "field_8971": [ + 36, + 35, + 34, + 33 + ], + "field_9005": null + }, + { + "id": 14, + "order": "14.00000000000000000000", + "created_on": "2026-01-13T13:16:49.251633+00:00", + "updated_on": "2026-01-14T10:17:00.690934+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8966": "Lane Mahon", + "field_8967": "lane.mahon@example.com", + "field_8968": "(925) 250-4627", + "field_8969": [ + { + "name": "MigrQOHs6ef3tBW7lfMZrROiO58AX2t2_7d55a7f32efd179a5dd35d905c33a80528c84e057c8c6ad07a6f190fd8a135b8.jpg", + "visible_name": "Man.18.jpg", + "original_name": "MigrQOHs6ef3tBW7lfMZrROiO58AX2t2_7d55a7f32efd179a5dd35d905c33a80528c84e057c8c6ad07a6f190fd8a135b8.jpg", + "size": 51628 + } + ], + "field_8970": [], + "field_8971": [ + 4, + 14, + 11, + 10, + 8, + 5 + ], + "field_9005": null + }, + { + "id": 15, + "order": "15.00000000000000000000", + "created_on": "2026-01-13T13:16:49.251669+00:00", + "updated_on": "2026-01-14T10:17:01.531557+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8966": "Latisha Mazon", + "field_8967": "latisha.mazon@example.com", + "field_8968": "(530) 540-8012", + "field_8969": [ + { + "name": "xYnZuzOAwXlYK10f2v2AnDpe9YLUySLE_64038313f395241c5d4d6615d9ba2d4d680777b263a811177230dbb5e391bd6c.jpg", + "visible_name": "Woman.46.jpg", + "original_name": "xYnZuzOAwXlYK10f2v2AnDpe9YLUySLE_64038313f395241c5d4d6615d9ba2d4d680777b263a811177230dbb5e391bd6c.jpg", + "size": 41851 + } + ], + "field_8970": [], + "field_8971": [], + "field_9005": null + }, + { + "id": 16, + "order": "16.00000000000000000000", + "created_on": "2026-01-13T13:16:49.251705+00:00", + "updated_on": "2026-01-14T10:17:02.809735+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8966": "Lena Hogan", + "field_8967": "lena.hogan@example.com", + "field_8968": "(559) 949-6790", + "field_8969": [ + { + "name": "HGnYKFYfe3XDvQZCSzvpNFzQP4Vpzn0S_623cf9aca2c33d047b0c4312716412c1265e6269631846fff2dfb1147070c8fd.jpg", + "visible_name": "Woman.17.jpg", + "original_name": "HGnYKFYfe3XDvQZCSzvpNFzQP4Vpzn0S_623cf9aca2c33d047b0c4312716412c1265e6269631846fff2dfb1147070c8fd.jpg", + "size": 57070 + } + ], + "field_8970": [], + "field_8971": [], + "field_9005": null + }, + { + "id": 17, + "order": "17.00000000000000000000", + "created_on": "2026-01-13T13:16:49.251741+00:00", + "updated_on": "2026-01-14T10:17:04.081197+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8966": "Leroy Tye", + "field_8967": "leroy.tye@example.com", + "field_8968": "(510) 808-7208", + "field_8969": [ + { + "name": "Wfsee8YlfaX6yYlfxXThnktu4YLcTlMV_9254445c723333fd7687daff449887a52d0178ff24e24af1c076144a7ba80b32.jpg", + "visible_name": "Man.02.jpg", + "original_name": "Wfsee8YlfaX6yYlfxXThnktu4YLcTlMV_9254445c723333fd7687daff449887a52d0178ff24e24af1c076144a7ba80b32.jpg", + "size": 51715 + } + ], + "field_8970": [], + "field_8971": [ + 6, + 7, + 9, + 12, + 13, + 15 + ], + "field_9005": null + }, + { + "id": 18, + "order": "18.00000000000000000000", + "created_on": "2026-01-13T13:16:49.251778+00:00", + "updated_on": "2026-01-14T10:17:05.176618+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8966": "Michael Robicheaux", + "field_8967": "michael.robicheaux@example.com", + "field_8968": "(707) 840-5210", + "field_8969": [ + { + "name": "EsCQRS35LQmewMl2hh1dlK0rDeHRt7xc_0afdb3017ed6ceb4d23b69ab3e44ef5efacb60ad98ddbd49c3138d3059b798c5.jpg", + "visible_name": "Man.28.jpg", + "original_name": "EsCQRS35LQmewMl2hh1dlK0rDeHRt7xc_0afdb3017ed6ceb4d23b69ab3e44ef5efacb60ad98ddbd49c3138d3059b798c5.jpg", + "size": 81365 + } + ], + "field_8970": [], + "field_8971": [], + "field_9005": null + }, + { + "id": 21, + "order": "21.00000000000000000000", + "created_on": "2026-01-13T13:16:49.251888+00:00", + "updated_on": "2026-01-14T10:17:06.855179+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8966": "Richard Rethman", + "field_8967": "richard.rethman@example.com", + "field_8968": "(626) 585-3240", + "field_8969": [ + { + "name": "e4WdmAbll9hfKSbcnxmr74TGFGTHLXM6_860fc8f7a7c919681aa15783aebf52d282bf73edcba69fd03516ca5aba743f14.jpg", + "visible_name": "Man.31.jpg", + "original_name": "e4WdmAbll9hfKSbcnxmr74TGFGTHLXM6_860fc8f7a7c919681aa15783aebf52d282bf73edcba69fd03516ca5aba743f14.jpg", + "size": 37358 + } + ], + "field_8970": [], + "field_8971": [ + 16, + 29, + 25 + ], + "field_9005": null + } + ], + "data_sync": null, + "field_rules": [] + }, + { + "id": 955, + "name": "Projects", + "order": 3, + "fields": [ + { + "id": 8972, + "type": "text", + "name": "Name", + "description": null, + "order": 2, + "primary": true, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "text_default": "" + }, + { + "id": 8973, + "type": "text", + "name": "Description", + "description": null, + "order": 3, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "text_default": "" + }, + { + "id": 9036, + "type": "rollup", + "name": "Start date", + "description": null, + "order": 5, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "date_show_tzinfo": false, + "number_prefix": "", + "number_separator": "", + "number_decimal_places": null, + "number_suffix": "", + "duration_format": null, + "nullable": true, + "date_time_format": "24", + "date_force_timezone": null, + "array_formula_type": null, + "error": null, + "date_format": "ISO", + "date_include_time": false, + "through_field_id": 8975, + "target_field_id": 9021, + "rollup_function": "min" + }, + { + "id": 9037, + "type": "rollup", + "name": "End date", + "description": null, + "order": 6, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "date_show_tzinfo": false, + "number_prefix": "", + "number_separator": "", + "number_decimal_places": null, + "number_suffix": "", + "duration_format": null, + "nullable": true, + "date_time_format": "24", + "date_force_timezone": null, + "array_formula_type": null, + "error": null, + "date_format": "ISO", + "date_include_time": false, + "through_field_id": 8975, + "target_field_id": 9022, + "rollup_function": "max" + }, + { + "id": 8974, + "type": "link_row", + "name": "Owner", + "description": null, + "order": 10, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "link_row_table_id": 954, + "link_row_related_field_id": 8970, + "link_row_limit_selection_view_id": null, + "has_related_field": true, + "link_row_multiple_relationships": false + }, + { + "id": 9046, + "type": "formula", + "name": "Status", + "description": null, + "order": 11, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "date_show_tzinfo": null, + "number_prefix": "", + "number_separator": "", + "number_decimal_places": null, + "number_suffix": "", + "duration_format": null, + "nullable": false, + "date_time_format": null, + "date_force_timezone": null, + "array_formula_type": null, + "error": null, + "date_format": null, + "date_include_time": null, + "formula": "if(totext(field('Approval status')) != 'Approved','',if(today() < field('Start date'), \"Scheduled\", if(and(today() >field('End date'), field('Progress (workload)') = 100), \"Completed\", \"Active\")))", + "formula_type": "text" + }, + { + "id": 8975, + "type": "link_row", + "name": "Phases", + "description": null, + "order": 13, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "link_row_table_id": 956, + "link_row_related_field_id": 8981, + "link_row_limit_selection_view_id": null, + "has_related_field": true, + "link_row_multiple_relationships": true + }, + { + "id": 8976, + "type": "link_row", + "name": "Tasks", + "description": null, + "order": 14, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "link_row_table_id": 957, + "link_row_related_field_id": 8992, + "link_row_limit_selection_view_id": null, + "has_related_field": true, + "link_row_multiple_relationships": true + }, + { + "id": 9006, + "type": "rollup", + "name": "Estimated workload", + "description": null, + "order": 18, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "date_show_tzinfo": null, + "number_prefix": "", + "number_separator": "", + "number_decimal_places": 0, + "number_suffix": "", + "duration_format": null, + "nullable": false, + "date_time_format": null, + "date_force_timezone": null, + "array_formula_type": null, + "error": null, + "date_format": null, + "date_include_time": null, + "through_field_id": 8976, + "target_field_id": 8996, + "rollup_function": "sum" + }, + { + "id": 9007, + "type": "formula", + "name": "Open workload", + "description": null, + "order": 19, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "date_show_tzinfo": null, + "number_prefix": "", + "number_separator": "", + "number_decimal_places": 0, + "number_suffix": "", + "duration_format": null, + "nullable": false, + "date_time_format": null, + "date_force_timezone": null, + "array_formula_type": null, + "error": null, + "date_format": null, + "date_include_time": null, + "formula": "sum(filter(lookup('Tasks','Estimated workload'),lookup('Tasks','Status') != 'Done'))", + "formula_type": "number" + }, + { + "id": 9008, + "type": "formula", + "name": "Completed workload", + "description": null, + "order": 20, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "date_show_tzinfo": null, + "number_prefix": "", + "number_separator": "", + "number_decimal_places": 0, + "number_suffix": "", + "duration_format": null, + "nullable": false, + "date_time_format": null, + "date_force_timezone": null, + "array_formula_type": null, + "error": null, + "date_format": null, + "date_include_time": null, + "formula": "sum(filter(lookup('Tasks','Estimated workload'),lookup('Tasks','Status') = 'Done'))", + "formula_type": "number" + }, + { + "id": 9016, + "type": "count", + "name": "Total tasks", + "description": null, + "order": 21, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "date_show_tzinfo": null, + "number_prefix": "", + "number_separator": "", + "number_decimal_places": 0, + "number_suffix": "", + "duration_format": null, + "nullable": false, + "date_time_format": null, + "date_force_timezone": null, + "array_formula_type": null, + "error": null, + "date_format": null, + "date_include_time": null, + "through_field_id": 8976 + }, + { + "id": 9009, + "type": "formula", + "name": "Open tasks", + "description": null, + "order": 22, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "date_show_tzinfo": null, + "number_prefix": "", + "number_separator": "", + "number_decimal_places": 0, + "number_suffix": "", + "duration_format": null, + "nullable": false, + "date_time_format": null, + "date_force_timezone": null, + "array_formula_type": null, + "error": null, + "date_format": null, + "date_include_time": null, + "formula": "count(filter(lookup('Tasks','Estimated workload'),lookup('Tasks','Status') != 'Done'))", + "formula_type": "number" + }, + { + "id": 9010, + "type": "formula", + "name": "Completed tasks", + "description": null, + "order": 23, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "date_show_tzinfo": null, + "number_prefix": "", + "number_separator": "", + "number_decimal_places": 0, + "number_suffix": "", + "duration_format": null, + "nullable": false, + "date_time_format": null, + "date_force_timezone": null, + "array_formula_type": null, + "error": null, + "date_format": null, + "date_include_time": null, + "formula": "count(filter(lookup('Tasks','Estimated workload'),lookup('Tasks','Status') = 'Done'))", + "formula_type": "number" + }, + { + "id": 9047, + "type": "formula", + "name": "Progress (time)", + "description": null, + "order": 25, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "date_show_tzinfo": null, + "number_prefix": "", + "number_separator": "", + "number_decimal_places": 0, + "number_suffix": "", + "duration_format": null, + "nullable": false, + "date_time_format": null, + "date_force_timezone": null, + "array_formula_type": null, + "error": null, + "date_format": null, + "date_include_time": null, + "formula": "if(count(field('Tasks')) = 0,0,if(field('Start date') > now(),0,if(field('End date') < now(),100,\nround((date_diff('dd',field('Start date'),now()) / date_diff('dd',field('Start date'),field('End date'))) * 100,0))))", + "formula_type": "number" + }, + { + "id": 9054, + "type": "formula", + "name": "Bad health", + "description": null, + "order": 37, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "date_show_tzinfo": null, + "number_prefix": "", + "number_separator": "", + "number_decimal_places": null, + "number_suffix": "", + "duration_format": null, + "nullable": false, + "date_time_format": null, + "date_force_timezone": null, + "array_formula_type": null, + "error": null, + "date_format": null, + "date_include_time": null, + "formula": "or(field('Progress (budget)') >= 100,and(field('Progress (time)') >= 100, field('Progress (workload)') < 100))", + "formula_type": "boolean" + }, + { + "id": 8977, + "type": "single_select", + "name": "Approval status", + "description": null, + "order": 38, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "select_options": [ + { + "id": 3605, + "value": "Submitted", + "color": "gray", + "order": 0 + }, + { + "id": 3606, + "value": "Approved", + "color": "green", + "order": 1 + }, + { + "id": 3607, + "value": "Declined", + "color": "red", + "order": 2 + } + ], + "single_select_default": 3605 + }, + { + "id": 9040, + "type": "rollup", + "name": "Estimated budget", + "description": null, + "order": 40, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "date_show_tzinfo": null, + "number_prefix": "$", + "number_separator": "SPACE_COMMA", + "number_decimal_places": 0, + "number_suffix": "", + "duration_format": null, + "nullable": false, + "date_time_format": null, + "date_force_timezone": null, + "array_formula_type": null, + "error": null, + "date_format": null, + "date_include_time": null, + "through_field_id": 8975, + "target_field_id": 9024, + "rollup_function": "sum" + }, + { + "id": 9041, + "type": "rollup", + "name": "Actual expenses", + "description": null, + "order": 41, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "date_show_tzinfo": null, + "number_prefix": "$", + "number_separator": "SPACE_COMMA", + "number_decimal_places": 0, + "number_suffix": "", + "duration_format": null, + "nullable": false, + "date_time_format": null, + "date_force_timezone": null, + "array_formula_type": null, + "error": null, + "date_format": null, + "date_include_time": null, + "through_field_id": 8975, + "target_field_id": 9025, + "rollup_function": "sum" + }, + { + "id": 9030, + "type": "formula", + "name": "Progress (workload)", + "description": null, + "order": 42, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "date_show_tzinfo": null, + "number_prefix": "", + "number_separator": "", + "number_decimal_places": 2, + "number_suffix": "", + "duration_format": null, + "nullable": false, + "date_time_format": null, + "date_force_timezone": null, + "array_formula_type": null, + "error": null, + "date_format": null, + "date_include_time": null, + "formula": "if(field('Estimated workload') = 0,0,round(field('Completed workload') / field('Estimated workload') * 100,2))", + "formula_type": "number" + }, + { + "id": 9049, + "type": "formula", + "name": "Progress (budget)", + "description": null, + "order": 43, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "date_show_tzinfo": null, + "number_prefix": "", + "number_separator": "", + "number_decimal_places": 2, + "number_suffix": "", + "duration_format": null, + "nullable": false, + "date_time_format": null, + "date_force_timezone": null, + "array_formula_type": null, + "error": null, + "date_format": null, + "date_include_time": null, + "formula": "if(field('Estimated budget') = 0,0,round(field('Actual expenses') / field('Estimated budget') * 100,2))", + "formula_type": "number" + }, + { + "id": 9053, + "type": "formula", + "name": "Medium helath", + "description": null, + "order": 44, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "date_show_tzinfo": null, + "number_prefix": "", + "number_separator": "", + "number_decimal_places": null, + "number_suffix": "", + "duration_format": null, + "nullable": false, + "date_time_format": null, + "date_force_timezone": null, + "array_formula_type": null, + "error": null, + "date_format": null, + "date_include_time": null, + "formula": "field('Progress (time)') > field('Progress (workload)')", + "formula_type": "boolean" + }, + { + "id": 9055, + "type": "formula", + "name": "Good health", + "description": null, + "order": 45, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "date_show_tzinfo": null, + "number_prefix": "", + "number_separator": "", + "number_decimal_places": null, + "number_suffix": "", + "duration_format": null, + "nullable": false, + "date_time_format": null, + "date_force_timezone": null, + "array_formula_type": null, + "error": null, + "date_format": null, + "date_include_time": null, + "formula": "and(field('Progress (budget)') <= 100, field('Progress (time)') < field('Progress (workload)'))", + "formula_type": "boolean" + }, + { + "id": 9033, + "type": "formula", + "name": "Progress (tasks)", + "description": null, + "order": 46, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "date_show_tzinfo": null, + "number_prefix": "", + "number_separator": "", + "number_decimal_places": 2, + "number_suffix": "", + "duration_format": null, + "nullable": false, + "date_time_format": null, + "date_force_timezone": null, + "array_formula_type": null, + "error": null, + "date_format": null, + "date_include_time": null, + "formula": "if(field('Total tasks') = 0,0,round((field('Completed tasks') / field('Total tasks')) * 100,2))", + "formula_type": "number" + }, + { + "id": 8978, + "type": "formula", + "name": "Dashboard", + "description": null, + "order": 47, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "date_show_tzinfo": null, + "number_prefix": "", + "number_separator": "", + "number_decimal_places": null, + "number_suffix": "", + "duration_format": null, + "nullable": false, + "date_time_format": null, + "date_force_timezone": null, + "array_formula_type": null, + "error": null, + "date_format": null, + "date_include_time": null, + "formula": "button(concat('https://your-baserow-i stance/builder/271/preview/project-details/',row_id()),'Open dashboard')", + "formula_type": "button" + } + ], + "views": [ + { + "id": 3989, + "type": "grid", + "name": "All projects", + "order": 1, + "ownership_type": "collaborative", + "owned_by": "frederik@baserow.io", + "filter_type": "AND", + "filters_disabled": false, + "filters": [], + "filter_groups": [], + "sortings": [], + "group_bys": [], + "decorations": [ + { + "id": 750, + "type": "left_border_color", + "value_provider_type": "conditional_color", + "value_provider_conf": { + "colors": [ + { + "id": "0dbe932a-9fa7-4c9b-a83b-3d5426246185", + "color": "darker-blue", + "filters": [ + { + "id": "b8253e92-409f-48ae-bff1-386203a509d4", + "type": "equal", + "field": 9046, + "group": null, + "value": "Scheduled" + } + ], + "operator": "AND" + }, + { + "id": "60daab4e-a27a-49f1-ba4e-90845f5a673d", + "color": "darker-yellow", + "filters": [ + { + "id": "30f7659c-3831-4b2c-ab61-3cd4c1305a1e", + "type": "equal", + "field": 9046, + "group": null, + "value": "Active" + } + ], + "operator": "AND" + }, + { + "id": "1dcfb827-2ff8-4a53-b091-2716007c370b", + "color": "darker-green", + "filters": [ + { + "id": "ec3418a0-895d-4c73-8cba-43fbf0f49143", + "type": "equal", + "field": 9046, + "group": null, + "value": "Completed" + } + ], + "operator": "AND" + } + ] + }, + "order": 1 + }, + { + "id": 751, + "type": "background_color", + "value_provider_type": "conditional_color", + "value_provider_conf": { + "colors": [ + { + "id": "4d602d53-72d6-4c7c-8cd0-0f3b65196962", + "color": "light-red", + "filters": [ + { + "id": "db167e51-7d83-43ce-8018-55f94c11aa68", + "type": "boolean", + "field": 9054, + "group": null, + "value": "1" + } + ], + "operator": "AND" + }, + { + "id": "c5546969-9a44-4e2c-85c7-222610eadd28", + "color": "light-yellow", + "filters": [ + { + "id": "a45a45da-ddf6-4f4f-858f-299ff96f521e", + "type": "boolean", + "field": 9053, + "group": null, + "value": "1" + } + ], + "operator": "AND" + }, + { + "id": "042cb553-cdb5-4684-b216-78e6a2339043", + "color": "light-green", + "filters": [ + { + "id": "924245f2-1b7d-4915-ac2e-cd5a8176fb4c", + "type": "boolean", + "field": 9055, + "group": null, + "value": "1" + } + ], + "operator": "AND" + } + ] + }, + "order": 2 + } + ], + "public": false, + "row_identifier_type": "id", + "row_height_size": "small", + "field_options": [ + { + "id": 33083, + "field_id": 8972, + "width": 200, + "hidden": false, + "order": 0, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33084, + "field_id": 8973, + "width": 283, + "hidden": false, + "order": 1, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33085, + "field_id": 8978, + "width": 200, + "hidden": false, + "order": 2, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33086, + "field_id": 8977, + "width": 161, + "hidden": false, + "order": 3, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33087, + "field_id": 9046, + "width": 126, + "hidden": false, + "order": 4, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33088, + "field_id": 8974, + "width": 168, + "hidden": false, + "order": 5, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33089, + "field_id": 9036, + "width": 134, + "hidden": false, + "order": 6, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33090, + "field_id": 9037, + "width": 130, + "hidden": false, + "order": 7, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33091, + "field_id": 9047, + "width": 153, + "hidden": false, + "order": 8, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33092, + "field_id": 9006, + "width": 176, + "hidden": false, + "order": 9, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33093, + "field_id": 9007, + "width": 149, + "hidden": false, + "order": 10, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33094, + "field_id": 9008, + "width": 191, + "hidden": false, + "order": 11, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33095, + "field_id": 9030, + "width": 182, + "hidden": false, + "order": 12, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33096, + "field_id": 9040, + "width": 166, + "hidden": false, + "order": 13, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33097, + "field_id": 9041, + "width": 159, + "hidden": false, + "order": 14, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33098, + "field_id": 9049, + "width": 200, + "hidden": false, + "order": 15, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33099, + "field_id": 8975, + "width": 200, + "hidden": false, + "order": 16, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33100, + "field_id": 8976, + "width": 200, + "hidden": false, + "order": 17, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33101, + "field_id": 9016, + "width": 200, + "hidden": false, + "order": 18, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33102, + "field_id": 9009, + "width": 200, + "hidden": false, + "order": 19, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33103, + "field_id": 9010, + "width": 200, + "hidden": false, + "order": 20, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33104, + "field_id": 9054, + "width": 151, + "hidden": true, + "order": 21, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33105, + "field_id": 9053, + "width": 200, + "hidden": true, + "order": 22, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33106, + "field_id": 9055, + "width": 200, + "hidden": true, + "order": 23, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33107, + "field_id": 9033, + "width": 200, + "hidden": false, + "order": 24, + "aggregation_type": "", + "aggregation_raw_type": "" + } + ] + } + ], + "rows": [ + { + "id": 1, + "order": "1.00000000000000000000", + "created_on": "2026-01-13T13:23:10.784255+00:00", + "updated_on": "2026-03-31T11:18:05.601348+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8972": "CRM System Upgrade", + "field_8973": "Upgrade CRM to support automation", + "field_9036": null, + "field_9037": null, + "field_8974": [ + 2 + ], + "field_9046": null, + "field_8975": [ + 1, + 2, + 3, + 4, + 5 + ], + "field_8976": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15 + ], + "field_9006": null, + "field_9007": null, + "field_9008": null, + "field_9016": null, + "field_9009": null, + "field_9010": null, + "field_9047": null, + "field_9054": null, + "field_8977": 3606, + "field_9040": null, + "field_9041": null, + "field_9030": null, + "field_9049": null, + "field_9053": null, + "field_9055": null, + "field_9033": null, + "field_8978": null + }, + { + "id": 2, + "order": "2.00000000000000000000", + "created_on": "2026-01-13T13:23:10.784295+00:00", + "updated_on": "2026-03-31T11:18:00.383378+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8972": "ISO 27001 Compliance", + "field_8973": "Implement information security controls", + "field_9036": null, + "field_9037": null, + "field_8974": [ + 7 + ], + "field_9046": null, + "field_8975": [ + 6, + 7, + 8, + 9, + 10 + ], + "field_8976": [ + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30 + ], + "field_9006": null, + "field_9007": null, + "field_9008": null, + "field_9016": null, + "field_9009": null, + "field_9010": null, + "field_9047": null, + "field_9054": null, + "field_8977": 3606, + "field_9040": null, + "field_9041": null, + "field_9030": null, + "field_9049": null, + "field_9053": null, + "field_9055": null, + "field_9033": null, + "field_8978": null + }, + { + "id": 3, + "order": "3.00000000000000000000", + "created_on": "2026-01-13T13:23:10.784307+00:00", + "updated_on": "2026-04-01T12:20:05.695209+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8972": "Spring Marketing Campaign", + "field_8973": "Launch new spring promotion", + "field_9036": null, + "field_9037": null, + "field_8974": [ + 3 + ], + "field_9046": null, + "field_8975": [ + 11, + 12, + 13, + 14 + ], + "field_8976": [ + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38 + ], + "field_9006": null, + "field_9007": null, + "field_9008": null, + "field_9016": null, + "field_9009": null, + "field_9010": null, + "field_9047": null, + "field_9054": null, + "field_8977": 3606, + "field_9040": null, + "field_9041": null, + "field_9030": null, + "field_9049": null, + "field_9053": null, + "field_9055": null, + "field_9033": null, + "field_8978": null + } + ], + "data_sync": null, + "field_rules": [] + }, + { + "id": 956, + "name": "Phases", + "order": 6, + "fields": [ + { + "id": 8979, + "type": "text", + "name": "Name", + "description": null, + "order": 2, + "primary": true, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "text_default": "" + }, + { + "id": 9045, + "type": "formula", + "name": "Status", + "description": null, + "order": 4, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "date_show_tzinfo": null, + "number_prefix": "", + "number_separator": "", + "number_decimal_places": null, + "number_suffix": "", + "duration_format": null, + "nullable": false, + "date_time_format": null, + "date_force_timezone": null, + "array_formula_type": null, + "error": null, + "date_format": null, + "date_include_time": null, + "formula": "if(count(field('Tasks')) = 0,'Not started yet',if(field('All tasks completed'),'Completed',if(field('No tasks started'),'Not started yet','In progress')))", + "formula_type": "text" + }, + { + "id": 8980, + "type": "text", + "name": "Description", + "description": null, + "order": 5, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "text_default": "" + }, + { + "id": 8981, + "type": "link_row", + "name": "Project", + "description": null, + "order": 6, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "link_row_table_id": 955, + "link_row_related_field_id": 8975, + "link_row_limit_selection_view_id": null, + "has_related_field": true, + "link_row_multiple_relationships": false + }, + { + "id": 8982, + "type": "link_row", + "name": "Tasks", + "description": null, + "order": 7, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "link_row_table_id": 957, + "link_row_related_field_id": 8991, + "link_row_limit_selection_view_id": null, + "has_related_field": true, + "link_row_multiple_relationships": true + }, + { + "id": 9031, + "type": "formula", + "name": "All tasks completed", + "description": null, + "order": 9, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "date_show_tzinfo": null, + "number_prefix": "", + "number_separator": "", + "number_decimal_places": null, + "number_suffix": "", + "duration_format": null, + "nullable": false, + "date_time_format": null, + "date_force_timezone": null, + "array_formula_type": null, + "error": null, + "date_format": null, + "date_include_time": null, + "formula": "field('Open workload') = 0", + "formula_type": "boolean" + }, + { + "id": 9020, + "type": "formula", + "name": "No tasks started", + "description": null, + "order": 10, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "date_show_tzinfo": null, + "number_prefix": "", + "number_separator": "", + "number_decimal_places": null, + "number_suffix": "", + "duration_format": null, + "nullable": false, + "date_time_format": null, + "date_force_timezone": null, + "array_formula_type": null, + "error": null, + "date_format": null, + "date_include_time": null, + "formula": "count(filter(field('Tasks'),lookup('Tasks','Status') = 'To do')) = count(field('Tasks'))", + "formula_type": "boolean" + }, + { + "id": 9021, + "type": "rollup", + "name": "Start date", + "description": null, + "order": 12, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "date_show_tzinfo": false, + "number_prefix": "", + "number_separator": "", + "number_decimal_places": null, + "number_suffix": "", + "duration_format": null, + "nullable": true, + "date_time_format": "24", + "date_force_timezone": null, + "array_formula_type": null, + "error": null, + "date_format": "ISO", + "date_include_time": false, + "through_field_id": 8982, + "target_field_id": 8988, + "rollup_function": "min" + }, + { + "id": 9022, + "type": "rollup", + "name": "End date", + "description": null, + "order": 13, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "date_show_tzinfo": false, + "number_prefix": "", + "number_separator": "", + "number_decimal_places": null, + "number_suffix": "", + "duration_format": null, + "nullable": true, + "date_time_format": "24", + "date_force_timezone": null, + "array_formula_type": null, + "error": null, + "date_format": "ISO", + "date_include_time": false, + "through_field_id": 8982, + "target_field_id": 8989, + "rollup_function": "max" + }, + { + "id": 9011, + "type": "rollup", + "name": "Estimated workload", + "description": null, + "order": 14, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "date_show_tzinfo": null, + "number_prefix": "", + "number_separator": "", + "number_decimal_places": 0, + "number_suffix": "", + "duration_format": null, + "nullable": false, + "date_time_format": null, + "date_force_timezone": null, + "array_formula_type": null, + "error": null, + "date_format": null, + "date_include_time": null, + "through_field_id": 8982, + "target_field_id": 8996, + "rollup_function": "sum" + }, + { + "id": 9017, + "type": "count", + "name": "Total tasks", + "description": null, + "order": 15, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "date_show_tzinfo": null, + "number_prefix": "", + "number_separator": "", + "number_decimal_places": 0, + "number_suffix": "", + "duration_format": null, + "nullable": false, + "date_time_format": null, + "date_force_timezone": null, + "array_formula_type": null, + "error": null, + "date_format": null, + "date_include_time": null, + "through_field_id": 8982 + }, + { + "id": 9012, + "type": "formula", + "name": "Open workload", + "description": null, + "order": 16, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "date_show_tzinfo": null, + "number_prefix": "", + "number_separator": "", + "number_decimal_places": 0, + "number_suffix": "", + "duration_format": null, + "nullable": false, + "date_time_format": null, + "date_force_timezone": null, + "array_formula_type": null, + "error": null, + "date_format": null, + "date_include_time": null, + "formula": "sum(filter(lookup('Tasks','Estimated workload'),lookup('Tasks','Status') != 'Done'))", + "formula_type": "number" + }, + { + "id": 9013, + "type": "formula", + "name": "Open tasks", + "description": null, + "order": 17, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "date_show_tzinfo": null, + "number_prefix": "", + "number_separator": "", + "number_decimal_places": 0, + "number_suffix": "", + "duration_format": null, + "nullable": false, + "date_time_format": null, + "date_force_timezone": null, + "array_formula_type": null, + "error": null, + "date_format": null, + "date_include_time": null, + "formula": "count(filter(lookup('Tasks','Estimated workload'),lookup('Tasks','Status') != 'Done'))", + "formula_type": "number" + }, + { + "id": 9014, + "type": "formula", + "name": "Completed workload", + "description": null, + "order": 18, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "date_show_tzinfo": null, + "number_prefix": "", + "number_separator": "", + "number_decimal_places": 0, + "number_suffix": "", + "duration_format": null, + "nullable": false, + "date_time_format": null, + "date_force_timezone": null, + "array_formula_type": null, + "error": null, + "date_format": null, + "date_include_time": null, + "formula": "sum(filter(lookup('Tasks','Estimated workload'),lookup('Tasks','Status') = 'Done'))", + "formula_type": "number" + }, + { + "id": 9015, + "type": "formula", + "name": "Completed tasks", + "description": null, + "order": 19, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "date_show_tzinfo": null, + "number_prefix": "", + "number_separator": "", + "number_decimal_places": 0, + "number_suffix": "", + "duration_format": null, + "nullable": false, + "date_time_format": null, + "date_force_timezone": null, + "array_formula_type": null, + "error": null, + "date_format": null, + "date_include_time": null, + "formula": "count(filter(lookup('Tasks','Estimated workload'),lookup('Tasks','Status') = 'Done'))", + "formula_type": "number" + }, + { + "id": 9032, + "type": "formula", + "name": "Progress (workload)", + "description": null, + "order": 20, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "date_show_tzinfo": null, + "number_prefix": "", + "number_separator": "", + "number_decimal_places": 2, + "number_suffix": "", + "duration_format": null, + "nullable": false, + "date_time_format": null, + "date_force_timezone": null, + "array_formula_type": null, + "error": null, + "date_format": null, + "date_include_time": null, + "formula": "if(field('Estimated workload') = 0,0,round(field('Completed workload') / field('Estimated workload') * 100,2))", + "formula_type": "number" + }, + { + "id": 9038, + "type": "formula", + "name": "Progress (time)", + "description": null, + "order": 21, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "date_show_tzinfo": null, + "number_prefix": "", + "number_separator": "", + "number_decimal_places": 0, + "number_suffix": "", + "duration_format": null, + "nullable": false, + "date_time_format": null, + "date_force_timezone": null, + "array_formula_type": null, + "error": null, + "date_format": null, + "date_include_time": null, + "formula": "if(count(field('Tasks')) = 0,0,if(field('Start date') > now(),0,if(field('End date') < now(),100,\nround((date_diff('dd',field('Start date'),now()) / date_diff('dd',field('Start date'),field('End date'))) * 100,0))))", + "formula_type": "number" + }, + { + "id": 9024, + "type": "rollup", + "name": "Estimated budget", + "description": null, + "order": 22, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "date_show_tzinfo": null, + "number_prefix": "$", + "number_separator": "SPACE_COMMA", + "number_decimal_places": 0, + "number_suffix": "", + "duration_format": null, + "nullable": false, + "date_time_format": null, + "date_force_timezone": null, + "array_formula_type": null, + "error": null, + "date_format": null, + "date_include_time": null, + "through_field_id": 8982, + "target_field_id": 8997, + "rollup_function": "sum" + }, + { + "id": 9025, + "type": "rollup", + "name": "Actual expenses", + "description": null, + "order": 23, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "date_show_tzinfo": null, + "number_prefix": "$", + "number_separator": "SPACE_COMMA", + "number_decimal_places": 0, + "number_suffix": "", + "duration_format": null, + "nullable": false, + "date_time_format": null, + "date_force_timezone": null, + "array_formula_type": null, + "error": null, + "date_format": null, + "date_include_time": null, + "through_field_id": 8982, + "target_field_id": 8998, + "rollup_function": "sum" + }, + { + "id": 9042, + "type": "formula", + "name": "Progress (budget)", + "description": null, + "order": 24, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "date_show_tzinfo": null, + "number_prefix": "", + "number_separator": "", + "number_decimal_places": 2, + "number_suffix": "", + "duration_format": null, + "nullable": false, + "date_time_format": null, + "date_force_timezone": null, + "array_formula_type": null, + "error": null, + "date_format": null, + "date_include_time": null, + "formula": "if(field('Estimated budget') = 0,0,round(field('Actual expenses') / field('Estimated budget') * 100,2))", + "formula_type": "number" + }, + { + "id": 9050, + "type": "formula", + "name": "Bad health", + "description": null, + "order": 25, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "date_show_tzinfo": null, + "number_prefix": "", + "number_separator": "", + "number_decimal_places": null, + "number_suffix": "", + "duration_format": null, + "nullable": false, + "date_time_format": null, + "date_force_timezone": null, + "array_formula_type": null, + "error": null, + "date_format": null, + "date_include_time": null, + "formula": "or(field('Progress (budget)') >= 100,and(field('Progress (time)') >= 100, field('Progress (workload)') < 100))", + "formula_type": "boolean" + }, + { + "id": 9048, + "type": "formula", + "name": "Medium health", + "description": null, + "order": 26, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "date_show_tzinfo": null, + "number_prefix": "", + "number_separator": "", + "number_decimal_places": null, + "number_suffix": "", + "duration_format": null, + "nullable": false, + "date_time_format": null, + "date_force_timezone": null, + "array_formula_type": null, + "error": null, + "date_format": null, + "date_include_time": null, + "formula": "field('Progress (time)') > field('Progress (workload)')", + "formula_type": "boolean" + }, + { + "id": 9051, + "type": "formula", + "name": "Good health", + "description": null, + "order": 27, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "date_show_tzinfo": null, + "number_prefix": "", + "number_separator": "", + "number_decimal_places": null, + "number_suffix": "", + "duration_format": null, + "nullable": false, + "date_time_format": null, + "date_force_timezone": null, + "array_formula_type": null, + "error": null, + "date_format": null, + "date_include_time": null, + "formula": "and(field('Progress (budget)') <= 100, field('Progress (time)') < field('Progress (workload)'))", + "formula_type": "boolean" + }, + { + "id": 9034, + "type": "formula", + "name": "Progress (tasks)", + "description": null, + "order": 28, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "date_show_tzinfo": null, + "number_prefix": "", + "number_separator": "", + "number_decimal_places": 2, + "number_suffix": "", + "duration_format": null, + "nullable": false, + "date_time_format": null, + "date_force_timezone": null, + "array_formula_type": null, + "error": null, + "date_format": null, + "date_include_time": null, + "formula": "if(field('Total tasks') = 0,0,round((field('Completed tasks') / field('Total tasks')) * 100,2))", + "formula_type": "number" + }, + { + "id": 9027, + "type": "formula", + "name": "New task", + "description": null, + "order": 29, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "date_show_tzinfo": null, + "number_prefix": "", + "number_separator": "", + "number_decimal_places": null, + "number_suffix": "", + "duration_format": null, + "nullable": false, + "date_time_format": null, + "date_force_timezone": null, + "array_formula_type": "button", + "error": null, + "date_format": null, + "date_include_time": null, + "formula": "button(concat('https://your-baserow-instance/form/-nr5oT9QZUoUgq9EJyBjnG7N4TZVSa62pCt528YT3Vs?prefill_Project=',encode_uri(field('Project')),'&prefill_Phase=',encode_uri(field('Name'))),'Add new task')", + "formula_type": "array" + } + ], + "views": [ + { + "id": 3990, + "type": "grid", + "name": "All phases", + "order": 1, + "ownership_type": "collaborative", + "owned_by": "frederik@baserow.io", + "filter_type": "AND", + "filters_disabled": false, + "filters": [], + "filter_groups": [], + "sortings": [ + { + "id": 2618, + "field_id": 9021, + "order": "ASC" + } + ], + "group_bys": [], + "decorations": [ + { + "id": 752, + "type": "left_border_color", + "value_provider_type": "conditional_color", + "value_provider_conf": { + "colors": [ + { + "id": "99fafe47-cfb8-4c3a-b49c-89b01a9c480e", + "color": "darker-blue", + "filters": [ + { + "id": "e129bdc5-77aa-44cc-8dd9-a39b007c38ed", + "type": "equal", + "field": 9045, + "group": null, + "value": "Not started yet" + } + ], + "operator": "AND" + }, + { + "id": "d27f219e-7fe7-403a-b95f-7c6ef6d5cb68", + "color": "darker-orange", + "filters": [ + { + "id": "2780033c-b8a4-465d-b3fd-0ba03f2be954", + "type": "equal", + "field": 9045, + "group": null, + "value": "In progress" + } + ], + "operator": "AND" + }, + { + "id": "27d96cd0-47dc-4df8-83cb-b9d50a4a722c", + "color": "darker-green", + "filters": [ + { + "id": "31b08521-fa39-4914-996f-399f56a136b3", + "type": "equal", + "field": 9045, + "group": null, + "value": "Completed" + } + ], + "operator": "AND" + } + ] + }, + "order": 2 + }, + { + "id": 753, + "type": "background_color", + "value_provider_type": "conditional_color", + "value_provider_conf": { + "colors": [ + { + "id": "48a6bf2d-ccaf-42ef-9d6f-2ccb96949b02", + "color": "light-red", + "filters": [ + { + "id": "d3a60ccb-47c0-4cfa-945f-c65e90aa0e00", + "type": "boolean", + "field": 9050, + "group": null, + "value": "1" + } + ], + "operator": "AND" + }, + { + "id": "db0e1c81-f870-45d8-a96a-98acd9f66663", + "color": "light-yellow", + "filters": [ + { + "id": "fd34e8f1-6db1-4770-b6ce-83443f6df927", + "type": "boolean", + "field": 9048, + "group": null, + "value": "1" + } + ], + "operator": "AND" + }, + { + "id": "dcef7883-4710-4bc5-ad43-5d9d69884972", + "color": "light-green", + "filters": [ + { + "id": "6dde97f9-014d-462c-a244-f1999c853a29", + "type": "boolean", + "field": 9051, + "group": null, + "value": "1" + } + ], + "operator": "AND" + } + ] + }, + "order": 3 + } + ], + "public": false, + "row_identifier_type": "id", + "row_height_size": "small", + "field_options": [ + { + "id": 33108, + "field_id": 8979, + "width": 200, + "hidden": false, + "order": 0, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33109, + "field_id": 8980, + "width": 200, + "hidden": false, + "order": 1, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33110, + "field_id": 9027, + "width": 142, + "hidden": false, + "order": 2, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33111, + "field_id": 8981, + "width": 200, + "hidden": false, + "order": 3, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33112, + "field_id": 9045, + "width": 148, + "hidden": false, + "order": 4, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33113, + "field_id": 9021, + "width": 130, + "hidden": false, + "order": 5, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33114, + "field_id": 9022, + "width": 126, + "hidden": false, + "order": 6, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33115, + "field_id": 9038, + "width": 152, + "hidden": false, + "order": 7, + "aggregation_type": "average", + "aggregation_raw_type": "average" + }, + { + "id": 33116, + "field_id": 9011, + "width": 178, + "hidden": false, + "order": 8, + "aggregation_type": "sum", + "aggregation_raw_type": "sum" + }, + { + "id": 33117, + "field_id": 9012, + "width": 160, + "hidden": false, + "order": 9, + "aggregation_type": "sum", + "aggregation_raw_type": "sum" + }, + { + "id": 33118, + "field_id": 9014, + "width": 182, + "hidden": false, + "order": 10, + "aggregation_type": "sum", + "aggregation_raw_type": "sum" + }, + { + "id": 33119, + "field_id": 9032, + "width": 180, + "hidden": false, + "order": 11, + "aggregation_type": "average", + "aggregation_raw_type": "average" + }, + { + "id": 33120, + "field_id": 9024, + "width": 200, + "hidden": false, + "order": 12, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33121, + "field_id": 9025, + "width": 200, + "hidden": false, + "order": 13, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33122, + "field_id": 9042, + "width": 172, + "hidden": false, + "order": 14, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33123, + "field_id": 8982, + "width": 200, + "hidden": false, + "order": 15, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33124, + "field_id": 9017, + "width": 129, + "hidden": false, + "order": 16, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33125, + "field_id": 9013, + "width": 143, + "hidden": false, + "order": 17, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33126, + "field_id": 9015, + "width": 163, + "hidden": false, + "order": 18, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33127, + "field_id": 9031, + "width": 200, + "hidden": true, + "order": 19, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33128, + "field_id": 9020, + "width": 200, + "hidden": true, + "order": 20, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33129, + "field_id": 9050, + "width": 200, + "hidden": true, + "order": 21, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33130, + "field_id": 9051, + "width": 200, + "hidden": true, + "order": 22, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33131, + "field_id": 9048, + "width": 200, + "hidden": true, + "order": 23, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33132, + "field_id": 9034, + "width": 160, + "hidden": false, + "order": 24, + "aggregation_type": "", + "aggregation_raw_type": "" + } + ] + }, + { + "id": 3991, + "type": "grid", + "name": "All phases grouped by project", + "order": 3, + "ownership_type": "collaborative", + "owned_by": "frederik@baserow.io", + "filter_type": "AND", + "filters_disabled": false, + "filters": [], + "filter_groups": [], + "sortings": [ + { + "id": 2619, + "field_id": 9021, + "order": "ASC" + } + ], + "group_bys": [ + { + "id": 432, + "field_id": 8981, + "order": "ASC" + } + ], + "decorations": [ + { + "id": 754, + "type": "left_border_color", + "value_provider_type": "conditional_color", + "value_provider_conf": { + "colors": [ + { + "id": "99fafe47-cfb8-4c3a-b49c-89b01a9c480e", + "color": "darker-blue", + "filters": [ + { + "id": "e129bdc5-77aa-44cc-8dd9-a39b007c38ed", + "type": "equal", + "field": 9045, + "group": null, + "value": "Not started yet" + } + ], + "operator": "AND" + }, + { + "id": "d27f219e-7fe7-403a-b95f-7c6ef6d5cb68", + "color": "darker-orange", + "filters": [ + { + "id": "2780033c-b8a4-465d-b3fd-0ba03f2be954", + "type": "equal", + "field": 9045, + "group": null, + "value": "In progress" + } + ], + "operator": "AND" + }, + { + "id": "27d96cd0-47dc-4df8-83cb-b9d50a4a722c", + "color": "darker-green", + "filters": [ + { + "id": "31b08521-fa39-4914-996f-399f56a136b3", + "type": "equal", + "field": 9045, + "group": null, + "value": "Completed" + } + ], + "operator": "AND" + } + ] + }, + "order": 2 + }, + { + "id": 755, + "type": "background_color", + "value_provider_type": "conditional_color", + "value_provider_conf": { + "colors": [ + { + "id": "48a6bf2d-ccaf-42ef-9d6f-2ccb96949b02", + "color": "light-red", + "filters": [ + { + "id": "d3a60ccb-47c0-4cfa-945f-c65e90aa0e00", + "type": "boolean", + "field": 9050, + "group": null, + "value": "1" + } + ], + "operator": "AND" + }, + { + "id": "db0e1c81-f870-45d8-a96a-98acd9f66663", + "color": "light-yellow", + "filters": [ + { + "id": "fd34e8f1-6db1-4770-b6ce-83443f6df927", + "type": "boolean", + "field": 9048, + "group": null, + "value": "1" + } + ], + "operator": "AND" + }, + { + "id": "dcef7883-4710-4bc5-ad43-5d9d69884972", + "color": "light-green", + "filters": [ + { + "id": "6dde97f9-014d-462c-a244-f1999c853a29", + "type": "boolean", + "field": 9051, + "group": null, + "value": "1" + } + ], + "operator": "AND" + } + ] + }, + "order": 3 + } + ], + "public": false, + "row_identifier_type": "id", + "row_height_size": "small", + "field_options": [ + { + "id": 33133, + "field_id": 8980, + "width": 200, + "hidden": false, + "order": 0, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33134, + "field_id": 8981, + "width": 200, + "hidden": false, + "order": 1, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33135, + "field_id": 9045, + "width": 148, + "hidden": false, + "order": 2, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33136, + "field_id": 8979, + "width": 255, + "hidden": false, + "order": 3, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33137, + "field_id": 9021, + "width": 130, + "hidden": false, + "order": 4, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33138, + "field_id": 9022, + "width": 126, + "hidden": false, + "order": 5, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33139, + "field_id": 9038, + "width": 152, + "hidden": false, + "order": 6, + "aggregation_type": "average", + "aggregation_raw_type": "average" + }, + { + "id": 33140, + "field_id": 9011, + "width": 178, + "hidden": false, + "order": 7, + "aggregation_type": "sum", + "aggregation_raw_type": "sum" + }, + { + "id": 33141, + "field_id": 9012, + "width": 160, + "hidden": false, + "order": 8, + "aggregation_type": "sum", + "aggregation_raw_type": "sum" + }, + { + "id": 33142, + "field_id": 9014, + "width": 182, + "hidden": false, + "order": 9, + "aggregation_type": "sum", + "aggregation_raw_type": "sum" + }, + { + "id": 33143, + "field_id": 9032, + "width": 180, + "hidden": false, + "order": 10, + "aggregation_type": "average", + "aggregation_raw_type": "average" + }, + { + "id": 33144, + "field_id": 9024, + "width": 200, + "hidden": false, + "order": 11, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33145, + "field_id": 9025, + "width": 200, + "hidden": false, + "order": 12, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33146, + "field_id": 9042, + "width": 172, + "hidden": false, + "order": 13, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33147, + "field_id": 8982, + "width": 200, + "hidden": false, + "order": 14, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33148, + "field_id": 9017, + "width": 129, + "hidden": false, + "order": 15, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33149, + "field_id": 9013, + "width": 143, + "hidden": false, + "order": 16, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33150, + "field_id": 9015, + "width": 163, + "hidden": false, + "order": 17, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33151, + "field_id": 9031, + "width": 200, + "hidden": true, + "order": 18, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33152, + "field_id": 9020, + "width": 200, + "hidden": true, + "order": 19, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33153, + "field_id": 9050, + "width": 200, + "hidden": false, + "order": 20, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33154, + "field_id": 9051, + "width": 200, + "hidden": false, + "order": 21, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33155, + "field_id": 9048, + "width": 200, + "hidden": false, + "order": 22, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33157, + "field_id": 9027, + "width": 200, + "hidden": true, + "order": 32767, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33156, + "field_id": 9034, + "width": 200, + "hidden": true, + "order": 32767, + "aggregation_type": "", + "aggregation_raw_type": "" + } + ] + }, + { + "id": 3992, + "type": "timeline", + "name": "Timeline: All phases", + "order": 4, + "ownership_type": "collaborative", + "owned_by": "frederik@baserow.io", + "filter_type": "AND", + "filters_disabled": false, + "filters": [], + "filter_groups": [], + "sortings": [ + { + "id": 2620, + "field_id": 9021, + "order": "ASC" + } + ], + "decorations": [ + { + "id": 756, + "type": "left_border_color", + "value_provider_type": "conditional_color", + "value_provider_conf": { + "colors": [ + { + "id": "8a9ca05b-dd42-4074-8dfa-4cd79409bdee", + "color": "darker-blue", + "filters": [ + { + "id": "fa219e31-e944-46fa-be71-feb1d8017545", + "type": "equal", + "field": 9045, + "group": null, + "value": "Not started yet" + } + ], + "operator": "AND" + }, + { + "id": "9aaa79e4-917b-4a23-a4ce-c14392128e55", + "color": "darker-orange", + "filters": [ + { + "id": "c3f3f393-f577-4b8f-a2ac-9573046ff6c5", + "type": "equal", + "field": 9045, + "group": null, + "value": "In progress" + } + ], + "operator": "AND" + }, + { + "id": "2e061c7a-beaf-45c4-bc92-67dcbdfb3920", + "color": "darker-green", + "filters": [ + { + "id": "5c4b2dbc-50db-4be7-82f8-8a726b6aa211", + "type": "equal", + "field": 9045, + "group": null, + "value": "Completed" + } + ], + "operator": "AND" + } + ] + }, + "order": 1 + }, + { + "id": 757, + "type": "background_color", + "value_provider_type": "conditional_color", + "value_provider_conf": { + "colors": [ + { + "id": "f14688c6-06ad-49d2-96db-de73b47f7dcd", + "color": "light-red", + "filters": [ + { + "id": "eca2ac58-4085-41e1-a591-c66ebfd6ff6e", + "type": "boolean", + "field": 9050, + "group": null, + "value": "1" + } + ], + "operator": "AND" + }, + { + "id": "dc9141c1-dedd-485d-be25-cc30601b5978", + "color": "light-yellow", + "filters": [ + { + "id": "cebc3b1d-aae0-45b4-982a-07ffe8c007b1", + "type": "boolean", + "field": 9048, + "group": null, + "value": "1" + } + ], + "operator": "AND" + }, + { + "id": "7a47c603-8381-4b24-9bf4-69952049ac7c", + "color": "light-green", + "filters": [ + { + "id": "3a254cb0-8b51-4e09-871a-e08727ca3628", + "type": "boolean", + "field": 9051, + "group": null, + "value": "1" + } + ], + "operator": "AND" + } + ] + }, + "order": 2 + } + ], + "public": false, + "start_date_field_id": 9021, + "end_date_field_id": 9022, + "field_options": [ + { + "id": 681, + "field_id": 8979, + "hidden": false, + "order": 32767 + }, + { + "id": 682, + "field_id": 8980, + "hidden": true, + "order": 32767 + }, + { + "id": 683, + "field_id": 8981, + "hidden": false, + "order": 32767 + }, + { + "id": 684, + "field_id": 8982, + "hidden": true, + "order": 32767 + }, + { + "id": 685, + "field_id": 9011, + "hidden": true, + "order": 32767 + }, + { + "id": 686, + "field_id": 9012, + "hidden": true, + "order": 32767 + }, + { + "id": 687, + "field_id": 9013, + "hidden": true, + "order": 32767 + }, + { + "id": 688, + "field_id": 9014, + "hidden": true, + "order": 32767 + }, + { + "id": 689, + "field_id": 9015, + "hidden": true, + "order": 32767 + }, + { + "id": 690, + "field_id": 9017, + "hidden": true, + "order": 32767 + }, + { + "id": 691, + "field_id": 9020, + "hidden": true, + "order": 32767 + }, + { + "id": 692, + "field_id": 9021, + "hidden": true, + "order": 32767 + }, + { + "id": 693, + "field_id": 9022, + "hidden": true, + "order": 32767 + }, + { + "id": 698, + "field_id": 9024, + "hidden": true, + "order": 32767 + }, + { + "id": 699, + "field_id": 9025, + "hidden": true, + "order": 32767 + }, + { + "id": 705, + "field_id": 9027, + "hidden": true, + "order": 32767 + }, + { + "id": 694, + "field_id": 9031, + "hidden": true, + "order": 32767 + }, + { + "id": 695, + "field_id": 9032, + "hidden": true, + "order": 32767 + }, + { + "id": 704, + "field_id": 9034, + "hidden": true, + "order": 32767 + }, + { + "id": 696, + "field_id": 9038, + "hidden": true, + "order": 32767 + }, + { + "id": 700, + "field_id": 9042, + "hidden": true, + "order": 32767 + }, + { + "id": 697, + "field_id": 9045, + "hidden": true, + "order": 32767 + }, + { + "id": 702, + "field_id": 9048, + "hidden": true, + "order": 32767 + }, + { + "id": 701, + "field_id": 9050, + "hidden": true, + "order": 32767 + }, + { + "id": 703, + "field_id": 9051, + "hidden": true, + "order": 32767 + } + ] + }, + { + "id": 3993, + "type": "grid", + "name": "CRM System Upgrade phases", + "order": 5, + "ownership_type": "collaborative", + "owned_by": "frederik@baserow.io", + "filter_type": "AND", + "filters_disabled": false, + "filters": [ + { + "id": 2024, + "field_id": 8981, + "type": "link_row_has", + "value": "1", + "group": null + } + ], + "filter_groups": [], + "sortings": [ + { + "id": 2621, + "field_id": 9021, + "order": "ASC" + } + ], + "group_bys": [], + "decorations": [ + { + "id": 758, + "type": "left_border_color", + "value_provider_type": "conditional_color", + "value_provider_conf": { + "colors": [ + { + "id": "99fafe47-cfb8-4c3a-b49c-89b01a9c480e", + "color": "darker-blue", + "filters": [ + { + "id": "e129bdc5-77aa-44cc-8dd9-a39b007c38ed", + "type": "equal", + "field": 9045, + "group": null, + "value": "Not started yet" + } + ], + "operator": "AND" + }, + { + "id": "d27f219e-7fe7-403a-b95f-7c6ef6d5cb68", + "color": "darker-orange", + "filters": [ + { + "id": "2780033c-b8a4-465d-b3fd-0ba03f2be954", + "type": "equal", + "field": 9045, + "group": null, + "value": "In progress" + } + ], + "operator": "AND" + }, + { + "id": "27d96cd0-47dc-4df8-83cb-b9d50a4a722c", + "color": "darker-green", + "filters": [ + { + "id": "31b08521-fa39-4914-996f-399f56a136b3", + "type": "equal", + "field": 9045, + "group": null, + "value": "Completed" + } + ], + "operator": "AND" + } + ] + }, + "order": 2 + }, + { + "id": 759, + "type": "background_color", + "value_provider_type": "conditional_color", + "value_provider_conf": { + "colors": [ + { + "id": "48a6bf2d-ccaf-42ef-9d6f-2ccb96949b02", + "color": "light-red", + "filters": [ + { + "id": "d3a60ccb-47c0-4cfa-945f-c65e90aa0e00", + "type": "boolean", + "field": 9050, + "group": null, + "value": "1" + } + ], + "operator": "AND" + }, + { + "id": "db0e1c81-f870-45d8-a96a-98acd9f66663", + "color": "light-yellow", + "filters": [ + { + "id": "fd34e8f1-6db1-4770-b6ce-83443f6df927", + "type": "boolean", + "field": 9048, + "group": null, + "value": "1" + } + ], + "operator": "AND" + }, + { + "id": "dcef7883-4710-4bc5-ad43-5d9d69884972", + "color": "light-green", + "filters": [ + { + "id": "6dde97f9-014d-462c-a244-f1999c853a29", + "type": "boolean", + "field": 9051, + "group": null, + "value": "1" + } + ], + "operator": "AND" + } + ] + }, + "order": 3 + } + ], + "public": false, + "row_identifier_type": "id", + "row_height_size": "small", + "field_options": [ + { + "id": 33158, + "field_id": 8980, + "width": 200, + "hidden": false, + "order": 0, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33159, + "field_id": 8981, + "width": 200, + "hidden": false, + "order": 1, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33160, + "field_id": 9045, + "width": 148, + "hidden": false, + "order": 2, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33161, + "field_id": 8979, + "width": 200, + "hidden": false, + "order": 3, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33162, + "field_id": 9021, + "width": 130, + "hidden": false, + "order": 4, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33163, + "field_id": 9022, + "width": 126, + "hidden": false, + "order": 5, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33164, + "field_id": 9038, + "width": 152, + "hidden": false, + "order": 6, + "aggregation_type": "average", + "aggregation_raw_type": "average" + }, + { + "id": 33165, + "field_id": 9011, + "width": 178, + "hidden": false, + "order": 7, + "aggregation_type": "sum", + "aggregation_raw_type": "sum" + }, + { + "id": 33166, + "field_id": 9012, + "width": 160, + "hidden": false, + "order": 8, + "aggregation_type": "sum", + "aggregation_raw_type": "sum" + }, + { + "id": 33167, + "field_id": 9014, + "width": 182, + "hidden": false, + "order": 9, + "aggregation_type": "sum", + "aggregation_raw_type": "sum" + }, + { + "id": 33168, + "field_id": 9032, + "width": 180, + "hidden": false, + "order": 10, + "aggregation_type": "average", + "aggregation_raw_type": "average" + }, + { + "id": 33169, + "field_id": 9024, + "width": 200, + "hidden": false, + "order": 11, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33170, + "field_id": 9025, + "width": 200, + "hidden": false, + "order": 12, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33171, + "field_id": 9042, + "width": 172, + "hidden": false, + "order": 13, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33172, + "field_id": 8982, + "width": 200, + "hidden": false, + "order": 14, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33173, + "field_id": 9017, + "width": 129, + "hidden": false, + "order": 15, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33174, + "field_id": 9013, + "width": 143, + "hidden": false, + "order": 16, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33175, + "field_id": 9015, + "width": 163, + "hidden": false, + "order": 17, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33176, + "field_id": 9031, + "width": 200, + "hidden": true, + "order": 18, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33177, + "field_id": 9020, + "width": 200, + "hidden": true, + "order": 19, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33178, + "field_id": 9050, + "width": 200, + "hidden": true, + "order": 20, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33179, + "field_id": 9051, + "width": 200, + "hidden": true, + "order": 21, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33180, + "field_id": 9048, + "width": 200, + "hidden": true, + "order": 22, + "aggregation_type": "", + "aggregation_raw_type": "" + } + ] + }, + { + "id": 3994, + "type": "grid", + "name": "ISO 27001 Compliance", + "order": 6, + "ownership_type": "collaborative", + "owned_by": "frederik@baserow.io", + "filter_type": "AND", + "filters_disabled": false, + "filters": [ + { + "id": 2025, + "field_id": 8981, + "type": "link_row_has", + "value": "2", + "group": null + } + ], + "filter_groups": [], + "sortings": [ + { + "id": 2622, + "field_id": 9021, + "order": "ASC" + } + ], + "group_bys": [], + "decorations": [ + { + "id": 760, + "type": "left_border_color", + "value_provider_type": "conditional_color", + "value_provider_conf": { + "colors": [ + { + "id": "99fafe47-cfb8-4c3a-b49c-89b01a9c480e", + "color": "darker-blue", + "filters": [ + { + "id": "e129bdc5-77aa-44cc-8dd9-a39b007c38ed", + "type": "equal", + "field": 9045, + "group": null, + "value": "Not started yet" + } + ], + "operator": "AND" + }, + { + "id": "d27f219e-7fe7-403a-b95f-7c6ef6d5cb68", + "color": "darker-orange", + "filters": [ + { + "id": "2780033c-b8a4-465d-b3fd-0ba03f2be954", + "type": "equal", + "field": 9045, + "group": null, + "value": "In progress" + } + ], + "operator": "AND" + }, + { + "id": "27d96cd0-47dc-4df8-83cb-b9d50a4a722c", + "color": "darker-green", + "filters": [ + { + "id": "31b08521-fa39-4914-996f-399f56a136b3", + "type": "equal", + "field": 9045, + "group": null, + "value": "Completed" + } + ], + "operator": "AND" + } + ] + }, + "order": 2 + }, + { + "id": 761, + "type": "background_color", + "value_provider_type": "conditional_color", + "value_provider_conf": { + "colors": [ + { + "id": "48a6bf2d-ccaf-42ef-9d6f-2ccb96949b02", + "color": "light-red", + "filters": [ + { + "id": "d3a60ccb-47c0-4cfa-945f-c65e90aa0e00", + "type": "boolean", + "field": 9050, + "group": null, + "value": "1" + } + ], + "operator": "AND" + }, + { + "id": "db0e1c81-f870-45d8-a96a-98acd9f66663", + "color": "light-yellow", + "filters": [ + { + "id": "fd34e8f1-6db1-4770-b6ce-83443f6df927", + "type": "boolean", + "field": 9048, + "group": null, + "value": "1" + } + ], + "operator": "AND" + }, + { + "id": "dcef7883-4710-4bc5-ad43-5d9d69884972", + "color": "light-green", + "filters": [ + { + "id": "6dde97f9-014d-462c-a244-f1999c853a29", + "type": "boolean", + "field": 9051, + "group": null, + "value": "1" + } + ], + "operator": "AND" + } + ] + }, + "order": 3 + } + ], + "public": false, + "row_identifier_type": "id", + "row_height_size": "small", + "field_options": [ + { + "id": 33181, + "field_id": 8980, + "width": 200, + "hidden": false, + "order": 0, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33182, + "field_id": 8981, + "width": 200, + "hidden": false, + "order": 1, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33183, + "field_id": 9045, + "width": 148, + "hidden": false, + "order": 2, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33184, + "field_id": 8979, + "width": 200, + "hidden": false, + "order": 3, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33185, + "field_id": 9021, + "width": 130, + "hidden": false, + "order": 4, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33186, + "field_id": 9022, + "width": 126, + "hidden": false, + "order": 5, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33187, + "field_id": 9038, + "width": 152, + "hidden": false, + "order": 6, + "aggregation_type": "average", + "aggregation_raw_type": "average" + }, + { + "id": 33188, + "field_id": 9011, + "width": 178, + "hidden": false, + "order": 7, + "aggregation_type": "sum", + "aggregation_raw_type": "sum" + }, + { + "id": 33189, + "field_id": 9012, + "width": 160, + "hidden": false, + "order": 8, + "aggregation_type": "sum", + "aggregation_raw_type": "sum" + }, + { + "id": 33190, + "field_id": 9014, + "width": 182, + "hidden": false, + "order": 9, + "aggregation_type": "sum", + "aggregation_raw_type": "sum" + }, + { + "id": 33191, + "field_id": 9032, + "width": 180, + "hidden": false, + "order": 10, + "aggregation_type": "average", + "aggregation_raw_type": "average" + }, + { + "id": 33192, + "field_id": 9024, + "width": 200, + "hidden": false, + "order": 11, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33193, + "field_id": 9025, + "width": 200, + "hidden": false, + "order": 12, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33194, + "field_id": 9042, + "width": 172, + "hidden": false, + "order": 13, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33195, + "field_id": 8982, + "width": 200, + "hidden": false, + "order": 14, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33196, + "field_id": 9017, + "width": 129, + "hidden": false, + "order": 15, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33197, + "field_id": 9013, + "width": 143, + "hidden": false, + "order": 16, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33198, + "field_id": 9015, + "width": 163, + "hidden": false, + "order": 17, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33199, + "field_id": 9031, + "width": 200, + "hidden": true, + "order": 18, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33200, + "field_id": 9020, + "width": 200, + "hidden": true, + "order": 19, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33201, + "field_id": 9050, + "width": 200, + "hidden": true, + "order": 20, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33202, + "field_id": 9051, + "width": 200, + "hidden": true, + "order": 21, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33203, + "field_id": 9048, + "width": 200, + "hidden": true, + "order": 22, + "aggregation_type": "", + "aggregation_raw_type": "" + } + ] + }, + { + "id": 3995, + "type": "grid", + "name": "Spring Marketing Campaign", + "order": 7, + "ownership_type": "collaborative", + "owned_by": "frederik@baserow.io", + "filter_type": "AND", + "filters_disabled": false, + "filters": [ + { + "id": 2026, + "field_id": 8981, + "type": "link_row_has", + "value": "3", + "group": null + } + ], + "filter_groups": [], + "sortings": [ + { + "id": 2623, + "field_id": 9021, + "order": "ASC" + } + ], + "group_bys": [], + "decorations": [ + { + "id": 762, + "type": "left_border_color", + "value_provider_type": "conditional_color", + "value_provider_conf": { + "colors": [ + { + "id": "99fafe47-cfb8-4c3a-b49c-89b01a9c480e", + "color": "darker-blue", + "filters": [ + { + "id": "e129bdc5-77aa-44cc-8dd9-a39b007c38ed", + "type": "equal", + "field": 9045, + "group": null, + "value": "Not started yet" + } + ], + "operator": "AND" + }, + { + "id": "d27f219e-7fe7-403a-b95f-7c6ef6d5cb68", + "color": "darker-orange", + "filters": [ + { + "id": "2780033c-b8a4-465d-b3fd-0ba03f2be954", + "type": "equal", + "field": 9045, + "group": null, + "value": "In progress" + } + ], + "operator": "AND" + }, + { + "id": "27d96cd0-47dc-4df8-83cb-b9d50a4a722c", + "color": "darker-green", + "filters": [ + { + "id": "31b08521-fa39-4914-996f-399f56a136b3", + "type": "equal", + "field": 9045, + "group": null, + "value": "Completed" + } + ], + "operator": "AND" + } + ] + }, + "order": 2 + }, + { + "id": 763, + "type": "background_color", + "value_provider_type": "conditional_color", + "value_provider_conf": { + "colors": [ + { + "id": "48a6bf2d-ccaf-42ef-9d6f-2ccb96949b02", + "color": "light-red", + "filters": [ + { + "id": "d3a60ccb-47c0-4cfa-945f-c65e90aa0e00", + "type": "boolean", + "field": 9050, + "group": null, + "value": "1" + } + ], + "operator": "AND" + }, + { + "id": "db0e1c81-f870-45d8-a96a-98acd9f66663", + "color": "light-yellow", + "filters": [ + { + "id": "fd34e8f1-6db1-4770-b6ce-83443f6df927", + "type": "boolean", + "field": 9048, + "group": null, + "value": "1" + } + ], + "operator": "AND" + }, + { + "id": "dcef7883-4710-4bc5-ad43-5d9d69884972", + "color": "light-green", + "filters": [ + { + "id": "6dde97f9-014d-462c-a244-f1999c853a29", + "type": "boolean", + "field": 9051, + "group": null, + "value": "1" + } + ], + "operator": "AND" + } + ] + }, + "order": 3 + } + ], + "public": false, + "row_identifier_type": "id", + "row_height_size": "small", + "field_options": [ + { + "id": 33204, + "field_id": 8980, + "width": 200, + "hidden": false, + "order": 0, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33205, + "field_id": 8981, + "width": 200, + "hidden": false, + "order": 1, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33206, + "field_id": 9045, + "width": 148, + "hidden": false, + "order": 2, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33207, + "field_id": 8979, + "width": 200, + "hidden": false, + "order": 3, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33208, + "field_id": 9021, + "width": 130, + "hidden": false, + "order": 4, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33209, + "field_id": 9022, + "width": 126, + "hidden": false, + "order": 5, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33210, + "field_id": 9038, + "width": 152, + "hidden": false, + "order": 6, + "aggregation_type": "average", + "aggregation_raw_type": "average" + }, + { + "id": 33211, + "field_id": 9011, + "width": 178, + "hidden": false, + "order": 7, + "aggregation_type": "sum", + "aggregation_raw_type": "sum" + }, + { + "id": 33212, + "field_id": 9012, + "width": 160, + "hidden": false, + "order": 8, + "aggregation_type": "sum", + "aggregation_raw_type": "sum" + }, + { + "id": 33213, + "field_id": 9014, + "width": 182, + "hidden": false, + "order": 9, + "aggregation_type": "sum", + "aggregation_raw_type": "sum" + }, + { + "id": 33214, + "field_id": 9032, + "width": 180, + "hidden": false, + "order": 10, + "aggregation_type": "average", + "aggregation_raw_type": "average" + }, + { + "id": 33215, + "field_id": 9024, + "width": 200, + "hidden": false, + "order": 11, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33216, + "field_id": 9025, + "width": 200, + "hidden": false, + "order": 12, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33217, + "field_id": 9042, + "width": 172, + "hidden": false, + "order": 13, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33218, + "field_id": 8982, + "width": 200, + "hidden": false, + "order": 14, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33219, + "field_id": 9017, + "width": 129, + "hidden": false, + "order": 15, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33220, + "field_id": 9013, + "width": 143, + "hidden": false, + "order": 16, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33221, + "field_id": 9015, + "width": 163, + "hidden": false, + "order": 17, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33222, + "field_id": 9031, + "width": 200, + "hidden": true, + "order": 18, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33223, + "field_id": 9020, + "width": 200, + "hidden": true, + "order": 19, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33224, + "field_id": 9050, + "width": 200, + "hidden": true, + "order": 20, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33225, + "field_id": 9051, + "width": 200, + "hidden": true, + "order": 21, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33226, + "field_id": 9048, + "width": 200, + "hidden": true, + "order": 22, + "aggregation_type": "", + "aggregation_raw_type": "" + } + ] + } + ], + "rows": [ + { + "id": 1, + "order": "1.00000000000000000000", + "created_on": "2026-01-14T07:19:45.062709+00:00", + "updated_on": "2026-02-03T11:24:39.221846+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8979": "CRM Architecture Approved", + "field_9045": null, + "field_8980": "System design and data model approved", + "field_8981": [ + 1 + ], + "field_8982": [ + 1, + 2, + 3 + ], + "field_9031": null, + "field_9020": null, + "field_9021": null, + "field_9022": null, + "field_9011": null, + "field_9017": null, + "field_9012": null, + "field_9013": null, + "field_9014": null, + "field_9015": null, + "field_9032": null, + "field_9038": null, + "field_9024": null, + "field_9025": null, + "field_9042": null, + "field_9050": null, + "field_9048": null, + "field_9051": null, + "field_9034": null, + "field_9027": null + }, + { + "id": 2, + "order": "2.00000000000000000000", + "created_on": "2026-01-14T07:19:45.062743+00:00", + "updated_on": "2026-01-14T07:21:10.714479+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8979": "Core CRM Implemented", + "field_9045": null, + "field_8980": "Basic CRM features running", + "field_8981": [ + 1 + ], + "field_8982": [ + 4, + 5, + 6 + ], + "field_9031": null, + "field_9020": null, + "field_9021": null, + "field_9022": null, + "field_9011": null, + "field_9017": null, + "field_9012": null, + "field_9013": null, + "field_9014": null, + "field_9015": null, + "field_9032": null, + "field_9038": null, + "field_9024": null, + "field_9025": null, + "field_9042": null, + "field_9050": null, + "field_9048": null, + "field_9051": null, + "field_9034": null, + "field_9027": null + }, + { + "id": 3, + "order": "3.00000000000000000000", + "created_on": "2026-01-14T07:19:45.062752+00:00", + "updated_on": "2026-01-14T07:21:11.162348+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8979": "Automation Engine Live", + "field_9045": null, + "field_8980": "Workflow automation deployed", + "field_8981": [ + 1 + ], + "field_8982": [ + 7, + 8, + 9 + ], + "field_9031": null, + "field_9020": null, + "field_9021": null, + "field_9022": null, + "field_9011": null, + "field_9017": null, + "field_9012": null, + "field_9013": null, + "field_9014": null, + "field_9015": null, + "field_9032": null, + "field_9038": null, + "field_9024": null, + "field_9025": null, + "field_9042": null, + "field_9050": null, + "field_9048": null, + "field_9051": null, + "field_9034": null, + "field_9027": null + }, + { + "id": 4, + "order": "4.00000000000000000000", + "created_on": "2026-01-14T07:19:45.062769+00:00", + "updated_on": "2026-01-14T07:21:11.459034+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8979": "User Acceptance Testing", + "field_9045": null, + "field_8980": "Business users validate CRM", + "field_8981": [ + 1 + ], + "field_8982": [ + 10, + 11, + 12 + ], + "field_9031": null, + "field_9020": null, + "field_9021": null, + "field_9022": null, + "field_9011": null, + "field_9017": null, + "field_9012": null, + "field_9013": null, + "field_9014": null, + "field_9015": null, + "field_9032": null, + "field_9038": null, + "field_9024": null, + "field_9025": null, + "field_9042": null, + "field_9050": null, + "field_9048": null, + "field_9051": null, + "field_9034": null, + "field_9027": null + }, + { + "id": 5, + "order": "5.00000000000000000000", + "created_on": "2026-01-14T07:19:45.062777+00:00", + "updated_on": "2026-01-20T12:18:51.118317+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8979": "Go-Live test", + "field_9045": null, + "field_8980": "CRM released to all users", + "field_8981": [ + 1 + ], + "field_8982": [ + 13, + 14, + 15 + ], + "field_9031": null, + "field_9020": null, + "field_9021": null, + "field_9022": null, + "field_9011": null, + "field_9017": null, + "field_9012": null, + "field_9013": null, + "field_9014": null, + "field_9015": null, + "field_9032": null, + "field_9038": null, + "field_9024": null, + "field_9025": null, + "field_9042": null, + "field_9050": null, + "field_9048": null, + "field_9051": null, + "field_9034": null, + "field_9027": null + }, + { + "id": 6, + "order": "6.00000000000000000000", + "created_on": "2026-01-14T07:19:45.062786+00:00", + "updated_on": "2026-01-14T07:21:03.163091+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8979": "Security Risk Assessment", + "field_9045": null, + "field_8980": "All ISO 27001 risks identified", + "field_8981": [ + 2 + ], + "field_8982": [ + 16, + 17, + 18, + 25 + ], + "field_9031": null, + "field_9020": null, + "field_9021": null, + "field_9022": null, + "field_9011": null, + "field_9017": null, + "field_9012": null, + "field_9013": null, + "field_9014": null, + "field_9015": null, + "field_9032": null, + "field_9038": null, + "field_9024": null, + "field_9025": null, + "field_9042": null, + "field_9050": null, + "field_9048": null, + "field_9051": null, + "field_9034": null, + "field_9027": null + }, + { + "id": 7, + "order": "7.00000000000000000000", + "created_on": "2026-01-14T07:19:45.062794+00:00", + "updated_on": "2026-01-14T07:21:13.249190+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8979": "Control Framework Defined", + "field_9045": null, + "field_8980": "Security controls documented", + "field_8981": [ + 2 + ], + "field_8982": [ + 19, + 20, + 21 + ], + "field_9031": null, + "field_9020": null, + "field_9021": null, + "field_9022": null, + "field_9011": null, + "field_9017": null, + "field_9012": null, + "field_9013": null, + "field_9014": null, + "field_9015": null, + "field_9032": null, + "field_9038": null, + "field_9024": null, + "field_9025": null, + "field_9042": null, + "field_9050": null, + "field_9048": null, + "field_9051": null, + "field_9034": null, + "field_9027": null + }, + { + "id": 8, + "order": "8.00000000000000000000", + "created_on": "2026-01-14T07:19:45.062802+00:00", + "updated_on": "2026-01-14T07:21:13.591532+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8979": "Technical Controls Implemented", + "field_9045": null, + "field_8980": "Security tools and configurations deployed", + "field_8981": [ + 2 + ], + "field_8982": [ + 22, + 23, + 24 + ], + "field_9031": null, + "field_9020": null, + "field_9021": null, + "field_9022": null, + "field_9011": null, + "field_9017": null, + "field_9012": null, + "field_9013": null, + "field_9014": null, + "field_9015": null, + "field_9032": null, + "field_9038": null, + "field_9024": null, + "field_9025": null, + "field_9042": null, + "field_9050": null, + "field_9048": null, + "field_9051": null, + "field_9034": null, + "field_9027": null + }, + { + "id": 9, + "order": "9.00000000000000000000", + "created_on": "2026-01-14T07:19:45.062810+00:00", + "updated_on": "2026-01-14T07:21:13.989238+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8979": "Internal Audit", + "field_9045": null, + "field_8980": "ISO readiness audit performed", + "field_8981": [ + 2 + ], + "field_8982": [ + 26, + 27 + ], + "field_9031": null, + "field_9020": null, + "field_9021": null, + "field_9022": null, + "field_9011": null, + "field_9017": null, + "field_9012": null, + "field_9013": null, + "field_9014": null, + "field_9015": null, + "field_9032": null, + "field_9038": null, + "field_9024": null, + "field_9025": null, + "field_9042": null, + "field_9050": null, + "field_9048": null, + "field_9051": null, + "field_9034": null, + "field_9027": null + }, + { + "id": 10, + "order": "10.00000000000000000000", + "created_on": "2026-01-14T07:19:45.062818+00:00", + "updated_on": "2026-01-14T07:21:14.305312+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8979": "Certification Audit", + "field_9045": null, + "field_8980": "External ISO 27001 certification", + "field_8981": [ + 2 + ], + "field_8982": [ + 28, + 29, + 30 + ], + "field_9031": null, + "field_9020": null, + "field_9021": null, + "field_9022": null, + "field_9011": null, + "field_9017": null, + "field_9012": null, + "field_9013": null, + "field_9014": null, + "field_9015": null, + "field_9032": null, + "field_9038": null, + "field_9024": null, + "field_9025": null, + "field_9042": null, + "field_9050": null, + "field_9048": null, + "field_9051": null, + "field_9034": null, + "field_9027": null + }, + { + "id": 11, + "order": "11.00000000000000000000", + "created_on": "2026-01-14T07:19:45.062826+00:00", + "updated_on": "2026-01-14T07:21:07.391903+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8979": "Campaign Strategy Approved", + "field_9045": null, + "field_8980": "Marketing plan and target audience defined", + "field_8981": [ + 3 + ], + "field_8982": [ + 31, + 32 + ], + "field_9031": null, + "field_9020": null, + "field_9021": null, + "field_9022": null, + "field_9011": null, + "field_9017": null, + "field_9012": null, + "field_9013": null, + "field_9014": null, + "field_9015": null, + "field_9032": null, + "field_9038": null, + "field_9024": null, + "field_9025": null, + "field_9042": null, + "field_9050": null, + "field_9048": null, + "field_9051": null, + "field_9034": null, + "field_9027": null + }, + { + "id": 12, + "order": "12.00000000000000000000", + "created_on": "2026-01-14T07:19:45.062834+00:00", + "updated_on": "2026-01-14T07:21:15.600162+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8979": "Creative Assets Ready", + "field_9045": null, + "field_8980": "All visuals and copy produced", + "field_8981": [ + 3 + ], + "field_8982": [ + 33, + 34 + ], + "field_9031": null, + "field_9020": null, + "field_9021": null, + "field_9022": null, + "field_9011": null, + "field_9017": null, + "field_9012": null, + "field_9013": null, + "field_9014": null, + "field_9015": null, + "field_9032": null, + "field_9038": null, + "field_9024": null, + "field_9025": null, + "field_9042": null, + "field_9050": null, + "field_9048": null, + "field_9051": null, + "field_9034": null, + "field_9027": null + }, + { + "id": 13, + "order": "13.00000000000000000000", + "created_on": "2026-01-14T07:19:45.062842+00:00", + "updated_on": "2026-01-14T07:21:16.019206+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8979": "Campaign Launched", + "field_9045": null, + "field_8980": "Campaign goes live across channels", + "field_8981": [ + 3 + ], + "field_8982": [ + 35, + 36 + ], + "field_9031": null, + "field_9020": null, + "field_9021": null, + "field_9022": null, + "field_9011": null, + "field_9017": null, + "field_9012": null, + "field_9013": null, + "field_9014": null, + "field_9015": null, + "field_9032": null, + "field_9038": null, + "field_9024": null, + "field_9025": null, + "field_9042": null, + "field_9050": null, + "field_9048": null, + "field_9051": null, + "field_9034": null, + "field_9027": null + }, + { + "id": 14, + "order": "14.00000000000000000000", + "created_on": "2026-01-14T07:19:45.062850+00:00", + "updated_on": "2026-01-14T07:21:16.354840+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8979": "Performance Review", + "field_9045": null, + "field_8980": "Campaign KPIs reviewed", + "field_8981": [ + 3 + ], + "field_8982": [ + 37, + 38 + ], + "field_9031": null, + "field_9020": null, + "field_9021": null, + "field_9022": null, + "field_9011": null, + "field_9017": null, + "field_9012": null, + "field_9013": null, + "field_9014": null, + "field_9015": null, + "field_9032": null, + "field_9038": null, + "field_9024": null, + "field_9025": null, + "field_9042": null, + "field_9050": null, + "field_9048": null, + "field_9051": null, + "field_9034": null, + "field_9027": null + } + ], + "data_sync": null, + "field_rules": [] + }, + { + "id": 957, + "name": "Tasks", + "order": 7, + "fields": [ + { + "id": 8983, + "type": "text", + "name": "Name", + "description": null, + "order": 2, + "primary": true, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "text_default": "" + }, + { + "id": 8984, + "type": "text", + "name": "Description", + "description": null, + "order": 3, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "text_default": "" + }, + { + "id": 8985, + "type": "single_select", + "name": "Status", + "description": null, + "order": 4, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "select_options": [ + { + "id": 3608, + "value": "To do", + "color": "light-cyan", + "order": 0 + }, + { + "id": 3609, + "value": "In progress", + "color": "light-yellow", + "order": 1 + }, + { + "id": 3610, + "value": "Done", + "color": "light-green", + "order": 2 + } + ], + "single_select_default": 3608 + }, + { + "id": 8986, + "type": "single_select", + "name": "Priority", + "description": null, + "order": 5, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "select_options": [ + { + "id": 3611, + "value": "Critical", + "color": "dark-red", + "order": 0 + }, + { + "id": 3612, + "value": "High", + "color": "dark-yellow", + "order": 1 + }, + { + "id": 3613, + "value": "Medium", + "color": "dark-blue", + "order": 2 + }, + { + "id": 3614, + "value": "Low", + "color": "dark-cyan", + "order": 3 + } + ], + "single_select_default": 3613 + }, + { + "id": 8987, + "type": "link_row", + "name": "Assignee", + "description": null, + "order": 6, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "link_row_table_id": 954, + "link_row_related_field_id": 8971, + "link_row_limit_selection_view_id": null, + "has_related_field": true, + "link_row_multiple_relationships": false + }, + { + "id": 8988, + "type": "date", + "name": "Start date", + "description": null, + "order": 8, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "date_format": "ISO", + "date_include_time": false, + "date_time_format": "24", + "date_show_tzinfo": false, + "date_force_timezone": null + }, + { + "id": 8989, + "type": "date", + "name": "Due date", + "description": null, + "order": 9, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "date_format": "ISO", + "date_include_time": false, + "date_time_format": "24", + "date_show_tzinfo": false, + "date_force_timezone": null + }, + { + "id": 8990, + "type": "date", + "name": "Completion date", + "description": null, + "order": 10, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "date_format": "ISO", + "date_include_time": false, + "date_time_format": "24", + "date_show_tzinfo": false, + "date_force_timezone": null + }, + { + "id": 8991, + "type": "link_row", + "name": "Phase", + "description": null, + "order": 14, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "link_row_table_id": 956, + "link_row_related_field_id": 8982, + "link_row_limit_selection_view_id": null, + "has_related_field": true, + "link_row_multiple_relationships": false + }, + { + "id": 8992, + "type": "link_row", + "name": "Project", + "description": null, + "order": 15, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "link_row_table_id": 955, + "link_row_related_field_id": 8976, + "link_row_limit_selection_view_id": null, + "has_related_field": true, + "link_row_multiple_relationships": false + }, + { + "id": 8993, + "type": "link_row", + "name": "Depends on", + "description": null, + "order": 16, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "link_row_table_id": 957, + "link_row_related_field_id": null, + "link_row_limit_selection_view_id": null, + "has_related_field": false, + "link_row_multiple_relationships": true + }, + { + "id": 8994, + "type": "link_row", + "name": "Subtasks", + "description": null, + "order": 19, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "link_row_table_id": 958, + "link_row_related_field_id": 9000, + "link_row_limit_selection_view_id": null, + "has_related_field": true, + "link_row_multiple_relationships": true + }, + { + "id": 9044, + "type": "rollup", + "name": "Registered workload", + "description": null, + "order": 20, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "date_show_tzinfo": null, + "number_prefix": "", + "number_separator": "", + "number_decimal_places": null, + "number_suffix": "", + "duration_format": "h:mm", + "nullable": true, + "date_time_format": null, + "date_force_timezone": null, + "array_formula_type": null, + "error": null, + "date_format": null, + "date_include_time": null, + "through_field_id": 8994, + "target_field_id": 9028, + "rollup_function": "sum" + }, + { + "id": 8995, + "type": "duration", + "name": "Task duration", + "description": null, + "order": 22, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "duration_format": "d h" + }, + { + "id": 9023, + "type": "formula", + "name": "Days until due date", + "description": null, + "order": 24, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "date_show_tzinfo": null, + "number_prefix": "", + "number_separator": "", + "number_decimal_places": null, + "number_suffix": "", + "duration_format": null, + "nullable": false, + "date_time_format": null, + "date_force_timezone": null, + "array_formula_type": null, + "error": null, + "date_format": null, + "date_include_time": null, + "formula": "if(field('Status') = 'Done',0,field('Due date') - today())", + "formula_type": "text" + }, + { + "id": 9018, + "type": "formula", + "name": "Blocked by", + "description": null, + "order": 25, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "date_show_tzinfo": null, + "number_prefix": "", + "number_separator": "", + "number_decimal_places": null, + "number_suffix": "", + "duration_format": null, + "nullable": false, + "date_time_format": null, + "date_force_timezone": null, + "array_formula_type": "text", + "error": null, + "date_format": null, + "date_include_time": null, + "formula": "filter(lookup('Depends on','Name'),lookup('Depends on','Status') != 'Done')", + "formula_type": "array" + }, + { + "id": 9035, + "type": "formula", + "name": "Blocked icon", + "description": null, + "order": 26, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "date_show_tzinfo": null, + "number_prefix": "", + "number_separator": "", + "number_decimal_places": null, + "number_suffix": "", + "duration_format": null, + "nullable": false, + "date_time_format": null, + "date_force_timezone": null, + "array_formula_type": null, + "error": null, + "date_format": null, + "date_include_time": null, + "formula": "if(count(field('Blocked by')) > 0,'\u26d4','')", + "formula_type": "text" + }, + { + "id": 9039, + "type": "formula", + "name": "Overdue icon", + "description": null, + "order": 27, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "date_show_tzinfo": null, + "number_prefix": "", + "number_separator": "", + "number_decimal_places": null, + "number_suffix": "", + "duration_format": null, + "nullable": false, + "date_time_format": null, + "date_force_timezone": null, + "array_formula_type": null, + "error": null, + "date_format": null, + "date_include_time": null, + "formula": "if(tonumber(split_part(field('Days until due date'),' ',1)) < 0,'\u23f0','')", + "formula_type": "text" + }, + { + "id": 8996, + "type": "number", + "name": "Estimated workload", + "description": null, + "order": 30, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "number_decimal_places": 0, + "number_negative": false, + "number_prefix": "", + "number_suffix": "", + "number_separator": "", + "number_default": null + }, + { + "id": 9052, + "type": "formula", + "name": "Workload difference", + "description": null, + "order": 31, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "date_show_tzinfo": null, + "number_prefix": "", + "number_separator": "", + "number_decimal_places": null, + "number_suffix": "", + "duration_format": "h:mm", + "nullable": true, + "date_time_format": null, + "date_force_timezone": null, + "array_formula_type": null, + "error": null, + "date_format": null, + "date_include_time": null, + "formula": "if(totext(field('Status')) = 'To do',field('Registered workload'),field('Registered workload') - date_interval(concat(field('Estimated workload'),' hours')))", + "formula_type": "duration" + }, + { + "id": 9056, + "type": "formula", + "name": "Difference icon", + "description": null, + "order": 32, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "date_show_tzinfo": null, + "number_prefix": "", + "number_separator": "", + "number_decimal_places": null, + "number_suffix": "", + "duration_format": null, + "nullable": false, + "date_time_format": null, + "date_force_timezone": null, + "array_formula_type": null, + "error": null, + "date_format": null, + "date_include_time": null, + "formula": "if(and(field('Status') != 'To do',toseconds(field('Workload difference')) > 0),'\u26a0\ufe0f','')", + "formula_type": "text" + }, + { + "id": 9057, + "type": "formula", + "name": "Icons", + "description": null, + "order": 33, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "date_show_tzinfo": null, + "number_prefix": "", + "number_separator": "", + "number_decimal_places": null, + "number_suffix": "", + "duration_format": null, + "nullable": false, + "date_time_format": null, + "date_force_timezone": null, + "array_formula_type": null, + "error": null, + "date_format": null, + "date_include_time": null, + "formula": "concat(field('Blocked icon'),field('Difference icon'),field('Overdue icon'),field('Budget icon'))", + "formula_type": "text" + }, + { + "id": 9019, + "type": "formula", + "name": "Subtask", + "description": null, + "order": 34, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "date_show_tzinfo": null, + "number_prefix": "", + "number_separator": "", + "number_decimal_places": null, + "number_suffix": "", + "duration_format": null, + "nullable": false, + "date_time_format": null, + "date_force_timezone": null, + "array_formula_type": null, + "error": null, + "date_format": null, + "date_include_time": null, + "formula": "button(concat('https://your-baserow-instance/form/Fs4SSZ0qA78L0_JAMcY4NcPFJf4RDjoSGSvwt0EhXfY?prefill_Task=',encode_uri(field('Name')),'&',encode_uri('prefill_Start time='),encode_uri(totext(now()))),'Add new subtask')", + "formula_type": "button" + }, + { + "id": 8997, + "type": "number", + "name": "Estimated budget", + "description": null, + "order": 35, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "number_decimal_places": 0, + "number_negative": false, + "number_prefix": "$", + "number_suffix": "", + "number_separator": "SPACE_COMMA", + "number_default": null + }, + { + "id": 8998, + "type": "number", + "name": "Actual expenses", + "description": null, + "order": 36, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "number_decimal_places": 0, + "number_negative": false, + "number_prefix": "$", + "number_suffix": "", + "number_separator": "SPACE_COMMA", + "number_default": null + }, + { + "id": 9026, + "type": "formula", + "name": "Budget difference", + "description": null, + "order": 37, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "date_show_tzinfo": null, + "number_prefix": "$", + "number_separator": "SPACE_COMMA", + "number_decimal_places": 0, + "number_suffix": "", + "duration_format": null, + "nullable": false, + "date_time_format": null, + "date_force_timezone": null, + "array_formula_type": null, + "error": null, + "date_format": null, + "date_include_time": null, + "formula": "if(field('Status') = 'To do',0,field('Estimated budget') - field('Actual expenses'))", + "formula_type": "number" + }, + { + "id": 9043, + "type": "formula", + "name": "Budget icon", + "description": null, + "order": 38, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "date_show_tzinfo": null, + "number_prefix": "", + "number_separator": "", + "number_decimal_places": null, + "number_suffix": "", + "duration_format": null, + "nullable": false, + "date_time_format": null, + "date_force_timezone": null, + "array_formula_type": null, + "error": null, + "date_format": null, + "date_include_time": null, + "formula": "if(field('Budget difference') < 0,'\ud83d\udcb0','')", + "formula_type": "text" + } + ], + "views": [ + { + "id": 3996, + "type": "grid", + "name": "All tasks", + "order": 1, + "ownership_type": "collaborative", + "owned_by": "frederik@baserow.io", + "filter_type": "AND", + "filters_disabled": false, + "filters": [], + "filter_groups": [], + "sortings": [], + "group_bys": [], + "decorations": [ + { + "id": 764, + "type": "background_color", + "value_provider_type": "conditional_color", + "value_provider_conf": { + "colors": [ + { + "id": "d0905d11-7900-4fd9-9ef9-74c3ba953f2b", + "color": "light-red", + "filters": [ + { + "id": "c361bd7f-855d-4367-9aaa-fd3e7688ffb3", + "type": "not_empty", + "field": 9039, + "group": null, + "value": "" + } + ], + "operator": "AND" + }, + { + "id": "c13748ee-f856-4cd0-9bdd-f520294a0342", + "color": "light-blue", + "filters": [ + { + "id": "5a0bcef3-dd1b-4e5f-ac3f-bc6d41985dfc", + "type": "not_empty", + "field": 9035, + "group": null, + "value": "" + } + ], + "operator": "AND" + }, + { + "id": "04bcf996-77ca-4e3b-917b-4e36b630b141", + "color": "light-yellow", + "filters": [ + { + "id": "e4690bce-1650-4fd3-8765-2e6bee7c2d75", + "type": "not_empty", + "field": 9056, + "group": null, + "value": "" + } + ], + "operator": "AND" + }, + { + "id": "aee1e016-bb9b-4603-a09c-ceea7cef74f0", + "color": "light-pink", + "filters": [ + { + "id": "cf287e4d-5ef0-4345-8a7b-fcef8c1dc56f", + "type": "not_empty", + "field": 9043, + "group": null, + "value": "" + } + ], + "operator": "AND" + } + ] + }, + "order": 1 + } + ], + "public": false, + "row_identifier_type": "id", + "row_height_size": "small", + "field_options": [ + { + "id": 33227, + "field_id": 9057, + "width": 95, + "hidden": false, + "order": 0, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33228, + "field_id": 9019, + "width": 152, + "hidden": false, + "order": 1, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33229, + "field_id": 8984, + "width": 200, + "hidden": false, + "order": 2, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33230, + "field_id": 8992, + "width": 200, + "hidden": false, + "order": 3, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33231, + "field_id": 8991, + "width": 200, + "hidden": false, + "order": 4, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33232, + "field_id": 8993, + "width": 200, + "hidden": false, + "order": 5, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33233, + "field_id": 9018, + "width": 200, + "hidden": false, + "order": 6, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33234, + "field_id": 9035, + "width": 155, + "hidden": true, + "order": 7, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33235, + "field_id": 8985, + "width": 146, + "hidden": false, + "order": 8, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33236, + "field_id": 8986, + "width": 117, + "hidden": false, + "order": 9, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33237, + "field_id": 8987, + "width": 157, + "hidden": false, + "order": 10, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33238, + "field_id": 8996, + "width": 184, + "hidden": false, + "order": 11, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33239, + "field_id": 9044, + "width": 183, + "hidden": false, + "order": 12, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33240, + "field_id": 9052, + "width": 184, + "hidden": false, + "order": 13, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33241, + "field_id": 9056, + "width": 78, + "hidden": true, + "order": 14, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33242, + "field_id": 8988, + "width": 200, + "hidden": false, + "order": 15, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33243, + "field_id": 8989, + "width": 200, + "hidden": false, + "order": 16, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33244, + "field_id": 8990, + "width": 158, + "hidden": false, + "order": 17, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33245, + "field_id": 9023, + "width": 175, + "hidden": false, + "order": 18, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33246, + "field_id": 9039, + "width": 86, + "hidden": true, + "order": 20, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33247, + "field_id": 8995, + "width": 170, + "hidden": false, + "order": 21, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33248, + "field_id": 8997, + "width": 168, + "hidden": false, + "order": 22, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33249, + "field_id": 8998, + "width": 164, + "hidden": false, + "order": 23, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33250, + "field_id": 9026, + "width": 174, + "hidden": false, + "order": 24, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33251, + "field_id": 9043, + "width": 200, + "hidden": true, + "order": 25, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33252, + "field_id": 8994, + "width": 200, + "hidden": false, + "order": 26, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33253, + "field_id": 8983, + "width": 200, + "hidden": false, + "order": 27, + "aggregation_type": "", + "aggregation_raw_type": "" + } + ] + }, + { + "id": 3997, + "type": "grid", + "name": "Overdue tasks", + "order": 3, + "ownership_type": "collaborative", + "owned_by": "frederik@baserow.io", + "filter_type": "AND", + "filters_disabled": false, + "filters": [ + { + "id": 2027, + "field_id": 9039, + "type": "not_empty", + "value": "", + "group": null + } + ], + "filter_groups": [], + "sortings": [], + "group_bys": [], + "decorations": [ + { + "id": 765, + "type": "background_color", + "value_provider_type": "conditional_color", + "value_provider_conf": { + "colors": [ + { + "id": "d0905d11-7900-4fd9-9ef9-74c3ba953f2b", + "color": "light-red", + "filters": [ + { + "id": "c361bd7f-855d-4367-9aaa-fd3e7688ffb3", + "type": "not_empty", + "field": 9039, + "group": null, + "value": "" + } + ], + "operator": "AND" + }, + { + "id": "c13748ee-f856-4cd0-9bdd-f520294a0342", + "color": "light-blue", + "filters": [ + { + "id": "5a0bcef3-dd1b-4e5f-ac3f-bc6d41985dfc", + "type": "not_empty", + "field": 9035, + "group": null, + "value": "" + } + ], + "operator": "AND" + }, + { + "id": "04bcf996-77ca-4e3b-917b-4e36b630b141", + "color": "light-yellow", + "filters": [ + { + "id": "e4690bce-1650-4fd3-8765-2e6bee7c2d75", + "type": "not_empty", + "field": 9056, + "group": null, + "value": "" + } + ], + "operator": "AND" + }, + { + "id": "aee1e016-bb9b-4603-a09c-ceea7cef74f0", + "color": "light-pink", + "filters": [ + { + "id": "cf287e4d-5ef0-4345-8a7b-fcef8c1dc56f", + "type": "not_empty", + "field": 9043, + "group": null, + "value": "" + } + ], + "operator": "AND" + } + ] + }, + "order": 1 + } + ], + "public": false, + "row_identifier_type": "id", + "row_height_size": "small", + "field_options": [ + { + "id": 33254, + "field_id": 9057, + "width": 95, + "hidden": false, + "order": 0, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33255, + "field_id": 9019, + "width": 152, + "hidden": false, + "order": 1, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33256, + "field_id": 8984, + "width": 200, + "hidden": false, + "order": 2, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33257, + "field_id": 8992, + "width": 200, + "hidden": false, + "order": 3, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33258, + "field_id": 8991, + "width": 200, + "hidden": false, + "order": 4, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33259, + "field_id": 8993, + "width": 200, + "hidden": false, + "order": 5, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33260, + "field_id": 9018, + "width": 200, + "hidden": false, + "order": 6, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33261, + "field_id": 9035, + "width": 155, + "hidden": true, + "order": 7, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33262, + "field_id": 8985, + "width": 146, + "hidden": false, + "order": 8, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33263, + "field_id": 8986, + "width": 117, + "hidden": false, + "order": 9, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33264, + "field_id": 8987, + "width": 157, + "hidden": false, + "order": 10, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33265, + "field_id": 8996, + "width": 184, + "hidden": false, + "order": 11, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33266, + "field_id": 9044, + "width": 183, + "hidden": false, + "order": 12, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33267, + "field_id": 9052, + "width": 184, + "hidden": false, + "order": 13, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33268, + "field_id": 9056, + "width": 78, + "hidden": true, + "order": 14, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33269, + "field_id": 8988, + "width": 200, + "hidden": false, + "order": 15, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33270, + "field_id": 8989, + "width": 200, + "hidden": false, + "order": 16, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33271, + "field_id": 8990, + "width": 158, + "hidden": false, + "order": 17, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33272, + "field_id": 9023, + "width": 175, + "hidden": false, + "order": 18, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33273, + "field_id": 9039, + "width": 86, + "hidden": true, + "order": 19, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33274, + "field_id": 8995, + "width": 170, + "hidden": false, + "order": 20, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33275, + "field_id": 8997, + "width": 168, + "hidden": false, + "order": 21, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33276, + "field_id": 8998, + "width": 164, + "hidden": false, + "order": 22, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33277, + "field_id": 9026, + "width": 174, + "hidden": false, + "order": 23, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33278, + "field_id": 9043, + "width": 200, + "hidden": true, + "order": 24, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33279, + "field_id": 8994, + "width": 200, + "hidden": false, + "order": 25, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33280, + "field_id": 8983, + "width": 200, + "hidden": false, + "order": 26, + "aggregation_type": "", + "aggregation_raw_type": "" + } + ] + }, + { + "id": 3998, + "type": "grid", + "name": "Tasks in progresss", + "order": 4, + "ownership_type": "collaborative", + "owned_by": "frederik@baserow.io", + "filter_type": "AND", + "filters_disabled": false, + "filters": [ + { + "id": 2028, + "field_id": 8985, + "type": "single_select_equal", + "value": "3609", + "group": null + } + ], + "filter_groups": [], + "sortings": [], + "group_bys": [], + "decorations": [ + { + "id": 766, + "type": "background_color", + "value_provider_type": "conditional_color", + "value_provider_conf": { + "colors": [ + { + "id": "d0905d11-7900-4fd9-9ef9-74c3ba953f2b", + "color": "light-red", + "filters": [ + { + "id": "c361bd7f-855d-4367-9aaa-fd3e7688ffb3", + "type": "not_empty", + "field": 9039, + "group": null, + "value": "" + } + ], + "operator": "AND" + }, + { + "id": "c13748ee-f856-4cd0-9bdd-f520294a0342", + "color": "light-blue", + "filters": [ + { + "id": "5a0bcef3-dd1b-4e5f-ac3f-bc6d41985dfc", + "type": "not_empty", + "field": 9035, + "group": null, + "value": "" + } + ], + "operator": "AND" + }, + { + "id": "04bcf996-77ca-4e3b-917b-4e36b630b141", + "color": "light-yellow", + "filters": [ + { + "id": "e4690bce-1650-4fd3-8765-2e6bee7c2d75", + "type": "not_empty", + "field": 9056, + "group": null, + "value": "" + } + ], + "operator": "AND" + }, + { + "id": "aee1e016-bb9b-4603-a09c-ceea7cef74f0", + "color": "light-pink", + "filters": [ + { + "id": "cf287e4d-5ef0-4345-8a7b-fcef8c1dc56f", + "type": "not_empty", + "field": 9043, + "group": null, + "value": "" + } + ], + "operator": "AND" + } + ] + }, + "order": 1 + } + ], + "public": false, + "row_identifier_type": "id", + "row_height_size": "small", + "field_options": [ + { + "id": 33281, + "field_id": 9057, + "width": 95, + "hidden": false, + "order": 0, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33282, + "field_id": 9019, + "width": 152, + "hidden": false, + "order": 1, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33283, + "field_id": 8984, + "width": 200, + "hidden": false, + "order": 2, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33284, + "field_id": 8992, + "width": 200, + "hidden": false, + "order": 3, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33285, + "field_id": 8991, + "width": 200, + "hidden": false, + "order": 4, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33286, + "field_id": 8993, + "width": 200, + "hidden": false, + "order": 5, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33287, + "field_id": 9018, + "width": 200, + "hidden": false, + "order": 6, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33288, + "field_id": 9035, + "width": 155, + "hidden": true, + "order": 7, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33289, + "field_id": 8985, + "width": 146, + "hidden": false, + "order": 8, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33290, + "field_id": 8986, + "width": 117, + "hidden": false, + "order": 9, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33291, + "field_id": 8987, + "width": 157, + "hidden": false, + "order": 10, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33292, + "field_id": 8996, + "width": 184, + "hidden": false, + "order": 11, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33293, + "field_id": 9044, + "width": 183, + "hidden": false, + "order": 12, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33294, + "field_id": 9052, + "width": 184, + "hidden": false, + "order": 13, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33295, + "field_id": 9056, + "width": 78, + "hidden": true, + "order": 14, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33296, + "field_id": 8988, + "width": 200, + "hidden": false, + "order": 15, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33297, + "field_id": 8989, + "width": 200, + "hidden": false, + "order": 16, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33298, + "field_id": 8990, + "width": 158, + "hidden": false, + "order": 17, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33299, + "field_id": 9023, + "width": 175, + "hidden": false, + "order": 18, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33300, + "field_id": 9039, + "width": 86, + "hidden": true, + "order": 19, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33301, + "field_id": 8995, + "width": 170, + "hidden": false, + "order": 20, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33302, + "field_id": 8997, + "width": 168, + "hidden": false, + "order": 21, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33303, + "field_id": 8998, + "width": 164, + "hidden": false, + "order": 22, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33304, + "field_id": 9026, + "width": 174, + "hidden": false, + "order": 23, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33305, + "field_id": 9043, + "width": 200, + "hidden": true, + "order": 24, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33306, + "field_id": 8994, + "width": 200, + "hidden": false, + "order": 25, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33307, + "field_id": 8983, + "width": 200, + "hidden": false, + "order": 26, + "aggregation_type": "", + "aggregation_raw_type": "" + } + ] + }, + { + "id": 3999, + "type": "form", + "name": "Add new task", + "order": 5, + "ownership_type": "collaborative", + "owned_by": "frederik@baserow.io", + "public": true, + "title": "Add a new task", + "description": "", + "cover_image": null, + "logo_image": null, + "submit_text": "Submit", + "submit_action": "MESSAGE", + "submit_action_message": "", + "submit_action_redirect_url": "", + "field_options": [ + { + "id": 3674, + "field_id": 8992, + "name": "", + "description": "", + "enabled": true, + "required": true, + "order": 0, + "show_when_matching_conditions": false, + "condition_type": "AND", + "conditions": [], + "condition_groups": [], + "field_component": "default", + "include_all_select_options": true, + "allowed_select_options": [] + }, + { + "id": 3675, + "field_id": 8991, + "name": "", + "description": "", + "enabled": true, + "required": true, + "order": 1, + "show_when_matching_conditions": false, + "condition_type": "AND", + "conditions": [], + "condition_groups": [], + "field_component": "default", + "include_all_select_options": true, + "allowed_select_options": [] + }, + { + "id": 3676, + "field_id": 8983, + "name": "", + "description": "", + "enabled": true, + "required": true, + "order": 2, + "show_when_matching_conditions": false, + "condition_type": "AND", + "conditions": [], + "condition_groups": [], + "field_component": "default", + "include_all_select_options": true, + "allowed_select_options": [] + }, + { + "id": 3677, + "field_id": 8984, + "name": "", + "description": "", + "enabled": true, + "required": false, + "order": 3, + "show_when_matching_conditions": false, + "condition_type": "AND", + "conditions": [], + "condition_groups": [], + "field_component": "default", + "include_all_select_options": true, + "allowed_select_options": [] + }, + { + "id": 3678, + "field_id": 8986, + "name": "", + "description": "", + "enabled": true, + "required": true, + "order": 4, + "show_when_matching_conditions": false, + "condition_type": "AND", + "conditions": [], + "condition_groups": [], + "field_component": "default", + "include_all_select_options": true, + "allowed_select_options": [] + }, + { + "id": 3679, + "field_id": 8987, + "name": "", + "description": "", + "enabled": true, + "required": true, + "order": 5, + "show_when_matching_conditions": false, + "condition_type": "AND", + "conditions": [], + "condition_groups": [], + "field_component": "default", + "include_all_select_options": true, + "allowed_select_options": [] + }, + { + "id": 3680, + "field_id": 8988, + "name": "", + "description": "", + "enabled": true, + "required": true, + "order": 6, + "show_when_matching_conditions": false, + "condition_type": "AND", + "conditions": [], + "condition_groups": [], + "field_component": "default", + "include_all_select_options": true, + "allowed_select_options": [] + }, + { + "id": 3681, + "field_id": 8989, + "name": "", + "description": "", + "enabled": true, + "required": true, + "order": 7, + "show_when_matching_conditions": false, + "condition_type": "AND", + "conditions": [], + "condition_groups": [], + "field_component": "default", + "include_all_select_options": true, + "allowed_select_options": [] + }, + { + "id": 3682, + "field_id": 8985, + "name": "", + "description": "", + "enabled": false, + "required": true, + "order": 8, + "show_when_matching_conditions": false, + "condition_type": "AND", + "conditions": [], + "condition_groups": [], + "field_component": "default", + "include_all_select_options": true, + "allowed_select_options": [] + }, + { + "id": 3683, + "field_id": 8990, + "name": "", + "description": "", + "enabled": false, + "required": true, + "order": 9, + "show_when_matching_conditions": false, + "condition_type": "AND", + "conditions": [], + "condition_groups": [], + "field_component": "default", + "include_all_select_options": true, + "allowed_select_options": [] + }, + { + "id": 3684, + "field_id": 8993, + "name": "", + "description": "", + "enabled": false, + "required": true, + "order": 10, + "show_when_matching_conditions": false, + "condition_type": "AND", + "conditions": [], + "condition_groups": [], + "field_component": "default", + "include_all_select_options": true, + "allowed_select_options": [] + }, + { + "id": 3685, + "field_id": 8994, + "name": "", + "description": "", + "enabled": false, + "required": true, + "order": 11, + "show_when_matching_conditions": false, + "condition_type": "AND", + "conditions": [], + "condition_groups": [], + "field_component": "default", + "include_all_select_options": true, + "allowed_select_options": [] + }, + { + "id": 3686, + "field_id": 8995, + "name": "", + "description": "", + "enabled": false, + "required": true, + "order": 12, + "show_when_matching_conditions": false, + "condition_type": "AND", + "conditions": [], + "condition_groups": [], + "field_component": "default", + "include_all_select_options": true, + "allowed_select_options": [] + }, + { + "id": 3687, + "field_id": 8996, + "name": "", + "description": "", + "enabled": true, + "required": true, + "order": 13, + "show_when_matching_conditions": false, + "condition_type": "AND", + "conditions": [], + "condition_groups": [], + "field_component": "default", + "include_all_select_options": true, + "allowed_select_options": [] + }, + { + "id": 3688, + "field_id": 9023, + "name": "", + "description": "", + "enabled": false, + "required": true, + "order": 14, + "show_when_matching_conditions": false, + "condition_type": "AND", + "conditions": [], + "condition_groups": [], + "field_component": "default", + "include_all_select_options": true, + "allowed_select_options": [] + }, + { + "id": 3689, + "field_id": 9018, + "name": "", + "description": "", + "enabled": false, + "required": true, + "order": 15, + "show_when_matching_conditions": false, + "condition_type": "AND", + "conditions": [], + "condition_groups": [], + "field_component": "default", + "include_all_select_options": true, + "allowed_select_options": [] + }, + { + "id": 3690, + "field_id": 9039, + "name": "", + "description": "", + "enabled": false, + "required": true, + "order": 16, + "show_when_matching_conditions": false, + "condition_type": "AND", + "conditions": [], + "condition_groups": [], + "field_component": "default", + "include_all_select_options": true, + "allowed_select_options": [] + }, + { + "id": 3691, + "field_id": 9035, + "name": "", + "description": "", + "enabled": false, + "required": true, + "order": 17, + "show_when_matching_conditions": false, + "condition_type": "AND", + "conditions": [], + "condition_groups": [], + "field_component": "default", + "include_all_select_options": true, + "allowed_select_options": [] + }, + { + "id": 3692, + "field_id": 9044, + "name": "", + "description": "", + "enabled": false, + "required": true, + "order": 18, + "show_when_matching_conditions": false, + "condition_type": "AND", + "conditions": [], + "condition_groups": [], + "field_component": "default", + "include_all_select_options": true, + "allowed_select_options": [] + }, + { + "id": 3693, + "field_id": 9052, + "name": "", + "description": "", + "enabled": false, + "required": true, + "order": 19, + "show_when_matching_conditions": false, + "condition_type": "AND", + "conditions": [], + "condition_groups": [], + "field_component": "default", + "include_all_select_options": true, + "allowed_select_options": [] + }, + { + "id": 3694, + "field_id": 9056, + "name": "", + "description": "", + "enabled": false, + "required": true, + "order": 20, + "show_when_matching_conditions": false, + "condition_type": "AND", + "conditions": [], + "condition_groups": [], + "field_component": "default", + "include_all_select_options": true, + "allowed_select_options": [] + }, + { + "id": 3695, + "field_id": 9057, + "name": "", + "description": "", + "enabled": false, + "required": true, + "order": 21, + "show_when_matching_conditions": false, + "condition_type": "AND", + "conditions": [], + "condition_groups": [], + "field_component": "default", + "include_all_select_options": true, + "allowed_select_options": [] + }, + { + "id": 3696, + "field_id": 9019, + "name": "", + "description": "", + "enabled": false, + "required": true, + "order": 22, + "show_when_matching_conditions": false, + "condition_type": "AND", + "conditions": [], + "condition_groups": [], + "field_component": "default", + "include_all_select_options": true, + "allowed_select_options": [] + }, + { + "id": 3697, + "field_id": 8997, + "name": "", + "description": "", + "enabled": true, + "required": true, + "order": 23, + "show_when_matching_conditions": false, + "condition_type": "AND", + "conditions": [], + "condition_groups": [], + "field_component": "default", + "include_all_select_options": true, + "allowed_select_options": [] + }, + { + "id": 3698, + "field_id": 8998, + "name": "", + "description": "", + "enabled": false, + "required": true, + "order": 24, + "show_when_matching_conditions": false, + "condition_type": "AND", + "conditions": [], + "condition_groups": [], + "field_component": "default", + "include_all_select_options": true, + "allowed_select_options": [] + }, + { + "id": 3699, + "field_id": 9026, + "name": "", + "description": "", + "enabled": false, + "required": true, + "order": 25, + "show_when_matching_conditions": false, + "condition_type": "AND", + "conditions": [], + "condition_groups": [], + "field_component": "default", + "include_all_select_options": true, + "allowed_select_options": [] + }, + { + "id": 3700, + "field_id": 9043, + "name": "", + "description": "", + "enabled": false, + "required": true, + "order": 26, + "show_when_matching_conditions": false, + "condition_type": "AND", + "conditions": [], + "condition_groups": [], + "field_component": "default", + "include_all_select_options": true, + "allowed_select_options": [] + } + ] + }, + { + "id": 4000, + "type": "kanban", + "name": "Kanban: All tasks", + "order": 6, + "ownership_type": "collaborative", + "owned_by": null, + "filter_type": "AND", + "filters_disabled": false, + "filters": [], + "filter_groups": [], + "sortings": [ + { + "id": 2624, + "field_id": 8988, + "order": "ASC" + } + ], + "decorations": [], + "public": false, + "single_select_field_id": 8985, + "field_options": [ + { + "id": 4693, + "field_id": 9057, + "hidden": false, + "order": 1 + }, + { + "id": 4694, + "field_id": 8992, + "hidden": false, + "order": 2 + }, + { + "id": 4695, + "field_id": 8983, + "hidden": false, + "order": 3 + }, + { + "id": 4696, + "field_id": 8984, + "hidden": false, + "order": 4 + }, + { + "id": 4697, + "field_id": 8985, + "hidden": false, + "order": 5 + }, + { + "id": 4698, + "field_id": 8986, + "hidden": false, + "order": 6 + }, + { + "id": 4699, + "field_id": 8987, + "hidden": false, + "order": 7 + }, + { + "id": 4700, + "field_id": 8988, + "hidden": false, + "order": 8 + }, + { + "id": 4701, + "field_id": 8989, + "hidden": false, + "order": 9 + }, + { + "id": 4702, + "field_id": 8990, + "hidden": false, + "order": 10 + }, + { + "id": 4703, + "field_id": 8991, + "hidden": false, + "order": 11 + }, + { + "id": 4704, + "field_id": 8993, + "hidden": false, + "order": 12 + }, + { + "id": 4705, + "field_id": 8994, + "hidden": false, + "order": 13 + }, + { + "id": 4706, + "field_id": 8995, + "hidden": false, + "order": 14 + }, + { + "id": 4707, + "field_id": 8996, + "hidden": false, + "order": 15 + }, + { + "id": 4708, + "field_id": 9023, + "hidden": false, + "order": 16 + }, + { + "id": 4709, + "field_id": 9018, + "hidden": false, + "order": 17 + }, + { + "id": 4710, + "field_id": 9039, + "hidden": true, + "order": 18 + }, + { + "id": 4711, + "field_id": 9035, + "hidden": true, + "order": 19 + }, + { + "id": 4712, + "field_id": 9044, + "hidden": false, + "order": 20 + }, + { + "id": 4713, + "field_id": 9052, + "hidden": false, + "order": 21 + }, + { + "id": 4714, + "field_id": 9056, + "hidden": true, + "order": 22 + }, + { + "id": 4715, + "field_id": 9019, + "hidden": true, + "order": 32767 + } + ] + }, + { + "id": 4001, + "type": "timeline", + "name": "Timeline: All tasks", + "order": 7, + "ownership_type": "collaborative", + "owned_by": null, + "filter_type": "AND", + "filters_disabled": false, + "filters": [], + "filter_groups": [], + "sortings": [], + "decorations": [ + { + "id": 767, + "type": "left_border_color", + "value_provider_type": "single_select_color", + "value_provider_conf": { + "field_id": 8985 + }, + "order": 1 + }, + { + "id": 768, + "type": "background_color", + "value_provider_type": "conditional_color", + "value_provider_conf": { + "colors": [ + { + "id": "35ce49f4-6745-4f3d-b4cd-6130c2435445", + "color": "light-red", + "filters": [ + { + "id": "f11195d1-19d6-4248-b91f-1a845f7ccfea", + "type": "not_empty", + "field": 9039, + "group": null, + "value": "" + } + ], + "operator": "AND" + }, + { + "id": "801e823d-32a6-4759-b485-e6f42988405b", + "color": "light-blue", + "filters": [ + { + "id": "eaa544d4-f22c-4188-81d8-e62df42814ff", + "type": "not_empty", + "field": 9035, + "group": null, + "value": "" + } + ], + "operator": "AND" + }, + { + "id": "241cca76-2a27-491c-8b88-8ef314714c4a", + "color": "light-orange", + "filters": [ + { + "id": "5bb2f507-1c99-4d64-9c71-3923c18e2870", + "type": "not_empty", + "field": 9056, + "group": null, + "value": "" + } + ], + "operator": "AND" + }, + { + "id": "dc387b01-d49e-4b00-b398-03758fccdb62", + "color": "light-pink", + "filters": [ + { + "id": "3521c967-f664-406b-a48d-28a4452b6267", + "type": "not_empty", + "field": 9043, + "group": null, + "value": "" + } + ], + "operator": "AND" + } + ] + }, + "order": 2 + } + ], + "public": false, + "start_date_field_id": 8988, + "end_date_field_id": 8989, + "field_options": [ + { + "id": 706, + "field_id": 9057, + "hidden": false, + "order": 1 + }, + { + "id": 707, + "field_id": 8992, + "hidden": false, + "order": 2 + }, + { + "id": 708, + "field_id": 8983, + "hidden": false, + "order": 3 + }, + { + "id": 709, + "field_id": 8984, + "hidden": true, + "order": 4 + }, + { + "id": 710, + "field_id": 8985, + "hidden": true, + "order": 5 + }, + { + "id": 711, + "field_id": 8986, + "hidden": true, + "order": 6 + }, + { + "id": 712, + "field_id": 8987, + "hidden": true, + "order": 7 + }, + { + "id": 713, + "field_id": 8988, + "hidden": true, + "order": 8 + }, + { + "id": 714, + "field_id": 8989, + "hidden": true, + "order": 9 + }, + { + "id": 715, + "field_id": 8990, + "hidden": true, + "order": 10 + }, + { + "id": 716, + "field_id": 8991, + "hidden": true, + "order": 11 + }, + { + "id": 717, + "field_id": 8993, + "hidden": true, + "order": 12 + }, + { + "id": 718, + "field_id": 8994, + "hidden": true, + "order": 13 + }, + { + "id": 719, + "field_id": 8995, + "hidden": true, + "order": 14 + }, + { + "id": 720, + "field_id": 8996, + "hidden": true, + "order": 15 + }, + { + "id": 721, + "field_id": 9023, + "hidden": true, + "order": 16 + }, + { + "id": 722, + "field_id": 9018, + "hidden": true, + "order": 17 + }, + { + "id": 723, + "field_id": 9039, + "hidden": true, + "order": 18 + }, + { + "id": 724, + "field_id": 9035, + "hidden": true, + "order": 19 + }, + { + "id": 725, + "field_id": 9044, + "hidden": true, + "order": 20 + }, + { + "id": 726, + "field_id": 9052, + "hidden": true, + "order": 21 + }, + { + "id": 727, + "field_id": 9056, + "hidden": true, + "order": 22 + }, + { + "id": 729, + "field_id": 8997, + "hidden": true, + "order": 32767 + }, + { + "id": 730, + "field_id": 8998, + "hidden": true, + "order": 32767 + }, + { + "id": 728, + "field_id": 9019, + "hidden": true, + "order": 32767 + }, + { + "id": 731, + "field_id": 9026, + "hidden": true, + "order": 32767 + }, + { + "id": 732, + "field_id": 9043, + "hidden": true, + "order": 32767 + } + ] + }, + { + "id": 4002, + "type": "calendar", + "name": "Calendar: All tasks", + "order": 8, + "ownership_type": "collaborative", + "owned_by": null, + "filter_type": "AND", + "filters_disabled": false, + "filters": [], + "filter_groups": [], + "sortings": [], + "decorations": [ + { + "id": 769, + "type": "left_border_color", + "value_provider_type": "single_select_color", + "value_provider_conf": { + "field_id": 8985 + }, + "order": 1 + }, + { + "id": 770, + "type": "background_color", + "value_provider_type": "conditional_color", + "value_provider_conf": { + "colors": [ + { + "id": "c226a089-94a6-45bc-b0dc-d2432b5431af", + "color": "light-red", + "filters": [ + { + "id": "ad20bf58-8a50-48ec-bd01-89ce6d78413c", + "type": "not_empty", + "field": 9039, + "group": null, + "value": "" + } + ], + "operator": "AND" + }, + { + "id": "3530295a-3bd6-41fb-9093-5b107ed29525", + "color": "light-blue", + "filters": [ + { + "id": "ce960a3b-4bf1-4475-bcd9-ff4846b605f3", + "type": "not_empty", + "field": 9035, + "group": null, + "value": "" + } + ], + "operator": "AND" + }, + { + "id": "a58985b1-e1ec-4c2c-82df-c7e30d6c3333", + "color": "light-yellow", + "filters": [ + { + "id": "fa730f78-d139-4c0a-ac35-6655337ef584", + "type": "not_empty", + "field": 9056, + "group": null, + "value": "" + } + ], + "operator": "AND" + }, + { + "id": "6c41d495-8a04-4c7e-9b1b-ad9580e065ea", + "color": "light-pink", + "filters": [ + { + "id": "18b38f11-58bd-4ce2-8924-ab1227bbf2d3", + "type": "not_empty", + "field": 9043, + "group": null, + "value": "" + } + ], + "operator": "AND" + } + ] + }, + "order": 2 + } + ], + "public": false, + "date_field_id": 8988, + "field_options": [ + { + "id": 1343, + "field_id": 8983, + "hidden": false, + "order": 32767 + }, + { + "id": 1344, + "field_id": 8984, + "hidden": true, + "order": 32767 + }, + { + "id": 1345, + "field_id": 8985, + "hidden": true, + "order": 32767 + }, + { + "id": 1346, + "field_id": 8986, + "hidden": true, + "order": 32767 + }, + { + "id": 1347, + "field_id": 8987, + "hidden": true, + "order": 32767 + }, + { + "id": 1348, + "field_id": 8988, + "hidden": true, + "order": 32767 + }, + { + "id": 1349, + "field_id": 8989, + "hidden": true, + "order": 32767 + }, + { + "id": 1350, + "field_id": 8990, + "hidden": true, + "order": 32767 + }, + { + "id": 1351, + "field_id": 8991, + "hidden": true, + "order": 32767 + }, + { + "id": 1352, + "field_id": 8992, + "hidden": false, + "order": 32767 + }, + { + "id": 1353, + "field_id": 8993, + "hidden": true, + "order": 32767 + }, + { + "id": 1354, + "field_id": 8994, + "hidden": true, + "order": 32767 + }, + { + "id": 1355, + "field_id": 8995, + "hidden": true, + "order": 32767 + }, + { + "id": 1356, + "field_id": 8996, + "hidden": true, + "order": 32767 + }, + { + "id": 1366, + "field_id": 8997, + "hidden": true, + "order": 32767 + }, + { + "id": 1367, + "field_id": 8998, + "hidden": true, + "order": 32767 + }, + { + "id": 1358, + "field_id": 9018, + "hidden": true, + "order": 32767 + }, + { + "id": 1365, + "field_id": 9019, + "hidden": true, + "order": 32767 + }, + { + "id": 1357, + "field_id": 9023, + "hidden": true, + "order": 32767 + }, + { + "id": 1368, + "field_id": 9026, + "hidden": true, + "order": 32767 + }, + { + "id": 1360, + "field_id": 9035, + "hidden": true, + "order": 32767 + }, + { + "id": 1359, + "field_id": 9039, + "hidden": true, + "order": 32767 + }, + { + "id": 1369, + "field_id": 9043, + "hidden": true, + "order": 32767 + }, + { + "id": 1361, + "field_id": 9044, + "hidden": true, + "order": 32767 + }, + { + "id": 1362, + "field_id": 9052, + "hidden": true, + "order": 32767 + }, + { + "id": 1363, + "field_id": 9056, + "hidden": true, + "order": 32767 + }, + { + "id": 1364, + "field_id": 9057, + "hidden": true, + "order": 32767 + } + ] + }, + { + "id": 4003, + "type": "grid", + "name": "Grid: CRM System Upgrade", + "order": 9, + "ownership_type": "collaborative", + "owned_by": null, + "filter_type": "AND", + "filters_disabled": false, + "filters": [ + { + "id": 2029, + "field_id": 8992, + "type": "link_row_has", + "value": "1", + "group": null + } + ], + "filter_groups": [], + "sortings": [ + { + "id": 2625, + "field_id": 8988, + "order": "ASC" + } + ], + "group_bys": [ + { + "id": 433, + "field_id": 8991, + "order": "ASC" + } + ], + "decorations": [ + { + "id": 771, + "type": "background_color", + "value_provider_type": "conditional_color", + "value_provider_conf": { + "colors": [ + { + "id": "d2bdac34-1d74-4efc-81e6-14ea5dc4475d", + "color": "light-red", + "filters": [ + { + "id": "0cc5b17b-99e4-496a-b97a-efe2f6de1d8b", + "type": "not_empty", + "field": 9039, + "group": null, + "value": "" + } + ], + "operator": "AND" + }, + { + "id": "fec2674d-5285-4361-841b-b5d1f7e3462f", + "color": "light-blue", + "filters": [ + { + "id": "a43c6f11-8ee6-4144-9954-717bb38628b3", + "type": "not_empty", + "field": 9035, + "group": null, + "value": "" + } + ], + "operator": "AND" + }, + { + "id": "4eacf9ec-9d68-4e92-a289-b2cafa492358", + "color": "light-yellow", + "filters": [ + { + "id": "15f5e904-3f52-490b-88dc-3f421b8338e9", + "type": "not_empty", + "field": 9056, + "group": null, + "value": "" + } + ], + "operator": "AND" + }, + { + "id": "deed9044-0280-48de-b15e-05e53f41678b", + "color": "light-pink", + "filters": [ + { + "id": "f41bfc2f-d3af-481c-aa07-68dc8f33e69c", + "type": "not_empty", + "field": 9043, + "group": null, + "value": "" + } + ], + "operator": "AND" + } + ] + }, + "order": 1 + } + ], + "public": true, + "row_identifier_type": "id", + "row_height_size": "small", + "field_options": [ + { + "id": 33308, + "field_id": 8983, + "width": 200, + "hidden": false, + "order": 0, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33309, + "field_id": 9057, + "width": 98, + "hidden": false, + "order": 1, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33310, + "field_id": 9019, + "width": 200, + "hidden": false, + "order": 2, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33311, + "field_id": 8984, + "width": 300, + "hidden": false, + "order": 3, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33312, + "field_id": 8985, + "width": 200, + "hidden": false, + "order": 4, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33313, + "field_id": 8986, + "width": 200, + "hidden": false, + "order": 5, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33314, + "field_id": 8987, + "width": 200, + "hidden": false, + "order": 6, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33315, + "field_id": 8988, + "width": 200, + "hidden": false, + "order": 7, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33316, + "field_id": 8989, + "width": 200, + "hidden": false, + "order": 8, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33317, + "field_id": 8990, + "width": 200, + "hidden": false, + "order": 9, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33318, + "field_id": 8991, + "width": 200, + "hidden": false, + "order": 10, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33319, + "field_id": 8992, + "width": 200, + "hidden": false, + "order": 11, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33320, + "field_id": 8993, + "width": 200, + "hidden": false, + "order": 12, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33321, + "field_id": 8994, + "width": 200, + "hidden": false, + "order": 13, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33322, + "field_id": 8995, + "width": 200, + "hidden": false, + "order": 14, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33323, + "field_id": 8996, + "width": 200, + "hidden": false, + "order": 15, + "aggregation_type": "sum", + "aggregation_raw_type": "sum" + }, + { + "id": 33324, + "field_id": 9023, + "width": 200, + "hidden": false, + "order": 16, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33325, + "field_id": 9018, + "width": 200, + "hidden": false, + "order": 17, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33326, + "field_id": 9039, + "width": 200, + "hidden": true, + "order": 18, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33327, + "field_id": 9035, + "width": 200, + "hidden": true, + "order": 19, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33328, + "field_id": 9044, + "width": 200, + "hidden": false, + "order": 20, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33329, + "field_id": 9052, + "width": 200, + "hidden": false, + "order": 21, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33330, + "field_id": 9056, + "width": 200, + "hidden": true, + "order": 22, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33331, + "field_id": 8997, + "width": 200, + "hidden": false, + "order": 23, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33332, + "field_id": 8998, + "width": 200, + "hidden": false, + "order": 24, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33333, + "field_id": 9026, + "width": 200, + "hidden": false, + "order": 25, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33334, + "field_id": 9043, + "width": 200, + "hidden": true, + "order": 26, + "aggregation_type": "", + "aggregation_raw_type": "" + } + ] + }, + { + "id": 4004, + "type": "kanban", + "name": "Kanban: CRM System Upgrade", + "order": 10, + "ownership_type": "collaborative", + "owned_by": null, + "filter_type": "AND", + "filters_disabled": false, + "filters": [ + { + "id": 2030, + "field_id": 8992, + "type": "link_row_has", + "value": "2", + "group": null + } + ], + "filter_groups": [], + "sortings": [ + { + "id": 2626, + "field_id": 8988, + "order": "ASC" + } + ], + "decorations": [], + "public": true, + "single_select_field_id": 8985, + "field_options": [ + { + "id": 4716, + "field_id": 9057, + "hidden": false, + "order": 1 + }, + { + "id": 4717, + "field_id": 8983, + "hidden": false, + "order": 2 + }, + { + "id": 4718, + "field_id": 8984, + "hidden": false, + "order": 3 + }, + { + "id": 4719, + "field_id": 8985, + "hidden": false, + "order": 4 + }, + { + "id": 4720, + "field_id": 8986, + "hidden": false, + "order": 5 + }, + { + "id": 4721, + "field_id": 8987, + "hidden": false, + "order": 6 + }, + { + "id": 4722, + "field_id": 8988, + "hidden": false, + "order": 7 + }, + { + "id": 4723, + "field_id": 8989, + "hidden": false, + "order": 8 + }, + { + "id": 4724, + "field_id": 8990, + "hidden": false, + "order": 9 + }, + { + "id": 4725, + "field_id": 8991, + "hidden": false, + "order": 10 + }, + { + "id": 4726, + "field_id": 8992, + "hidden": false, + "order": 11 + }, + { + "id": 4727, + "field_id": 8993, + "hidden": false, + "order": 12 + }, + { + "id": 4728, + "field_id": 8994, + "hidden": false, + "order": 13 + }, + { + "id": 4729, + "field_id": 8995, + "hidden": false, + "order": 14 + }, + { + "id": 4730, + "field_id": 8996, + "hidden": false, + "order": 15 + }, + { + "id": 4731, + "field_id": 9023, + "hidden": false, + "order": 16 + }, + { + "id": 4732, + "field_id": 9018, + "hidden": false, + "order": 17 + }, + { + "id": 4733, + "field_id": 9039, + "hidden": true, + "order": 18 + }, + { + "id": 4734, + "field_id": 9035, + "hidden": true, + "order": 19 + }, + { + "id": 4735, + "field_id": 9044, + "hidden": false, + "order": 20 + }, + { + "id": 4736, + "field_id": 9052, + "hidden": false, + "order": 21 + }, + { + "id": 4737, + "field_id": 9056, + "hidden": true, + "order": 22 + }, + { + "id": 4738, + "field_id": 9019, + "hidden": true, + "order": 32767 + } + ] + }, + { + "id": 4005, + "type": "timeline", + "name": "Timeline: CRM System Upgrade", + "order": 11, + "ownership_type": "collaborative", + "owned_by": null, + "filter_type": "AND", + "filters_disabled": false, + "filters": [ + { + "id": 2031, + "field_id": 8992, + "type": "link_row_has", + "value": "1", + "group": null + } + ], + "filter_groups": [], + "sortings": [], + "decorations": [ + { + "id": 772, + "type": "left_border_color", + "value_provider_type": "single_select_color", + "value_provider_conf": { + "field_id": 8985 + }, + "order": 1 + }, + { + "id": 773, + "type": "background_color", + "value_provider_type": "conditional_color", + "value_provider_conf": { + "colors": [ + { + "id": "35ce49f4-6745-4f3d-b4cd-6130c2435445", + "color": "light-red", + "filters": [ + { + "id": "f11195d1-19d6-4248-b91f-1a845f7ccfea", + "type": "not_empty", + "field": 9039, + "group": null, + "value": "" + } + ], + "operator": "AND" + }, + { + "id": "801e823d-32a6-4759-b485-e6f42988405b", + "color": "light-blue", + "filters": [ + { + "id": "eaa544d4-f22c-4188-81d8-e62df42814ff", + "type": "not_empty", + "field": 9035, + "group": null, + "value": "" + } + ], + "operator": "AND" + }, + { + "id": "241cca76-2a27-491c-8b88-8ef314714c4a", + "color": "light-orange", + "filters": [ + { + "id": "72606aba-7b03-4446-a8f3-c236afdb95fa", + "type": "not_empty", + "field": 9056, + "group": null, + "value": "" + } + ], + "operator": "AND" + }, + { + "id": "ba32bd72-1c87-44dd-ab2e-92e752713c7c", + "color": "light-pink", + "filters": [ + { + "id": "530a1d56-e524-490a-9433-cd814a7f6b9b", + "type": "not_empty", + "field": 9043, + "group": null, + "value": "" + } + ], + "operator": "AND" + } + ] + }, + "order": 2 + } + ], + "public": false, + "start_date_field_id": 8988, + "end_date_field_id": 8989, + "field_options": [ + { + "id": 733, + "field_id": 9057, + "hidden": false, + "order": 1 + }, + { + "id": 734, + "field_id": 8983, + "hidden": false, + "order": 2 + }, + { + "id": 735, + "field_id": 8984, + "hidden": true, + "order": 3 + }, + { + "id": 736, + "field_id": 8985, + "hidden": true, + "order": 4 + }, + { + "id": 737, + "field_id": 8986, + "hidden": true, + "order": 5 + }, + { + "id": 738, + "field_id": 8987, + "hidden": true, + "order": 6 + }, + { + "id": 739, + "field_id": 8988, + "hidden": true, + "order": 7 + }, + { + "id": 740, + "field_id": 8989, + "hidden": true, + "order": 8 + }, + { + "id": 741, + "field_id": 8990, + "hidden": true, + "order": 9 + }, + { + "id": 742, + "field_id": 8991, + "hidden": true, + "order": 10 + }, + { + "id": 743, + "field_id": 8992, + "hidden": true, + "order": 11 + }, + { + "id": 744, + "field_id": 8993, + "hidden": true, + "order": 12 + }, + { + "id": 745, + "field_id": 8994, + "hidden": true, + "order": 13 + }, + { + "id": 746, + "field_id": 8995, + "hidden": true, + "order": 14 + }, + { + "id": 747, + "field_id": 8996, + "hidden": true, + "order": 15 + }, + { + "id": 748, + "field_id": 9023, + "hidden": true, + "order": 16 + }, + { + "id": 749, + "field_id": 9018, + "hidden": true, + "order": 17 + }, + { + "id": 750, + "field_id": 9039, + "hidden": true, + "order": 18 + }, + { + "id": 751, + "field_id": 9035, + "hidden": true, + "order": 19 + }, + { + "id": 752, + "field_id": 9044, + "hidden": true, + "order": 20 + }, + { + "id": 753, + "field_id": 9052, + "hidden": true, + "order": 21 + }, + { + "id": 754, + "field_id": 9056, + "hidden": true, + "order": 22 + }, + { + "id": 756, + "field_id": 8997, + "hidden": true, + "order": 32767 + }, + { + "id": 757, + "field_id": 8998, + "hidden": true, + "order": 32767 + }, + { + "id": 755, + "field_id": 9019, + "hidden": true, + "order": 32767 + }, + { + "id": 758, + "field_id": 9026, + "hidden": true, + "order": 32767 + }, + { + "id": 759, + "field_id": 9043, + "hidden": true, + "order": 32767 + } + ] + }, + { + "id": 4006, + "type": "calendar", + "name": "Calendar: CRM System Upgrade", + "order": 12, + "ownership_type": "collaborative", + "owned_by": null, + "filter_type": "AND", + "filters_disabled": false, + "filters": [ + { + "id": 2032, + "field_id": 8992, + "type": "link_row_has", + "value": "1", + "group": null + } + ], + "filter_groups": [], + "sortings": [], + "decorations": [ + { + "id": 774, + "type": "left_border_color", + "value_provider_type": "single_select_color", + "value_provider_conf": { + "field_id": 8985 + }, + "order": 1 + }, + { + "id": 775, + "type": "background_color", + "value_provider_type": "conditional_color", + "value_provider_conf": { + "colors": [ + { + "id": "c226a089-94a6-45bc-b0dc-d2432b5431af", + "color": "light-red", + "filters": [ + { + "id": "ad20bf58-8a50-48ec-bd01-89ce6d78413c", + "type": "not_empty", + "field": 9039, + "group": null, + "value": "" + } + ], + "operator": "AND" + }, + { + "id": "3530295a-3bd6-41fb-9093-5b107ed29525", + "color": "light-blue", + "filters": [ + { + "id": "ce960a3b-4bf1-4475-bcd9-ff4846b605f3", + "type": "not_empty", + "field": 9035, + "group": null, + "value": "" + } + ], + "operator": "AND" + }, + { + "id": "a58985b1-e1ec-4c2c-82df-c7e30d6c3333", + "color": "light-yellow", + "filters": [ + { + "id": "87d3e88f-5c3a-414d-8981-f337bd3ddab8", + "type": "not_empty", + "field": 9056, + "group": null, + "value": "" + } + ], + "operator": "AND" + }, + { + "id": "3f58bb4d-b985-4c2f-8b9b-0b0309c0fabd", + "color": "light-pink", + "filters": [ + { + "id": "a03299bb-090f-4d50-b2b6-976e8454c1fc", + "type": "not_empty", + "field": 9043, + "group": null, + "value": "" + } + ], + "operator": "AND" + } + ] + }, + "order": 2 + } + ], + "public": true, + "date_field_id": 8988, + "field_options": [ + { + "id": 1370, + "field_id": 8983, + "hidden": false, + "order": 32767 + }, + { + "id": 1371, + "field_id": 8984, + "hidden": true, + "order": 32767 + }, + { + "id": 1372, + "field_id": 8985, + "hidden": true, + "order": 32767 + }, + { + "id": 1373, + "field_id": 8986, + "hidden": true, + "order": 32767 + }, + { + "id": 1374, + "field_id": 8987, + "hidden": true, + "order": 32767 + }, + { + "id": 1375, + "field_id": 8988, + "hidden": true, + "order": 32767 + }, + { + "id": 1376, + "field_id": 8989, + "hidden": true, + "order": 32767 + }, + { + "id": 1377, + "field_id": 8990, + "hidden": true, + "order": 32767 + }, + { + "id": 1378, + "field_id": 8991, + "hidden": true, + "order": 32767 + }, + { + "id": 1379, + "field_id": 8992, + "hidden": true, + "order": 32767 + }, + { + "id": 1380, + "field_id": 8993, + "hidden": true, + "order": 32767 + }, + { + "id": 1381, + "field_id": 8994, + "hidden": true, + "order": 32767 + }, + { + "id": 1382, + "field_id": 8995, + "hidden": true, + "order": 32767 + }, + { + "id": 1383, + "field_id": 8996, + "hidden": true, + "order": 32767 + }, + { + "id": 1393, + "field_id": 8997, + "hidden": true, + "order": 32767 + }, + { + "id": 1394, + "field_id": 8998, + "hidden": true, + "order": 32767 + }, + { + "id": 1385, + "field_id": 9018, + "hidden": true, + "order": 32767 + }, + { + "id": 1392, + "field_id": 9019, + "hidden": true, + "order": 32767 + }, + { + "id": 1384, + "field_id": 9023, + "hidden": true, + "order": 32767 + }, + { + "id": 1395, + "field_id": 9026, + "hidden": true, + "order": 32767 + }, + { + "id": 1387, + "field_id": 9035, + "hidden": true, + "order": 32767 + }, + { + "id": 1386, + "field_id": 9039, + "hidden": true, + "order": 32767 + }, + { + "id": 1396, + "field_id": 9043, + "hidden": true, + "order": 32767 + }, + { + "id": 1388, + "field_id": 9044, + "hidden": true, + "order": 32767 + }, + { + "id": 1389, + "field_id": 9052, + "hidden": true, + "order": 32767 + }, + { + "id": 1390, + "field_id": 9056, + "hidden": true, + "order": 32767 + }, + { + "id": 1391, + "field_id": 9057, + "hidden": true, + "order": 32767 + } + ] + }, + { + "id": 4007, + "type": "grid", + "name": "Grid: ISO 27001 Compliance", + "order": 13, + "ownership_type": "collaborative", + "owned_by": null, + "filter_type": "AND", + "filters_disabled": false, + "filters": [ + { + "id": 2033, + "field_id": 8992, + "type": "link_row_has", + "value": "2", + "group": null + } + ], + "filter_groups": [], + "sortings": [ + { + "id": 2627, + "field_id": 8988, + "order": "ASC" + } + ], + "group_bys": [ + { + "id": 434, + "field_id": 8991, + "order": "ASC" + } + ], + "decorations": [ + { + "id": 776, + "type": "background_color", + "value_provider_type": "conditional_color", + "value_provider_conf": { + "colors": [ + { + "id": "d2bdac34-1d74-4efc-81e6-14ea5dc4475d", + "color": "light-red", + "filters": [ + { + "id": "0cc5b17b-99e4-496a-b97a-efe2f6de1d8b", + "type": "not_empty", + "field": 9039, + "group": null, + "value": "" + } + ], + "operator": "AND" + }, + { + "id": "fec2674d-5285-4361-841b-b5d1f7e3462f", + "color": "light-blue", + "filters": [ + { + "id": "a43c6f11-8ee6-4144-9954-717bb38628b3", + "type": "not_empty", + "field": 9035, + "group": null, + "value": "" + } + ], + "operator": "AND" + }, + { + "id": "4eacf9ec-9d68-4e92-a289-b2cafa492358", + "color": "light-yellow", + "filters": [ + { + "id": "dc9b91a6-a1a5-4cc1-a410-eeacf2b95ee6", + "type": "not_empty", + "field": 9056, + "group": null, + "value": "" + } + ], + "operator": "AND" + }, + { + "id": "1ff9968b-4a55-4348-aa1a-892ff2cf18db", + "color": "light-pink", + "filters": [ + { + "id": "8a8a1e9b-1955-440f-91de-61d1a8580d04", + "type": "not_empty", + "field": 9043, + "group": null, + "value": "" + } + ], + "operator": "AND" + } + ] + }, + "order": 1 + } + ], + "public": false, + "row_identifier_type": "id", + "row_height_size": "small", + "field_options": [ + { + "id": 33335, + "field_id": 8983, + "width": 200, + "hidden": false, + "order": 0, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33336, + "field_id": 9057, + "width": 98, + "hidden": false, + "order": 1, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33337, + "field_id": 9019, + "width": 200, + "hidden": false, + "order": 2, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33338, + "field_id": 8984, + "width": 200, + "hidden": false, + "order": 3, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33339, + "field_id": 8985, + "width": 200, + "hidden": false, + "order": 4, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33340, + "field_id": 8986, + "width": 200, + "hidden": false, + "order": 5, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33341, + "field_id": 8987, + "width": 200, + "hidden": false, + "order": 6, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33342, + "field_id": 8988, + "width": 200, + "hidden": false, + "order": 7, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33343, + "field_id": 8989, + "width": 200, + "hidden": false, + "order": 8, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33344, + "field_id": 8990, + "width": 200, + "hidden": false, + "order": 9, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33345, + "field_id": 8991, + "width": 200, + "hidden": false, + "order": 10, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33346, + "field_id": 8992, + "width": 200, + "hidden": false, + "order": 11, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33347, + "field_id": 8993, + "width": 200, + "hidden": false, + "order": 12, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33348, + "field_id": 8994, + "width": 200, + "hidden": false, + "order": 13, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33349, + "field_id": 8995, + "width": 200, + "hidden": false, + "order": 14, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33350, + "field_id": 8996, + "width": 200, + "hidden": false, + "order": 15, + "aggregation_type": "sum", + "aggregation_raw_type": "sum" + }, + { + "id": 33351, + "field_id": 9023, + "width": 200, + "hidden": false, + "order": 16, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33352, + "field_id": 9018, + "width": 200, + "hidden": false, + "order": 17, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33353, + "field_id": 9039, "width": 200, "hidden": true, - "order": 32767, + "order": 18, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33354, + "field_id": 9035, + "width": 200, + "hidden": true, + "order": 19, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33355, + "field_id": 9044, + "width": 200, + "hidden": false, + "order": 20, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33356, + "field_id": 9052, + "width": 200, + "hidden": false, + "order": 21, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33357, + "field_id": 9056, + "width": 200, + "hidden": true, + "order": 22, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33358, + "field_id": 8997, + "width": 200, + "hidden": false, + "order": 23, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33359, + "field_id": 8998, + "width": 200, + "hidden": false, + "order": 24, "aggregation_type": "", "aggregation_raw_type": "" }, { - "id": 3033203, - "field_id": 1859644, + "id": 33360, + "field_id": 9026, "width": 200, "hidden": false, - "order": 32767, + "order": 25, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33361, + "field_id": 9043, + "width": 200, + "hidden": true, + "order": 26, "aggregation_type": "", "aggregation_raw_type": "" } ] }, { - "id": 437956, - "type": "grid", - "name": "All projects grouped by client", - "order": 2, + "id": 4008, + "type": "timeline", + "name": "Timeline: ISO 27001 Compliance", + "order": 14, + "ownership_type": "collaborative", + "owned_by": null, + "filter_type": "AND", + "filters_disabled": false, + "filters": [ + { + "id": 2034, + "field_id": 8992, + "type": "link_row_has", + "value": "2", + "group": null + } + ], + "filter_groups": [], + "sortings": [], + "decorations": [ + { + "id": 777, + "type": "left_border_color", + "value_provider_type": "single_select_color", + "value_provider_conf": { + "field_id": 8985 + }, + "order": 1 + }, + { + "id": 778, + "type": "background_color", + "value_provider_type": "conditional_color", + "value_provider_conf": { + "colors": [ + { + "id": "35ce49f4-6745-4f3d-b4cd-6130c2435445", + "color": "light-red", + "filters": [ + { + "id": "f11195d1-19d6-4248-b91f-1a845f7ccfea", + "type": "not_empty", + "field": 9039, + "group": null, + "value": "" + } + ], + "operator": "AND" + }, + { + "id": "801e823d-32a6-4759-b485-e6f42988405b", + "color": "light-blue", + "filters": [ + { + "id": "eaa544d4-f22c-4188-81d8-e62df42814ff", + "type": "not_empty", + "field": 9035, + "group": null, + "value": "" + } + ], + "operator": "AND" + }, + { + "id": "241cca76-2a27-491c-8b88-8ef314714c4a", + "color": "light-orange", + "filters": [ + { + "id": "62d3b3a5-6bfd-41df-a80f-563670634b2d", + "type": "not_empty", + "field": 9056, + "group": null, + "value": "" + } + ], + "operator": "AND" + }, + { + "id": "1d7d953c-1cf6-47d3-a80f-37fa11f3768c", + "color": "light-pink", + "filters": [ + { + "id": "96508724-cce3-416c-a429-418b5fceb9dc", + "type": "not_empty", + "field": 9043, + "group": null, + "value": "" + } + ], + "operator": "AND" + } + ] + }, + "order": 2 + } + ], + "public": true, + "start_date_field_id": 8988, + "end_date_field_id": 8989, + "field_options": [ + { + "id": 760, + "field_id": 9057, + "hidden": false, + "order": 1 + }, + { + "id": 761, + "field_id": 8983, + "hidden": false, + "order": 2 + }, + { + "id": 762, + "field_id": 8984, + "hidden": true, + "order": 3 + }, + { + "id": 763, + "field_id": 8985, + "hidden": true, + "order": 4 + }, + { + "id": 764, + "field_id": 8986, + "hidden": true, + "order": 5 + }, + { + "id": 765, + "field_id": 8987, + "hidden": true, + "order": 6 + }, + { + "id": 766, + "field_id": 8988, + "hidden": true, + "order": 7 + }, + { + "id": 767, + "field_id": 8989, + "hidden": true, + "order": 8 + }, + { + "id": 768, + "field_id": 8990, + "hidden": true, + "order": 9 + }, + { + "id": 769, + "field_id": 8991, + "hidden": true, + "order": 10 + }, + { + "id": 770, + "field_id": 8992, + "hidden": true, + "order": 11 + }, + { + "id": 771, + "field_id": 8993, + "hidden": true, + "order": 12 + }, + { + "id": 772, + "field_id": 8994, + "hidden": true, + "order": 13 + }, + { + "id": 773, + "field_id": 8995, + "hidden": true, + "order": 14 + }, + { + "id": 774, + "field_id": 8996, + "hidden": true, + "order": 15 + }, + { + "id": 775, + "field_id": 9023, + "hidden": true, + "order": 16 + }, + { + "id": 776, + "field_id": 9018, + "hidden": true, + "order": 17 + }, + { + "id": 777, + "field_id": 9039, + "hidden": true, + "order": 18 + }, + { + "id": 778, + "field_id": 9035, + "hidden": true, + "order": 19 + }, + { + "id": 779, + "field_id": 9044, + "hidden": true, + "order": 20 + }, + { + "id": 780, + "field_id": 9052, + "hidden": true, + "order": 21 + }, + { + "id": 781, + "field_id": 9056, + "hidden": true, + "order": 22 + }, + { + "id": 783, + "field_id": 8997, + "hidden": true, + "order": 32767 + }, + { + "id": 784, + "field_id": 8998, + "hidden": true, + "order": 32767 + }, + { + "id": 782, + "field_id": 9019, + "hidden": true, + "order": 32767 + }, + { + "id": 785, + "field_id": 9026, + "hidden": true, + "order": 32767 + }, + { + "id": 786, + "field_id": 9043, + "hidden": true, + "order": 32767 + } + ] + }, + { + "id": 4009, + "type": "kanban", + "name": "Kanban: ISO 27001 Compliance", + "order": 15, + "ownership_type": "collaborative", + "owned_by": null, + "filter_type": "AND", + "filters_disabled": false, + "filters": [ + { + "id": 2035, + "field_id": 8992, + "type": "link_row_has", + "value": "2", + "group": null + } + ], + "filter_groups": [], + "sortings": [ + { + "id": 2628, + "field_id": 8988, + "order": "ASC" + } + ], + "decorations": [], + "public": true, + "single_select_field_id": 8985, + "field_options": [ + { + "id": 4739, + "field_id": 9057, + "hidden": false, + "order": 1 + }, + { + "id": 4740, + "field_id": 8983, + "hidden": false, + "order": 2 + }, + { + "id": 4741, + "field_id": 8984, + "hidden": false, + "order": 3 + }, + { + "id": 4742, + "field_id": 8985, + "hidden": false, + "order": 4 + }, + { + "id": 4743, + "field_id": 8986, + "hidden": false, + "order": 5 + }, + { + "id": 4744, + "field_id": 8987, + "hidden": false, + "order": 6 + }, + { + "id": 4745, + "field_id": 8988, + "hidden": false, + "order": 7 + }, + { + "id": 4746, + "field_id": 8989, + "hidden": false, + "order": 8 + }, + { + "id": 4747, + "field_id": 8990, + "hidden": false, + "order": 9 + }, + { + "id": 4748, + "field_id": 8991, + "hidden": false, + "order": 10 + }, + { + "id": 4749, + "field_id": 8992, + "hidden": false, + "order": 11 + }, + { + "id": 4750, + "field_id": 8993, + "hidden": false, + "order": 12 + }, + { + "id": 4751, + "field_id": 8994, + "hidden": false, + "order": 13 + }, + { + "id": 4752, + "field_id": 8995, + "hidden": false, + "order": 14 + }, + { + "id": 4753, + "field_id": 8996, + "hidden": false, + "order": 15 + }, + { + "id": 4754, + "field_id": 9023, + "hidden": false, + "order": 16 + }, + { + "id": 4755, + "field_id": 9018, + "hidden": false, + "order": 17 + }, + { + "id": 4756, + "field_id": 9039, + "hidden": true, + "order": 18 + }, + { + "id": 4757, + "field_id": 9035, + "hidden": true, + "order": 19 + }, + { + "id": 4758, + "field_id": 9044, + "hidden": false, + "order": 20 + }, + { + "id": 4759, + "field_id": 9052, + "hidden": true, + "order": 21 + }, + { + "id": 4760, + "field_id": 9056, + "hidden": false, + "order": 22 + } + ] + }, + { + "id": 4010, + "type": "calendar", + "name": "Calendar: ISO 27001 Compliance", + "order": 16, "ownership_type": "collaborative", "owned_by": null, "filter_type": "AND", "filters_disabled": false, - "filters": [], - "filter_groups": [], - "sortings": [ + "filters": [ { - "id": 162281, - "field_id": 1859525, - "order": "ASC" + "id": 2036, + "field_id": 8992, + "type": "link_row_has", + "value": "2", + "group": null } ], - "group_bys": [ + "filter_groups": [], + "sortings": [], + "decorations": [ { - "id": 1885, - "field_id": 1859586, - "order": "ASC" + "id": 779, + "type": "left_border_color", + "value_provider_type": "single_select_color", + "value_provider_conf": { + "field_id": 8985 + }, + "order": 1 + }, + { + "id": 780, + "type": "background_color", + "value_provider_type": "conditional_color", + "value_provider_conf": { + "colors": [ + { + "id": "c226a089-94a6-45bc-b0dc-d2432b5431af", + "color": "light-red", + "filters": [ + { + "id": "ad20bf58-8a50-48ec-bd01-89ce6d78413c", + "type": "not_empty", + "field": 9039, + "group": null, + "value": "" + } + ], + "operator": "AND" + }, + { + "id": "3530295a-3bd6-41fb-9093-5b107ed29525", + "color": "light-blue", + "filters": [ + { + "id": "ce960a3b-4bf1-4475-bcd9-ff4846b605f3", + "type": "not_empty", + "field": 9035, + "group": null, + "value": "" + } + ], + "operator": "AND" + }, + { + "id": "a58985b1-e1ec-4c2c-82df-c7e30d6c3333", + "color": "light-yellow", + "filters": [ + { + "id": "83899b5b-edab-478e-82e7-41945c9b1f5f", + "type": "not_empty", + "field": 9056, + "group": null, + "value": "" + } + ], + "operator": "AND" + }, + { + "id": "bc03b3e6-9d32-471a-b0cb-0bb65875a324", + "color": "light-pink", + "filters": [ + { + "id": "fcbb2789-c56e-41c0-90e0-21a73c66f33b", + "type": "not_empty", + "field": 9043, + "group": null, + "value": "" + } + ], + "operator": "AND" + } + ] + }, + "order": 2 } ], - "decorations": [], "public": false, - "row_identifier_type": "id", + "date_field_id": 8988, "field_options": [ { - "id": 3032834, - "field_id": 1859526, - "width": 161, + "id": 1397, + "field_id": 8983, "hidden": false, - "order": 0, - "aggregation_type": "", - "aggregation_raw_type": "" + "order": 32767 }, { - "id": 3032835, - "field_id": 1859519, - "width": 137, - "hidden": false, - "order": 1, - "aggregation_type": "", - "aggregation_raw_type": "" + "id": 1398, + "field_id": 8984, + "hidden": true, + "order": 32767 }, { - "id": 3032836, - "field_id": 1859528, - "width": 118, - "hidden": false, - "order": 2, - "aggregation_type": "sum", - "aggregation_raw_type": "sum" + "id": 1399, + "field_id": 8985, + "hidden": true, + "order": 32767 }, { - "id": 3032837, - "field_id": 1859524, - "width": 110, - "hidden": false, - "order": 3, - "aggregation_type": "min_date", - "aggregation_raw_type": "min" + "id": 1400, + "field_id": 8986, + "hidden": true, + "order": 32767 }, { - "id": 3032838, - "field_id": 1859525, - "width": 129, - "hidden": false, - "order": 4, - "aggregation_type": "max_date", - "aggregation_raw_type": "max" + "id": 1401, + "field_id": 8987, + "hidden": true, + "order": 32767 }, { - "id": 3032839, - "field_id": 1859556, - "width": 126, - "hidden": false, - "order": 5, - "aggregation_type": "", - "aggregation_raw_type": "" + "id": 1402, + "field_id": 8988, + "hidden": true, + "order": 32767 }, { - "id": 3032840, - "field_id": 1859521, - "width": 165, - "hidden": false, - "order": 6, - "aggregation_type": "", - "aggregation_raw_type": "" + "id": 1403, + "field_id": 8989, + "hidden": true, + "order": 32767 }, { - "id": 3032850, - "field_id": 1859586, - "width": 168, + "id": 1404, + "field_id": 8990, "hidden": true, - "order": 7, - "aggregation_type": "", - "aggregation_raw_type": "" + "order": 32767 }, { - "id": 3032841, - "field_id": 1859557, - "width": 168, - "hidden": false, - "order": 8, - "aggregation_type": "", - "aggregation_raw_type": "" + "id": 1405, + "field_id": 8991, + "hidden": true, + "order": 32767 }, { - "id": 3032842, - "field_id": 1859522, - "width": 146, - "hidden": false, - "order": 9, - "aggregation_type": "", - "aggregation_raw_type": "" + "id": 1406, + "field_id": 8992, + "hidden": true, + "order": 32767 }, { - "id": 3032843, - "field_id": 1859523, - "width": 149, - "hidden": false, - "order": 10, - "aggregation_type": "", - "aggregation_raw_type": "" + "id": 1407, + "field_id": 8993, + "hidden": true, + "order": 32767 }, { - "id": 3032844, - "field_id": 1859518, - "width": 292, - "hidden": false, - "order": 11, - "aggregation_type": "", - "aggregation_raw_type": "" + "id": 1408, + "field_id": 8994, + "hidden": true, + "order": 32767 }, { - "id": 3032845, - "field_id": 1859527, - "width": 200, - "hidden": false, - "order": 12, - "aggregation_type": "", - "aggregation_raw_type": "" + "id": 1409, + "field_id": 8995, + "hidden": true, + "order": 32767 }, { - "id": 3032846, - "field_id": 1859572, - "width": 158, - "hidden": false, - "order": 13, - "aggregation_type": "", - "aggregation_raw_type": "" + "id": 1410, + "field_id": 8996, + "hidden": true, + "order": 32767 }, { - "id": 3032847, - "field_id": 1859573, - "width": 178, - "hidden": false, - "order": 14, - "aggregation_type": "", - "aggregation_raw_type": "" + "id": 1420, + "field_id": 8997, + "hidden": true, + "order": 32767 }, { - "id": 3032848, - "field_id": 1859574, - "width": 197, - "hidden": false, - "order": 15, - "aggregation_type": "", - "aggregation_raw_type": "" + "id": 1421, + "field_id": 8998, + "hidden": true, + "order": 32767 }, { - "id": 3032849, - "field_id": 1859575, - "width": 143, - "hidden": false, - "order": 16, - "aggregation_type": "", - "aggregation_raw_type": "" + "id": 1412, + "field_id": 9018, + "hidden": true, + "order": 32767 }, { - "id": 3033221, - "field_id": 1859644, - "width": 200, - "hidden": false, - "order": 32767, - "aggregation_type": "", - "aggregation_raw_type": "" + "id": 1419, + "field_id": 9019, + "hidden": true, + "order": 32767 + }, + { + "id": 1411, + "field_id": 9023, + "hidden": true, + "order": 32767 + }, + { + "id": 1422, + "field_id": 9026, + "hidden": true, + "order": 32767 + }, + { + "id": 1414, + "field_id": 9035, + "hidden": true, + "order": 32767 + }, + { + "id": 1413, + "field_id": 9039, + "hidden": true, + "order": 32767 + }, + { + "id": 1423, + "field_id": 9043, + "hidden": true, + "order": 32767 + }, + { + "id": 1415, + "field_id": 9044, + "hidden": true, + "order": 32767 + }, + { + "id": 1416, + "field_id": 9052, + "hidden": true, + "order": 32767 + }, + { + "id": 1417, + "field_id": 9056, + "hidden": true, + "order": 32767 + }, + { + "id": 1418, + "field_id": 9057, + "hidden": true, + "order": 32767 } ] }, { - "id": 437939, + "id": 4011, "type": "grid", - "name": "Completed projects", - "order": 3, + "name": "Grid: Spring Marketing Campaign", + "order": 17, "ownership_type": "collaborative", "owned_by": null, "filter_type": "AND", "filters_disabled": false, "filters": [ { - "id": 204906, - "field_id": 1859575, - "type": "boolean", - "value": "1", + "id": 2037, + "field_id": 8992, + "type": "link_row_has", + "value": "3", "group": null } ], "filter_groups": [], "sortings": [ { - "id": 162273, - "field_id": 1859525, + "id": 2629, + "field_id": 8988, "order": "ASC" } ], - "group_bys": [], - "decorations": [], + "group_bys": [ + { + "id": 435, + "field_id": 8991, + "order": "ASC" + } + ], + "decorations": [ + { + "id": 781, + "type": "background_color", + "value_provider_type": "conditional_color", + "value_provider_conf": { + "colors": [ + { + "id": "d2bdac34-1d74-4efc-81e6-14ea5dc4475d", + "color": "light-red", + "filters": [ + { + "id": "0cc5b17b-99e4-496a-b97a-efe2f6de1d8b", + "type": "not_empty", + "field": 9039, + "group": null, + "value": "" + } + ], + "operator": "AND" + }, + { + "id": "fec2674d-5285-4361-841b-b5d1f7e3462f", + "color": "light-blue", + "filters": [ + { + "id": "a43c6f11-8ee6-4144-9954-717bb38628b3", + "type": "not_empty", + "field": 9035, + "group": null, + "value": "" + } + ], + "operator": "AND" + }, + { + "id": "4eacf9ec-9d68-4e92-a289-b2cafa492358", + "color": "light-yellow", + "filters": [ + { + "id": "9c697050-dbc4-48f0-8bb3-a08283288080", + "type": "not_empty", + "field": 9056, + "group": null, + "value": "" + } + ], + "operator": "AND" + }, + { + "id": "c2332087-1e9a-4d0a-bcd5-f895776499af", + "color": "light-pink", + "filters": [ + { + "id": "3a671799-5b70-4305-8688-5c9cd882a1a5", + "type": "not_empty", + "field": 9043, + "group": null, + "value": "" + } + ], + "operator": "AND" + } + ] + }, + "order": 1 + } + ], "public": false, "row_identifier_type": "id", + "row_height_size": "small", "field_options": [ { - "id": 3032702, - "field_id": 1859521, - "width": 151, + "id": 33362, + "field_id": 8983, + "width": 200, "hidden": false, "order": 0, "aggregation_type": "", "aggregation_raw_type": "" }, { - "id": 3032700, - "field_id": 1859519, - "width": 117, + "id": 33363, + "field_id": 9057, + "width": 98, "hidden": false, "order": 1, "aggregation_type": "", "aggregation_raw_type": "" }, { - "id": 3032703, - "field_id": 1859522, - "width": 146, + "id": 33364, + "field_id": 9019, + "width": 200, + "hidden": false, + "order": 2, + "aggregation_type": "", + "aggregation_raw_type": "" + }, + { + "id": 33365, + "field_id": 8984, + "width": 200, "hidden": false, "order": 3, "aggregation_type": "", "aggregation_raw_type": "" }, { - "id": 3032704, - "field_id": 1859523, + "id": 33366, + "field_id": 8985, "width": 200, "hidden": false, "order": 4, @@ -758,44 +10172,44 @@ "aggregation_raw_type": "" }, { - "id": 3032705, - "field_id": 1859524, - "width": 134, + "id": 33367, + "field_id": 8986, + "width": 200, "hidden": false, "order": 5, "aggregation_type": "", "aggregation_raw_type": "" }, { - "id": 3032706, - "field_id": 1859525, - "width": 123, + "id": 33368, + "field_id": 8987, + "width": 200, "hidden": false, "order": 6, "aggregation_type": "", "aggregation_raw_type": "" }, { - "id": 3032709, - "field_id": 1859528, - "width": 114, + "id": 33369, + "field_id": 8988, + "width": 200, "hidden": false, "order": 7, "aggregation_type": "", "aggregation_raw_type": "" }, { - "id": 3032707, - "field_id": 1859526, - "width": 260, + "id": 33370, + "field_id": 8989, + "width": 200, "hidden": false, "order": 8, "aggregation_type": "", "aggregation_raw_type": "" }, { - "id": 3032699, - "field_id": 1859518, + "id": 33371, + "field_id": 8990, "width": 200, "hidden": false, "order": 9, @@ -803,814 +10217,848 @@ "aggregation_raw_type": "" }, { - "id": 3032708, - "field_id": 1859527, + "id": 33372, + "field_id": 8991, "width": 200, - "hidden": true, + "hidden": false, "order": 10, "aggregation_type": "", "aggregation_raw_type": "" }, { - "id": 3032792, - "field_id": 1859556, + "id": 33373, + "field_id": 8992, "width": 200, "hidden": false, - "order": 32767, + "order": 11, "aggregation_type": "", "aggregation_raw_type": "" }, { - "id": 3032793, - "field_id": 1859557, + "id": 33374, + "field_id": 8993, "width": 200, "hidden": false, - "order": 32767, + "order": 12, "aggregation_type": "", "aggregation_raw_type": "" }, { - "id": 3032794, - "field_id": 1859572, + "id": 33375, + "field_id": 8994, "width": 200, "hidden": false, - "order": 32767, + "order": 13, "aggregation_type": "", "aggregation_raw_type": "" }, { - "id": 3032795, - "field_id": 1859573, + "id": 33376, + "field_id": 8995, "width": 200, "hidden": false, - "order": 32767, + "order": 14, "aggregation_type": "", "aggregation_raw_type": "" }, { - "id": 3032796, - "field_id": 1859574, + "id": 33377, + "field_id": 8996, "width": 200, "hidden": false, - "order": 32767, - "aggregation_type": "", - "aggregation_raw_type": "" + "order": 15, + "aggregation_type": "sum", + "aggregation_raw_type": "sum" }, { - "id": 3032797, - "field_id": 1859575, + "id": 33378, + "field_id": 9023, "width": 200, "hidden": false, - "order": 32767, - "aggregation_type": "", - "aggregation_raw_type": "" - }, - { - "id": 3032862, - "field_id": 1859586, - "width": 200, - "hidden": true, - "order": 32767, + "order": 16, "aggregation_type": "", "aggregation_raw_type": "" }, { - "id": 3033222, - "field_id": 1859644, + "id": 33379, + "field_id": 9018, "width": 200, "hidden": false, - "order": 32767, - "aggregation_type": "", - "aggregation_raw_type": "" - } - ] - }, - { - "id": 437940, - "type": "grid", - "name": "Incomplete projects", - "order": 4, - "ownership_type": "collaborative", - "owned_by": null, - "filter_type": "AND", - "filters_disabled": false, - "filters": [ - { - "id": 204907, - "field_id": 1859575, - "type": "boolean", - "value": "", - "group": null - } - ], - "filter_groups": [], - "sortings": [ - { - "id": 162274, - "field_id": 1859525, - "order": "ASC" - } - ], - "group_bys": [], - "decorations": [], - "public": false, - "row_identifier_type": "id", - "field_options": [ - { - "id": 3032711, - "field_id": 1859519, - "width": 146, - "hidden": false, - "order": 0, - "aggregation_type": "", - "aggregation_raw_type": "" - }, - { - "id": 3032713, - "field_id": 1859521, - "width": 170, - "hidden": false, - "order": 1, - "aggregation_type": "", - "aggregation_raw_type": "" - }, - { - "id": 3032714, - "field_id": 1859522, - "width": 230, - "hidden": false, - "order": 2, - "aggregation_type": "", - "aggregation_raw_type": "" - }, - { - "id": 3032715, - "field_id": 1859523, - "width": 246, - "hidden": false, - "order": 3, - "aggregation_type": "", - "aggregation_raw_type": "" - }, - { - "id": 3032716, - "field_id": 1859524, - "width": 138, - "hidden": false, - "order": 4, - "aggregation_type": "", - "aggregation_raw_type": "" - }, - { - "id": 3032717, - "field_id": 1859525, - "width": 134, - "hidden": false, - "order": 5, - "aggregation_type": "", - "aggregation_raw_type": "" - }, - { - "id": 3032720, - "field_id": 1859528, - "width": 112, - "hidden": false, - "order": 6, + "order": 17, "aggregation_type": "", "aggregation_raw_type": "" }, { - "id": 3032718, - "field_id": 1859526, + "id": 33380, + "field_id": 9039, "width": 200, - "hidden": false, - "order": 7, - "aggregation_type": "", - "aggregation_raw_type": "" - }, - { - "id": 3032710, - "field_id": 1859518, - "width": 148, - "hidden": false, - "order": 8, + "hidden": true, + "order": 18, "aggregation_type": "", "aggregation_raw_type": "" }, { - "id": 3032719, - "field_id": 1859527, + "id": 33381, + "field_id": 9035, "width": 200, "hidden": true, - "order": 10, + "order": 19, "aggregation_type": "", "aggregation_raw_type": "" }, { - "id": 3032798, - "field_id": 1859556, + "id": 33382, + "field_id": 9044, "width": 200, "hidden": false, - "order": 32767, + "order": 20, "aggregation_type": "", "aggregation_raw_type": "" }, { - "id": 3032799, - "field_id": 1859557, + "id": 33383, + "field_id": 9052, "width": 200, "hidden": false, - "order": 32767, + "order": 21, "aggregation_type": "", "aggregation_raw_type": "" }, { - "id": 3032800, - "field_id": 1859572, + "id": 33384, + "field_id": 9056, "width": 200, - "hidden": false, - "order": 32767, + "hidden": true, + "order": 22, "aggregation_type": "", "aggregation_raw_type": "" }, { - "id": 3032801, - "field_id": 1859573, + "id": 33385, + "field_id": 8997, "width": 200, "hidden": false, - "order": 32767, + "order": 23, "aggregation_type": "", "aggregation_raw_type": "" }, { - "id": 3032802, - "field_id": 1859574, + "id": 33386, + "field_id": 8998, "width": 200, "hidden": false, - "order": 32767, + "order": 24, "aggregation_type": "", "aggregation_raw_type": "" }, { - "id": 3032803, - "field_id": 1859575, + "id": 33387, + "field_id": 9026, "width": 200, "hidden": false, - "order": 32767, + "order": 25, "aggregation_type": "", "aggregation_raw_type": "" }, { - "id": 3032866, - "field_id": 1859586, + "id": 33388, + "field_id": 9043, "width": 200, "hidden": true, - "order": 32767, - "aggregation_type": "", - "aggregation_raw_type": "" - }, - { - "id": 3033223, - "field_id": 1859644, - "width": 200, - "hidden": false, - "order": 32767, + "order": 26, "aggregation_type": "", "aggregation_raw_type": "" } ] }, { - "id": 437952, - "type": "grid", - "name": "Active projects", - "order": 5, + "id": 4012, + "type": "timeline", + "name": "Timeline: Spring Marketing Campaign", + "order": 18, "ownership_type": "collaborative", "owned_by": null, "filter_type": "AND", "filters_disabled": false, "filters": [ { - "id": 204908, - "field_id": 1859524, - "type": "date_is_before", - "value": "Europe/Brussels??today", + "id": 2038, + "field_id": 8992, + "type": "link_row_has", + "value": "3", "group": null - }, - { - "id": 204910, - "field_id": 1859575, - "type": "boolean", - "value": "", - "group": 1748 - }, - { - "id": 204911, - "field_id": 1859525, - "type": "date_is_after", - "value": "Europe/Brussels??today", - "group": 1748 } ], - "filter_groups": [ + "filter_groups": [], + "sortings": [], + "decorations": [ { - "id": 1748, - "filter_type": "OR", - "parent_group": null - } - ], - "sortings": [ + "id": 782, + "type": "left_border_color", + "value_provider_type": "single_select_color", + "value_provider_conf": { + "field_id": 8985 + }, + "order": 1 + }, { - "id": 162279, - "field_id": 1859525, - "order": "ASC" + "id": 783, + "type": "background_color", + "value_provider_type": "conditional_color", + "value_provider_conf": { + "colors": [ + { + "id": "35ce49f4-6745-4f3d-b4cd-6130c2435445", + "color": "light-red", + "filters": [ + { + "id": "f11195d1-19d6-4248-b91f-1a845f7ccfea", + "type": "not_empty", + "field": 9039, + "group": null, + "value": "" + } + ], + "operator": "AND" + }, + { + "id": "801e823d-32a6-4759-b485-e6f42988405b", + "color": "light-blue", + "filters": [ + { + "id": "eaa544d4-f22c-4188-81d8-e62df42814ff", + "type": "not_empty", + "field": 9035, + "group": null, + "value": "" + } + ], + "operator": "AND" + }, + { + "id": "241cca76-2a27-491c-8b88-8ef314714c4a", + "color": "light-orange", + "filters": [ + { + "id": "17dc5350-a667-443d-b229-8cf6f0730982", + "type": "not_empty", + "field": 9056, + "group": null, + "value": "" + } + ], + "operator": "AND" + }, + { + "id": "7fab65c7-e96f-4f33-9768-41ac98804e13", + "color": "light-pink", + "filters": [ + { + "id": "38c5929d-a8eb-4916-bbb8-3b5fb927c081", + "type": "not_empty", + "field": 9043, + "group": null, + "value": "" + } + ], + "operator": "AND" + } + ] + }, + "order": 2 } ], - "group_bys": [], - "decorations": [], "public": false, - "row_identifier_type": "id", + "start_date_field_id": 8988, + "end_date_field_id": 8989, "field_options": [ { - "id": 3032810, - "field_id": 1859521, - "width": 151, + "id": 787, + "field_id": 9057, "hidden": false, - "order": 0, - "aggregation_type": "", - "aggregation_raw_type": "" + "order": 1 }, { - "id": 3032811, - "field_id": 1859519, - "width": 117, + "id": 788, + "field_id": 8983, "hidden": false, - "order": 1, - "aggregation_type": "", - "aggregation_raw_type": "" + "order": 2 }, { - "id": 3032812, - "field_id": 1859522, - "width": 146, - "hidden": false, - "order": 3, - "aggregation_type": "", - "aggregation_raw_type": "" + "id": 789, + "field_id": 8984, + "hidden": true, + "order": 3 }, { - "id": 3032813, - "field_id": 1859523, - "width": 200, - "hidden": false, - "order": 4, - "aggregation_type": "", - "aggregation_raw_type": "" + "id": 790, + "field_id": 8985, + "hidden": true, + "order": 4 }, { - "id": 3032814, - "field_id": 1859524, - "width": 134, - "hidden": false, - "order": 5, - "aggregation_type": "", - "aggregation_raw_type": "" + "id": 791, + "field_id": 8986, + "hidden": true, + "order": 5 + }, + { + "id": 792, + "field_id": 8987, + "hidden": true, + "order": 6 + }, + { + "id": 793, + "field_id": 8988, + "hidden": true, + "order": 7 + }, + { + "id": 794, + "field_id": 8989, + "hidden": true, + "order": 8 + }, + { + "id": 795, + "field_id": 8990, + "hidden": true, + "order": 9 + }, + { + "id": 796, + "field_id": 8991, + "hidden": true, + "order": 10 + }, + { + "id": 797, + "field_id": 8992, + "hidden": true, + "order": 11 + }, + { + "id": 798, + "field_id": 8993, + "hidden": true, + "order": 12 + }, + { + "id": 799, + "field_id": 8994, + "hidden": true, + "order": 13 + }, + { + "id": 800, + "field_id": 8995, + "hidden": true, + "order": 14 }, { - "id": 3032815, - "field_id": 1859525, - "width": 123, - "hidden": false, - "order": 6, - "aggregation_type": "", - "aggregation_raw_type": "" + "id": 801, + "field_id": 8996, + "hidden": true, + "order": 15 }, { - "id": 3032816, - "field_id": 1859528, - "width": 114, - "hidden": false, - "order": 7, - "aggregation_type": "", - "aggregation_raw_type": "" + "id": 802, + "field_id": 9023, + "hidden": true, + "order": 16 }, { - "id": 3032817, - "field_id": 1859526, - "width": 260, - "hidden": false, - "order": 8, - "aggregation_type": "", - "aggregation_raw_type": "" + "id": 803, + "field_id": 9018, + "hidden": true, + "order": 17 }, { - "id": 3032818, - "field_id": 1859518, - "width": 200, - "hidden": false, - "order": 9, - "aggregation_type": "", - "aggregation_raw_type": "" + "id": 804, + "field_id": 9039, + "hidden": true, + "order": 18 }, { - "id": 3032819, - "field_id": 1859527, - "width": 200, + "id": 805, + "field_id": 9035, "hidden": true, - "order": 10, - "aggregation_type": "", - "aggregation_raw_type": "" + "order": 19 }, { - "id": 3032820, - "field_id": 1859556, - "width": 200, - "hidden": false, - "order": 32767, - "aggregation_type": "", - "aggregation_raw_type": "" + "id": 806, + "field_id": 9044, + "hidden": true, + "order": 20 }, { - "id": 3032821, - "field_id": 1859557, - "width": 200, - "hidden": false, - "order": 32767, - "aggregation_type": "", - "aggregation_raw_type": "" + "id": 807, + "field_id": 9052, + "hidden": true, + "order": 21 }, { - "id": 3032822, - "field_id": 1859572, - "width": 200, - "hidden": false, - "order": 32767, - "aggregation_type": "", - "aggregation_raw_type": "" + "id": 808, + "field_id": 9056, + "hidden": true, + "order": 22 }, { - "id": 3032823, - "field_id": 1859573, - "width": 200, - "hidden": false, - "order": 32767, - "aggregation_type": "", - "aggregation_raw_type": "" + "id": 810, + "field_id": 8997, + "hidden": true, + "order": 32767 }, { - "id": 3032824, - "field_id": 1859574, - "width": 200, - "hidden": false, - "order": 32767, - "aggregation_type": "", - "aggregation_raw_type": "" + "id": 811, + "field_id": 8998, + "hidden": true, + "order": 32767 }, { - "id": 3032825, - "field_id": 1859575, - "width": 200, - "hidden": false, - "order": 32767, - "aggregation_type": "", - "aggregation_raw_type": "" + "id": 809, + "field_id": 9019, + "hidden": true, + "order": 32767 }, { - "id": 3032867, - "field_id": 1859586, - "width": 200, + "id": 812, + "field_id": 9026, "hidden": true, - "order": 32767, - "aggregation_type": "", - "aggregation_raw_type": "" + "order": 32767 }, { - "id": 3033225, - "field_id": 1859644, - "width": 200, - "hidden": false, - "order": 32767, - "aggregation_type": "", - "aggregation_raw_type": "" + "id": 813, + "field_id": 9043, + "hidden": true, + "order": 32767 } ] }, { - "id": 437941, - "type": "grid", - "name": "High budget", - "order": 6, + "id": 4013, + "type": "kanban", + "name": "Kanban: Spring Marketing Campaign", + "order": 19, "ownership_type": "collaborative", "owned_by": null, "filter_type": "AND", "filters_disabled": false, "filters": [ { - "id": 204901, - "field_id": 1859528, - "type": "higher_than", - "value": "10000", + "id": 2039, + "field_id": 8992, + "type": "link_row_has", + "value": "2", "group": null } ], "filter_groups": [], "sortings": [ { - "id": 162275, - "field_id": 1859528, - "order": "DESC" + "id": 2630, + "field_id": 8988, + "order": "ASC" } ], - "group_bys": [], "decorations": [], - "public": false, - "row_identifier_type": "id", + "public": true, + "single_select_field_id": 8985, "field_options": [ { - "id": 3032722, - "field_id": 1859519, - "width": 123, + "id": 4761, + "field_id": 9057, "hidden": false, - "order": 0, - "aggregation_type": "", - "aggregation_raw_type": "" + "order": 1 }, { - "id": 3032724, - "field_id": 1859521, - "width": 170, + "id": 4762, + "field_id": 8983, "hidden": false, - "order": 1, - "aggregation_type": "", - "aggregation_raw_type": "" + "order": 2 }, { - "id": 3032725, - "field_id": 1859522, - "width": 226, + "id": 4763, + "field_id": 8984, "hidden": false, - "order": 2, - "aggregation_type": "", - "aggregation_raw_type": "" + "order": 3 }, { - "id": 3032726, - "field_id": 1859523, - "width": 200, + "id": 4764, + "field_id": 8985, "hidden": false, - "order": 3, - "aggregation_type": "", - "aggregation_raw_type": "" + "order": 4 }, { - "id": 3032730, - "field_id": 1859527, - "width": 200, + "id": 4765, + "field_id": 8986, "hidden": false, - "order": 4, - "aggregation_type": "", - "aggregation_raw_type": "" + "order": 5 }, { - "id": 3032727, - "field_id": 1859524, - "width": 137, + "id": 4766, + "field_id": 8987, "hidden": false, - "order": 5, - "aggregation_type": "", - "aggregation_raw_type": "" + "order": 6 }, { - "id": 3032728, - "field_id": 1859525, - "width": 122, + "id": 4767, + "field_id": 8988, "hidden": false, - "order": 6, - "aggregation_type": "", - "aggregation_raw_type": "" + "order": 7 }, { - "id": 3032731, - "field_id": 1859528, - "width": 117, + "id": 4768, + "field_id": 8989, "hidden": false, - "order": 7, - "aggregation_type": "", - "aggregation_raw_type": "" + "order": 8 }, { - "id": 3032729, - "field_id": 1859526, - "width": 200, + "id": 4769, + "field_id": 8990, "hidden": false, - "order": 9, - "aggregation_type": "", - "aggregation_raw_type": "" + "order": 9 }, { - "id": 3032721, - "field_id": 1859518, - "width": 144, + "id": 4770, + "field_id": 8991, "hidden": false, - "order": 10, - "aggregation_type": "", - "aggregation_raw_type": "" + "order": 10 }, { - "id": 3032804, - "field_id": 1859556, - "width": 200, + "id": 4771, + "field_id": 8992, "hidden": false, - "order": 32767, - "aggregation_type": "", - "aggregation_raw_type": "" + "order": 11 }, { - "id": 3032805, - "field_id": 1859557, - "width": 200, + "id": 4772, + "field_id": 8993, "hidden": false, - "order": 32767, - "aggregation_type": "", - "aggregation_raw_type": "" + "order": 12 }, { - "id": 3032806, - "field_id": 1859572, - "width": 200, + "id": 4773, + "field_id": 8994, "hidden": false, - "order": 32767, - "aggregation_type": "", - "aggregation_raw_type": "" + "order": 13 }, { - "id": 3032807, - "field_id": 1859573, - "width": 200, + "id": 4774, + "field_id": 8995, "hidden": false, - "order": 32767, - "aggregation_type": "", - "aggregation_raw_type": "" + "order": 14 }, { - "id": 3032808, - "field_id": 1859574, - "width": 200, + "id": 4775, + "field_id": 8996, "hidden": false, - "order": 32767, - "aggregation_type": "", - "aggregation_raw_type": "" + "order": 15 }, { - "id": 3032809, - "field_id": 1859575, - "width": 200, + "id": 4776, + "field_id": 9023, "hidden": false, - "order": 32767, - "aggregation_type": "", - "aggregation_raw_type": "" + "order": 16 }, { - "id": 3032868, - "field_id": 1859586, - "width": 200, + "id": 4777, + "field_id": 9018, + "hidden": false, + "order": 17 + }, + { + "id": 4778, + "field_id": 9039, "hidden": true, - "order": 32767, - "aggregation_type": "", - "aggregation_raw_type": "" + "order": 18 }, { - "id": 3033224, - "field_id": 1859644, - "width": 200, + "id": 4779, + "field_id": 9035, + "hidden": true, + "order": 19 + }, + { + "id": 4780, + "field_id": 9044, "hidden": false, - "order": 32767, - "aggregation_type": "", - "aggregation_raw_type": "" + "order": 20 + }, + { + "id": 4781, + "field_id": 9052, + "hidden": false, + "order": 21 + }, + { + "id": 4782, + "field_id": 9056, + "hidden": true, + "order": 22 } ] }, { - "id": 437942, - "type": "kanban", - "name": "By category", - "order": 7, + "id": 4014, + "type": "calendar", + "name": "Calendar: Spring Marketing Campaign", + "order": 20, "ownership_type": "collaborative", "owned_by": null, "filter_type": "AND", "filters_disabled": false, - "filters": [], + "filters": [ + { + "id": 2040, + "field_id": 8992, + "type": "link_row_has", + "value": "3", + "group": null + } + ], "filter_groups": [], "sortings": [], - "decorations": [], + "decorations": [ + { + "id": 784, + "type": "left_border_color", + "value_provider_type": "single_select_color", + "value_provider_conf": { + "field_id": 8985 + }, + "order": 1 + }, + { + "id": 785, + "type": "background_color", + "value_provider_type": "conditional_color", + "value_provider_conf": { + "colors": [ + { + "id": "c226a089-94a6-45bc-b0dc-d2432b5431af", + "color": "light-red", + "filters": [ + { + "id": "ad20bf58-8a50-48ec-bd01-89ce6d78413c", + "type": "not_empty", + "field": 9039, + "group": null, + "value": "" + } + ], + "operator": "AND" + }, + { + "id": "3530295a-3bd6-41fb-9093-5b107ed29525", + "color": "light-blue", + "filters": [ + { + "id": "ce960a3b-4bf1-4475-bcd9-ff4846b605f3", + "type": "not_empty", + "field": 9035, + "group": null, + "value": "" + } + ], + "operator": "AND" + }, + { + "id": "a58985b1-e1ec-4c2c-82df-c7e30d6c3333", + "color": "light-yellow", + "filters": [ + { + "id": "7b47ce59-5b4f-4a8c-ba5d-b6266f5a45a5", + "type": "not_empty", + "field": 9056, + "group": null, + "value": "" + } + ], + "operator": "AND" + }, + { + "id": "6b92d936-9c0c-479d-9a14-e9edc7f7bfcb", + "color": "light-pink", + "filters": [ + { + "id": "f73265b3-ee1f-4580-b6ab-30e3dc088fec", + "type": "not_empty", + "field": 9043, + "group": null, + "value": "" + } + ], + "operator": "AND" + } + ] + }, + "order": 2 + } + ], "public": false, - "single_select_field_id": 1859519, + "date_field_id": 8988, "field_options": [ { - "id": 208806, - "field_id": 1859518, - "hidden": false, + "id": 1424, + "field_id": 8983, + "hidden": false, + "order": 32767 + }, + { + "id": 1425, + "field_id": 8984, + "hidden": true, + "order": 32767 + }, + { + "id": 1426, + "field_id": 8985, + "hidden": true, + "order": 32767 + }, + { + "id": 1427, + "field_id": 8986, + "hidden": true, + "order": 32767 + }, + { + "id": 1428, + "field_id": 8987, + "hidden": true, + "order": 32767 + }, + { + "id": 1429, + "field_id": 8988, + "hidden": true, + "order": 32767 + }, + { + "id": 1430, + "field_id": 8989, + "hidden": true, + "order": 32767 + }, + { + "id": 1431, + "field_id": 8990, + "hidden": true, "order": 32767 }, { - "id": 208807, - "field_id": 1859519, - "hidden": false, + "id": 1432, + "field_id": 8991, + "hidden": true, "order": 32767 }, { - "id": 208809, - "field_id": 1859521, - "hidden": false, + "id": 1433, + "field_id": 8992, + "hidden": true, "order": 32767 }, { - "id": 208810, - "field_id": 1859522, - "hidden": false, + "id": 1434, + "field_id": 8993, + "hidden": true, "order": 32767 }, { - "id": 208811, - "field_id": 1859523, - "hidden": false, + "id": 1435, + "field_id": 8994, + "hidden": true, "order": 32767 }, { - "id": 208812, - "field_id": 1859524, - "hidden": false, + "id": 1436, + "field_id": 8995, + "hidden": true, "order": 32767 }, { - "id": 208813, - "field_id": 1859525, - "hidden": false, + "id": 1437, + "field_id": 8996, + "hidden": true, + "order": 32767 + }, + { + "id": 1447, + "field_id": 8997, + "hidden": true, + "order": 32767 + }, + { + "id": 1448, + "field_id": 8998, + "hidden": true, "order": 32767 }, { - "id": 208814, - "field_id": 1859526, + "id": 1439, + "field_id": 9018, "hidden": true, "order": 32767 }, { - "id": 208815, - "field_id": 1859527, + "id": 1446, + "field_id": 9019, "hidden": true, "order": 32767 }, { - "id": 208816, - "field_id": 1859528, + "id": 1438, + "field_id": 9023, "hidden": true, "order": 32767 }, { - "id": 208817, - "field_id": 1859556, + "id": 1449, + "field_id": 9026, "hidden": true, "order": 32767 }, { - "id": 208818, - "field_id": 1859557, + "id": 1441, + "field_id": 9035, "hidden": true, "order": 32767 }, { - "id": 208819, - "field_id": 1859572, + "id": 1440, + "field_id": 9039, "hidden": true, "order": 32767 }, { - "id": 208820, - "field_id": 1859573, + "id": 1450, + "field_id": 9043, "hidden": true, "order": 32767 }, { - "id": 208821, - "field_id": 1859574, + "id": 1442, + "field_id": 9044, "hidden": true, "order": 32767 }, { - "id": 208822, - "field_id": 1859575, + "id": 1443, + "field_id": 9052, "hidden": true, "order": 32767 }, { - "id": 208865, - "field_id": 1859586, + "id": 1444, + "field_id": 9056, "hidden": true, "order": 32767 }, { - "id": 208866, - "field_id": 1859644, + "id": 1445, + "field_id": 9057, "hidden": true, "order": 32767 } @@ -1619,263 +11067,1702 @@ ], "rows": [ { - "id": 3, - "order": "1.00000000000000000000", - "created_on": "2021-07-26T16:54:03.031240+00:00", - "updated_on": "2024-02-29T07:37:10.154379+00:00", + "id": 1, + "order": "1.00000000000000000000", + "created_on": "2026-01-14T07:27:14.883004+00:00", + "updated_on": "2026-04-01T11:11:09.784930+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8983": "Define CRM entities", + "field_8984": "List customers, deals, activities", + "field_8985": 3610, + "field_8986": 3612, + "field_8987": [ + 2 + ], + "field_8988": "2026-02-04", + "field_8989": "2026-02-08", + "field_8990": "2026-01-19", + "field_8991": [ + 1 + ], + "field_8992": [ + 1 + ], + "field_8993": [], + "field_8994": [ + 1, + 2, + 3, + 4 + ], + "field_9044": null, + "field_8995": 432000.0, + "field_9023": null, + "field_9018": null, + "field_9035": null, + "field_9039": null, + "field_8996": "6", + "field_9052": null, + "field_9056": null, + "field_9057": null, + "field_9019": null, + "field_8997": "2000", + "field_8998": "1800", + "field_9026": null, + "field_9043": null + }, + { + "id": 2, + "order": "2.00000000000000000000", + "created_on": "2026-01-14T07:27:14.883038+00:00", + "updated_on": "2026-04-01T12:26:24.198185+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8983": "Design CRM relationships", + "field_8984": "Link customers to orders and tickets", + "field_8985": 3608, + "field_8986": 3612, + "field_8987": [ + 2 + ], + "field_8988": "2026-02-04", + "field_8989": "2026-02-08", + "field_8990": null, + "field_8991": [ + 1 + ], + "field_8992": [ + 1 + ], + "field_8993": [], + "field_8994": [ + 5, + 6, + 7, + 8 + ], + "field_9044": null, + "field_8995": 432000.0, + "field_9023": null, + "field_9018": null, + "field_9035": null, + "field_9039": null, + "field_8996": "6", + "field_9052": null, + "field_9056": null, + "field_9057": null, + "field_9019": null, + "field_8997": "2500", + "field_8998": null, + "field_9026": null, + "field_9043": null + }, + { + "id": 3, + "order": "3.00000000000000000000", + "created_on": "2026-01-14T07:27:14.883052+00:00", + "updated_on": "2026-04-01T12:26:25.108740+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8983": "Approve data model", + "field_8984": "Business sign-off of CRM schema", + "field_8985": 3608, + "field_8986": 3613, + "field_8987": [ + 2 + ], + "field_8988": "2026-02-12", + "field_8989": "2026-02-17", + "field_8990": null, + "field_8991": [ + 1 + ], + "field_8992": [ + 1 + ], + "field_8993": [ + 1, + 2 + ], + "field_8994": [ + 9, + 10, + 11, + 12 + ], + "field_9044": null, + "field_8995": 518400.0, + "field_9023": null, + "field_9018": null, + "field_9035": null, + "field_9039": null, + "field_8996": "4", + "field_9052": null, + "field_9056": null, + "field_9057": null, + "field_9019": null, + "field_8997": "1000", + "field_8998": null, + "field_9026": null, + "field_9043": null + }, + { + "id": 4, + "order": "4.00000000000000000000", + "created_on": "2026-01-14T07:27:14.883066+00:00", + "updated_on": "2026-04-01T11:11:09.785338+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8983": "Build customer module", + "field_8984": "Implement customer tables and UI", + "field_8985": 3609, + "field_8986": 3612, + "field_8987": [ + 14 + ], + "field_8988": "2026-02-18", + "field_8989": "2026-03-03", + "field_8990": null, + "field_8991": [ + 2 + ], + "field_8992": [ + 1 + ], + "field_8993": [ + 3 + ], + "field_8994": [], + "field_9044": null, + "field_8995": 1209600.0, + "field_9023": null, + "field_9018": null, + "field_9035": null, + "field_9039": null, + "field_8996": "10", + "field_9052": null, + "field_9056": null, + "field_9057": null, + "field_9019": null, + "field_8997": "8000", + "field_8998": "8500", + "field_9026": null, + "field_9043": null + }, + { + "id": 5, + "order": "5.00000000000000000000", + "created_on": "2026-01-14T07:27:14.883079+00:00", + "updated_on": "2026-04-01T12:26:18.828264+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8983": "Build sales pipeline", + "field_8984": "Create deals and stages", + "field_8985": 3609, + "field_8986": 3612, + "field_8987": [ + 14 + ], + "field_8988": "2026-03-04", + "field_8989": "2026-03-20", + "field_8990": null, + "field_8991": [ + 2 + ], + "field_8992": [ + 1 + ], + "field_8993": [ + 4 + ], + "field_8994": [], + "field_9044": null, + "field_8995": 1468800.0, + "field_9023": null, + "field_9018": null, + "field_9035": null, + "field_9039": null, + "field_8996": "10", + "field_9052": null, + "field_9056": null, + "field_9057": null, + "field_9019": null, + "field_8997": "7000", + "field_8998": "6800", + "field_9026": null, + "field_9043": null + }, + { + "id": 6, + "order": "6.00000000000000000000", + "created_on": "2026-01-14T07:27:14.883092+00:00", + "updated_on": "2026-04-01T11:12:51.302936+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8983": "Import legacy CRM data", + "field_8984": "Migrate historical customer data", + "field_8985": 3608, + "field_8986": 3613, + "field_8987": [ + 17 + ], + "field_8988": "2026-02-14", + "field_8989": "2026-02-23", + "field_8990": null, + "field_8991": [ + 2 + ], + "field_8992": [ + 1 + ], + "field_8993": [], + "field_8994": [], + "field_9044": null, + "field_8995": 864000.0, + "field_9023": null, + "field_9018": null, + "field_9035": null, + "field_9039": null, + "field_8996": "8", + "field_9052": null, + "field_9056": null, + "field_9057": null, + "field_9019": null, + "field_8997": "4000", + "field_8998": null, + "field_9026": null, + "field_9043": null + }, + { + "id": 7, + "order": "7.00000000000000000000", + "created_on": "2026-01-14T07:27:14.883104+00:00", + "updated_on": "2026-04-01T11:12:51.806310+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8983": "Design automation rules", + "field_8984": "Define triggers and workflows", + "field_8985": 3608, + "field_8986": 3612, + "field_8987": [ + 17 + ], + "field_8988": "2026-02-28", + "field_8989": "2026-03-10", + "field_8990": null, + "field_8991": [ + 3 + ], + "field_8992": [ + 1 + ], + "field_8993": [], + "field_8994": [], + "field_9044": null, + "field_8995": 950400.0, + "field_9023": null, + "field_9018": null, + "field_9035": null, + "field_9039": null, + "field_8996": "6", + "field_9052": null, + "field_9056": null, + "field_9057": null, + "field_9019": null, + "field_8997": "3000", + "field_8998": null, + "field_9026": null, + "field_9043": null + }, + { + "id": 8, + "order": "8.00000000000000000000", + "created_on": "2026-01-14T07:27:14.883117+00:00", + "updated_on": "2026-04-01T11:12:52.466756+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8983": "Implement workflows", + "field_8984": "Build automations in CRM", + "field_8985": 3608, + "field_8986": 3612, + "field_8987": [ + 14 + ], + "field_8988": "2026-03-11", + "field_8989": "2026-04-01", + "field_8990": null, + "field_8991": [ + 3 + ], + "field_8992": [ + 1 + ], + "field_8993": [ + 7 + ], + "field_8994": [], + "field_9044": null, + "field_8995": 1900800.0, + "field_9023": null, + "field_9018": null, + "field_9035": null, + "field_9039": null, + "field_8996": "12", + "field_9052": null, + "field_9056": null, + "field_9057": null, + "field_9019": null, + "field_8997": "9000", + "field_8998": null, + "field_9026": null, + "field_9043": null + }, + { + "id": 9, + "order": "9.00000000000000000000", + "created_on": "2026-01-14T07:27:14.883129+00:00", + "updated_on": "2026-04-01T11:13:07.842577+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8983": "Test automation", + "field_8984": "Validate automatic task creation", + "field_8985": 3608, + "field_8986": 3613, + "field_8987": [ + 17 + ], + "field_8988": "2026-04-02", + "field_8989": "2026-04-12", + "field_8990": null, + "field_8991": [ + 3 + ], + "field_8992": [ + 1 + ], + "field_8993": [ + 8 + ], + "field_8994": [], + "field_9044": null, + "field_8995": 950400.0, + "field_9023": null, + "field_9018": null, + "field_9035": null, + "field_9039": null, + "field_8996": "8", + "field_9052": null, + "field_9056": null, + "field_9057": null, + "field_9019": null, + "field_8997": "3500", + "field_8998": null, + "field_9026": null, + "field_9043": null + }, + { + "id": 10, + "order": "10.00000000000000000000", + "created_on": "2026-01-14T07:27:14.883142+00:00", + "updated_on": "2026-04-01T11:13:07.842754+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8983": "Prepare UAT scripts", + "field_8984": "Create business test scenarios", + "field_8985": 3608, + "field_8986": 3613, + "field_8987": [ + 14 + ], + "field_8988": "2026-04-05", + "field_8989": "2026-04-15", + "field_8990": "2026-01-16", + "field_8991": [ + 4 + ], + "field_8992": [ + 1 + ], + "field_8993": [], + "field_8994": [], + "field_9044": null, + "field_8995": 950400.0, + "field_9023": null, + "field_9018": null, + "field_9035": null, + "field_9039": null, + "field_8996": "6", + "field_9052": null, + "field_9056": null, + "field_9057": null, + "field_9019": null, + "field_8997": "2000", + "field_8998": null, + "field_9026": null, + "field_9043": null + }, + { + "id": 11, + "order": "11.00000000000000000000", + "created_on": "2026-01-14T07:27:14.883154+00:00", + "updated_on": "2026-04-01T11:13:07.842859+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8983": "Run UAT sessions", + "field_8984": "Users test the CRM", + "field_8985": 3608, + "field_8986": 3612, + "field_8987": [ + 14 + ], + "field_8988": "2026-04-16", + "field_8989": "2026-04-23", + "field_8990": null, + "field_8991": [ + 4 + ], + "field_8992": [ + 1 + ], + "field_8993": [ + 10 + ], + "field_8994": [], + "field_9044": null, + "field_8995": 691200.0, + "field_9023": null, + "field_9018": null, + "field_9035": null, + "field_9039": null, + "field_8996": "10", + "field_9052": null, + "field_9056": null, + "field_9057": null, + "field_9019": null, + "field_8997": "3000", + "field_8998": null, + "field_9026": null, + "field_9043": null + }, + { + "id": 12, + "order": "12.00000000000000000000", + "created_on": "2026-01-14T07:27:14.883167+00:00", + "updated_on": "2026-04-01T11:13:07.842967+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8983": "Fix UAT issues", + "field_8984": "Resolve reported defects", + "field_8985": 3608, + "field_8986": 3612, + "field_8987": [ + 17 + ], + "field_8988": "2026-04-24", + "field_8989": "2026-04-29", + "field_8990": null, + "field_8991": [ + 4 + ], + "field_8992": [ + 1 + ], + "field_8993": [ + 11 + ], + "field_8994": [], + "field_9044": null, + "field_8995": 518400.0, + "field_9023": null, + "field_9018": null, + "field_9035": null, + "field_9039": null, + "field_8996": "10", + "field_9052": null, + "field_9056": null, + "field_9057": null, + "field_9019": null, + "field_8997": "4500", + "field_8998": null, + "field_9026": null, + "field_9043": null + }, + { + "id": 13, + "order": "13.00000000000000000000", + "created_on": "2026-01-14T07:27:14.883179+00:00", + "updated_on": "2026-04-01T11:13:07.843063+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8983": "Prepare go-live checklist", + "field_8984": "Final readiness review", + "field_8985": 3608, + "field_8986": 3612, + "field_8987": [ + 17 + ], + "field_8988": "2026-05-05", + "field_8989": "2026-05-10", + "field_8990": null, + "field_8991": [ + 5 + ], + "field_8992": [ + 1 + ], + "field_8993": [], + "field_8994": [], + "field_9044": null, + "field_8995": 518400.0, + "field_9023": null, + "field_9018": null, + "field_9035": null, + "field_9039": null, + "field_8996": "6", + "field_9052": null, + "field_9056": null, + "field_9057": null, + "field_9019": null, + "field_8997": "1500", + "field_8998": null, + "field_9026": null, + "field_9043": null + }, + { + "id": 14, + "order": "14.00000000000000000000", + "created_on": "2026-01-14T07:27:14.883192+00:00", + "updated_on": "2026-04-01T11:11:09.786307+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8983": "Deploy CRM", + "field_8984": "Release system to production", + "field_8985": 3610, + "field_8986": 3611, + "field_8987": [ + 14 + ], + "field_8988": "2026-05-13", + "field_8989": "2026-05-16", + "field_8990": null, + "field_8991": [ + 5 + ], + "field_8992": [ + 1 + ], + "field_8993": [], + "field_8994": [], + "field_9044": null, + "field_8995": 345600.0, + "field_9023": null, + "field_9018": null, + "field_9035": null, + "field_9039": null, + "field_8996": "8", + "field_9052": null, + "field_9056": null, + "field_9057": null, + "field_9019": null, + "field_8997": "5000", + "field_8998": "5500", + "field_9026": null, + "field_9043": null + }, + { + "id": 15, + "order": "15.00000000000000000000", + "created_on": "2026-01-14T07:27:14.883204+00:00", + "updated_on": "2026-04-01T11:13:07.843171+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8983": "Train users", + "field_8984": "User onboarding sessions", + "field_8985": 3608, + "field_8986": 3613, + "field_8987": [ + 17 + ], + "field_8988": "2026-05-17", + "field_8989": "2026-05-28", + "field_8990": null, + "field_8991": [ + 5 + ], + "field_8992": [ + 1 + ], + "field_8993": [ + 14 + ], + "field_8994": [], + "field_9044": null, + "field_8995": 1036800.0, + "field_9023": null, + "field_9018": null, + "field_9035": null, + "field_9039": null, + "field_8996": "10", + "field_9052": null, + "field_9056": null, + "field_9057": null, + "field_9019": null, + "field_8997": "4000", + "field_8998": null, + "field_9026": null, + "field_9043": null + }, + { + "id": 16, + "order": "16.00000000000000000000", + "created_on": "2026-01-14T07:27:14.883217+00:00", + "updated_on": "2026-04-01T11:11:09.786490+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8983": "Interview system owners", + "field_8984": "Gather security info", + "field_8985": 3610, + "field_8986": 3612, + "field_8987": [ + 21 + ], + "field_8988": "2025-12-31", + "field_8989": "2026-01-07", + "field_8990": "2025-01-22", + "field_8991": [ + 6 + ], + "field_8992": [ + 2 + ], + "field_8993": [], + "field_8994": [], + "field_9044": null, + "field_8995": 691200.0, + "field_9023": null, + "field_9018": null, + "field_9035": null, + "field_9039": null, + "field_8996": "6", + "field_9052": null, + "field_9056": null, + "field_9057": null, + "field_9019": null, + "field_8997": "2500", + "field_8998": "2300", + "field_9026": null, + "field_9043": null + }, + { + "id": 17, + "order": "17.00000000000000000000", + "created_on": "2026-01-14T07:27:14.883230+00:00", + "updated_on": "2026-04-01T11:11:09.786583+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8983": "Document security risks", + "field_8984": "Register ISO risks", + "field_8985": 3610, + "field_8986": 3612, + "field_8987": [ + 12 + ], + "field_8988": "2026-01-05", + "field_8989": "2026-01-16", + "field_8990": "2025-01-30", + "field_8991": [ + 6 + ], + "field_8992": [ + 2 + ], + "field_8993": [], + "field_8994": [], + "field_9044": null, + "field_8995": 1036800.0, + "field_9023": null, + "field_9018": null, + "field_9035": null, + "field_9039": null, + "field_8996": "8", + "field_9052": null, + "field_9056": null, + "field_9057": null, + "field_9019": null, + "field_8997": "3000", + "field_8998": "3200", + "field_9026": null, + "field_9043": null + }, + { + "id": 18, + "order": "18.00000000000000000000", + "created_on": "2026-01-14T07:27:14.883242+00:00", + "updated_on": "2026-04-01T11:11:09.786675+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8983": "Approve risk register", + "field_8984": "Management sign-off", + "field_8985": 3610, + "field_8986": 3613, + "field_8987": [ + 1 + ], + "field_8988": "2026-01-17", + "field_8989": "2026-01-23", + "field_8990": "2025-01-31", + "field_8991": [ + 6 + ], + "field_8992": [ + 2 + ], + "field_8993": [ + 17 + ], + "field_8994": [], + "field_9044": null, + "field_8995": 604800.0, + "field_9023": null, + "field_9018": null, + "field_9035": null, + "field_9039": null, + "field_8996": "4", + "field_9052": null, + "field_9056": null, + "field_9057": null, + "field_9019": null, + "field_8997": "1200", + "field_8998": "1100", + "field_9026": null, + "field_9043": null + }, + { + "id": 19, + "order": "19.00000000000000000000", + "created_on": "2026-01-14T07:27:14.883254+00:00", + "updated_on": "2026-04-01T11:11:09.786786+00:00", + "created_by": "frederik@baserow.io", "last_modified_by": "frederik@baserow.io", - "field_1859518": "Brand Identity Development", - "field_1859519": 1386716, - "field_1859521": [ - 3 + "field_8983": "Define access controls", + "field_8984": "User and role model", + "field_8985": 3609, + "field_8986": 3612, + "field_8987": [ + 5 ], - "field_1859522": [ - 3 + "field_8988": "2026-01-17", + "field_8989": "2026-01-31", + "field_8990": null, + "field_8991": [ + 7 ], - "field_1859523": [ - 1, + "field_8992": [ 2 ], - "field_1859524": null, - "field_1859525": null, - "field_1859526": "Create a unique brand identity including logo", - "field_1859527": [ - 3, - 4, - 5, - 6, + "field_8993": [], + "field_8994": [], + "field_9044": null, + "field_8995": 1296000.0, + "field_9023": null, + "field_9018": null, + "field_9035": null, + "field_9039": null, + "field_8996": "8", + "field_9052": null, + "field_9056": null, + "field_9057": null, + "field_9019": null, + "field_8997": "3500", + "field_8998": "3700", + "field_9026": null, + "field_9043": null + }, + { + "id": 20, + "order": "20.00000000000000000000", + "created_on": "2026-01-14T07:27:14.883267+00:00", + "updated_on": "2026-04-01T11:11:09.786888+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8983": "Define incident response", + "field_8984": "Security incident handling", + "field_8985": 3610, + "field_8986": 3612, + "field_8987": [ + 5 + ], + "field_8988": "2026-01-21", + "field_8989": "2026-02-13", + "field_8990": null, + "field_8991": [ 7 ], - "field_1859528": "12000", - "field_1859556": [ - { - "name": "laSIxqOPuse7l2HFMm8RvXUCJgq7wSCA_e7fa567aac5fdffb5569ad7301a186889981b3f504d39250a6aebbce0ac452d6.pdf", - "visible_name": "contract.pdf", - "original_name": "laSIxqOPuse7l2HFMm8RvXUCJgq7wSCA_e7fa567aac5fdffb5569ad7301a186889981b3f504d39250a6aebbce0ac452d6.pdf" - } + "field_8992": [ + 2 ], - "field_1859557": null, - "field_1859572": null, - "field_1859573": null, - "field_1859574": null, - "field_1859575": null, - "field_1859586": null, - "field_1859644": null + "field_8993": [], + "field_8994": [], + "field_9044": null, + "field_8995": 2073600.0, + "field_9023": null, + "field_9018": null, + "field_9035": null, + "field_9039": null, + "field_8996": "8", + "field_9052": null, + "field_9056": null, + "field_9057": null, + "field_9019": null, + "field_8997": "2800", + "field_8998": "2600", + "field_9026": null, + "field_9043": null }, { - "id": 4, - "order": "2.00000000000000000000", - "created_on": "2021-07-26T16:54:03.031510+00:00", - "updated_on": "2024-02-29T07:37:03.805741+00:00", + "id": 21, + "order": "21.00000000000000000000", + "created_on": "2026-01-14T07:27:14.883279+00:00", + "updated_on": "2026-04-01T11:13:07.843267+00:00", + "created_by": "frederik@baserow.io", "last_modified_by": "frederik@baserow.io", - "field_1859518": "Market Entry Strategy Consulting", - "field_1859519": 1386718, - "field_1859521": [ - 4 + "field_8983": "Define backup policy", + "field_8984": "Data protection rules", + "field_8985": 3608, + "field_8986": 3613, + "field_8987": [ + 5 ], - "field_1859522": [ - 3 + "field_8988": "2026-01-26", + "field_8989": "2026-02-13", + "field_8990": null, + "field_8991": [ + 7 ], - "field_1859523": [ - 4 + "field_8992": [ + 2 ], - "field_1859524": null, - "field_1859525": null, - "field_1859526": "Provide strategic guidance for the client's entry into a new market or industry", - "field_1859527": [ - 23, - 24, - 25, - 26, - 27 + "field_8993": [], + "field_8994": [], + "field_9044": null, + "field_8995": 1641600.0, + "field_9023": null, + "field_9018": null, + "field_9035": null, + "field_9039": null, + "field_8996": "6", + "field_9052": null, + "field_9056": null, + "field_9057": null, + "field_9019": null, + "field_8997": "2000", + "field_8998": null, + "field_9026": null, + "field_9043": null + }, + { + "id": 22, + "order": "22.00000000000000000000", + "created_on": "2026-01-14T07:27:14.883291+00:00", + "updated_on": "2026-04-01T11:13:07.843361+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8983": "Implement MFA", + "field_8984": "Enable multi-factor authentication", + "field_8985": 3608, + "field_8986": 3612, + "field_8987": [ + 12 ], - "field_1859528": "1700", - "field_1859556": [ - { - "name": "laSIxqOPuse7l2HFMm8RvXUCJgq7wSCA_e7fa567aac5fdffb5569ad7301a186889981b3f504d39250a6aebbce0ac452d6.pdf", - "visible_name": "contract.pdf", - "original_name": "laSIxqOPuse7l2HFMm8RvXUCJgq7wSCA_e7fa567aac5fdffb5569ad7301a186889981b3f504d39250a6aebbce0ac452d6.pdf" - } + "field_8988": "2026-02-01", + "field_8989": "2026-02-27", + "field_8990": null, + "field_8991": [ + 8 + ], + "field_8992": [ + 2 + ], + "field_8993": [ + 19, + 20, + 21 ], - "field_1859557": null, - "field_1859572": null, - "field_1859573": null, - "field_1859574": null, - "field_1859575": null, - "field_1859586": null, - "field_1859644": null + "field_8994": [], + "field_9044": null, + "field_8995": 2332800.0, + "field_9023": null, + "field_9018": null, + "field_9035": null, + "field_9039": null, + "field_8996": "10", + "field_9052": null, + "field_9056": null, + "field_9057": null, + "field_9019": null, + "field_8997": "4500", + "field_8998": null, + "field_9026": null, + "field_9043": null }, { - "id": 5, - "order": "3.00000000000000000000", - "created_on": "2021-07-26T16:54:03.032070+00:00", - "updated_on": "2024-02-29T07:37:16.531359+00:00", + "id": 23, + "order": "23.00000000000000000000", + "created_on": "2026-01-14T07:27:14.883303+00:00", + "updated_on": "2026-04-01T11:13:07.843456+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8983": "Configure SIEM", + "field_8984": "Set up security monitoring", + "field_8985": 3608, + "field_8986": 3612, + "field_8987": [ + 12 + ], + "field_8988": "2026-02-01", + "field_8989": "2026-03-04", + "field_8990": null, + "field_8991": [ + 8 + ], + "field_8992": [ + 2 + ], + "field_8993": [ + 19, + 20, + 21 + ], + "field_8994": [], + "field_9044": null, + "field_8995": 2764800.0, + "field_9023": null, + "field_9018": null, + "field_9035": null, + "field_9039": null, + "field_8996": "12", + "field_9052": null, + "field_9056": null, + "field_9057": null, + "field_9019": null, + "field_8997": "8000", + "field_8998": null, + "field_9026": null, + "field_9043": null + }, + { + "id": 24, + "order": "24.00000000000000000000", + "created_on": "2026-01-14T07:27:14.883316+00:00", + "updated_on": "2026-04-01T11:13:07.843589+00:00", + "created_by": "frederik@baserow.io", "last_modified_by": "frederik@baserow.io", - "field_1859518": "Social Media Marketing Campaign", - "field_1859519": 1386717, - "field_1859521": [ + "field_8983": "Apply hardening baseline", + "field_8984": "Secure servers and apps", + "field_8985": 3608, + "field_8986": 3612, + "field_8987": [ 5 ], - "field_1859522": [ + "field_8988": "2026-02-01", + "field_8989": "2026-02-27", + "field_8990": null, + "field_8991": [ + 8 + ], + "field_8992": [ + 2 + ], + "field_8993": [ + 19, + 20, + 21 + ], + "field_8994": [], + "field_9044": null, + "field_8995": 2332800.0, + "field_9023": null, + "field_9018": null, + "field_9035": null, + "field_9039": null, + "field_8996": "10", + "field_9052": null, + "field_9056": null, + "field_9057": null, + "field_9019": null, + "field_8997": "5000", + "field_8998": null, + "field_9026": null, + "field_9043": null + }, + { + "id": 25, + "order": "25.00000000000000000000", + "created_on": "2026-01-14T07:27:14.883328+00:00", + "updated_on": "2026-04-01T11:13:07.843706+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8983": "Prepare audit evidence", + "field_8984": "Collect policies and logs", + "field_8985": 3608, + "field_8986": 3612, + "field_8987": [ + 21 + ], + "field_8988": "2026-04-16", + "field_8989": "2026-05-05", + "field_8990": null, + "field_8991": [ 6 ], - "field_1859523": [ - 1, - 5 + "field_8992": [ + 2 ], - "field_1859524": null, - "field_1859525": null, - "field_1859526": "Plan and execute a targeted social media campaign to increase brand visibility", - "field_1859527": [ - 8, - 9, - 10, - 11, - 12 + "field_8993": [], + "field_8994": [], + "field_9044": null, + "field_8995": 1728000.0, + "field_9023": null, + "field_9018": null, + "field_9035": null, + "field_9039": null, + "field_8996": "10", + "field_9052": null, + "field_9056": null, + "field_9057": null, + "field_9019": null, + "field_8997": "3000", + "field_8998": null, + "field_9026": null, + "field_9043": null + }, + { + "id": 26, + "order": "26.00000000000000000000", + "created_on": "2026-01-14T07:27:14.883340+00:00", + "updated_on": "2026-04-01T11:13:07.843800+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8983": "Run internal audit", + "field_8984": "Test ISO compliance", + "field_8985": 3608, + "field_8986": 3612, + "field_8987": [ + 1 ], - "field_1859528": "14000", - "field_1859556": [ - { - "name": "laSIxqOPuse7l2HFMm8RvXUCJgq7wSCA_e7fa567aac5fdffb5569ad7301a186889981b3f504d39250a6aebbce0ac452d6.pdf", - "visible_name": "contract.pdf", - "original_name": "laSIxqOPuse7l2HFMm8RvXUCJgq7wSCA_e7fa567aac5fdffb5569ad7301a186889981b3f504d39250a6aebbce0ac452d6.pdf" - } + "field_8988": "2026-05-06", + "field_8989": "2026-05-22", + "field_8990": null, + "field_8991": [ + 9 + ], + "field_8992": [ + 2 + ], + "field_8993": [ + 25 ], - "field_1859557": null, - "field_1859572": null, - "field_1859573": null, - "field_1859574": null, - "field_1859575": null, - "field_1859586": null, - "field_1859644": null + "field_8994": [], + "field_9044": null, + "field_8995": 1468800.0, + "field_9023": null, + "field_9018": null, + "field_9035": null, + "field_9039": null, + "field_8996": "12", + "field_9052": null, + "field_9056": null, + "field_9057": null, + "field_9019": null, + "field_8997": "4000", + "field_8998": null, + "field_9026": null, + "field_9043": null }, { - "id": 7, - "order": "5.00000000000000000000", - "created_on": "2021-07-26T16:54:03.032316+00:00", - "updated_on": "2024-02-29T08:25:06.991548+00:00", + "id": 27, + "order": "27.00000000000000000000", + "created_on": "2026-01-14T07:27:14.883352+00:00", + "updated_on": "2026-04-01T11:13:07.843894+00:00", + "created_by": "frederik@baserow.io", "last_modified_by": "frederik@baserow.io", - "field_1859518": "Digital Advertising Campaign Management", - "field_1859519": 1386718, - "field_1859521": [ - 7 + "field_8983": "Close audit findings", + "field_8984": "Fix non-compliances", + "field_8985": 3608, + "field_8986": 3612, + "field_8987": [ + 12 ], - "field_1859522": [], - "field_1859523": [ + "field_8988": "2026-05-23", + "field_8989": "2026-06-03", + "field_8990": null, + "field_8991": [ + 9 + ], + "field_8992": [ + 2 + ], + "field_8993": [ + 26 + ], + "field_8994": [], + "field_9044": null, + "field_8995": 1036800.0, + "field_9023": null, + "field_9018": null, + "field_9035": null, + "field_9039": null, + "field_8996": "10", + "field_9052": null, + "field_9056": null, + "field_9057": null, + "field_9019": null, + "field_8997": "3500", + "field_8998": null, + "field_9026": null, + "field_9043": null + }, + { + "id": 28, + "order": "28.00000000000000000000", + "created_on": "2026-01-14T07:27:14.883365+00:00", + "updated_on": "2026-04-01T11:13:07.843996+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8983": "Book certification auditor", + "field_8984": "Engage external auditor", + "field_8985": 3608, + "field_8986": 3613, + "field_8987": [ 1 ], - "field_1859524": null, - "field_1859525": null, - "field_1859526": "Manage and optimize digital advertising campaigns across various platforms", - "field_1859527": [ - 13, - 14, - 15, - 16, - 17 + "field_8988": "2026-05-17", + "field_8989": "2026-05-21", + "field_8990": null, + "field_8991": [ + 10 ], - "field_1859528": "1000", - "field_1859556": [ - { - "name": "laSIxqOPuse7l2HFMm8RvXUCJgq7wSCA_e7fa567aac5fdffb5569ad7301a186889981b3f504d39250a6aebbce0ac452d6.pdf", - "visible_name": "contract.pdf", - "original_name": "laSIxqOPuse7l2HFMm8RvXUCJgq7wSCA_e7fa567aac5fdffb5569ad7301a186889981b3f504d39250a6aebbce0ac452d6.pdf" - } + "field_8992": [ + 2 ], - "field_1859557": null, - "field_1859572": null, - "field_1859573": null, - "field_1859574": null, - "field_1859575": null, - "field_1859586": null, - "field_1859644": null + "field_8993": [], + "field_8994": [], + "field_9044": null, + "field_8995": 432000.0, + "field_9023": null, + "field_9018": null, + "field_9035": null, + "field_9039": null, + "field_8996": "4", + "field_9052": null, + "field_9056": null, + "field_9057": null, + "field_9019": null, + "field_8997": "6000", + "field_8998": null, + "field_9026": null, + "field_9043": null }, { - "id": 8, - "order": "6.00000000000000000000", - "created_on": "2021-07-26T16:54:03.032415+00:00", - "updated_on": "2024-02-29T08:03:09.146853+00:00", + "id": 29, + "order": "29.00000000000000000000", + "created_on": "2026-01-14T07:27:14.883377+00:00", + "updated_on": "2026-04-01T11:13:07.844088+00:00", + "created_by": "frederik@baserow.io", "last_modified_by": "frederik@baserow.io", - "field_1859518": "Branding Workshop Facilitation", - "field_1859519": 1386715, - "field_1859521": [ - 4 + "field_8983": "Support certification audit", + "field_8984": "Answer auditor questions", + "field_8985": 3608, + "field_8986": 3612, + "field_8987": [ + 21 ], - "field_1859522": [ - 6, + "field_8988": "2026-05-31", + "field_8989": "2026-06-15", + "field_8990": null, + "field_8991": [ + 10 + ], + "field_8992": [ + 2 + ], + "field_8993": [], + "field_8994": [], + "field_9044": null, + "field_8995": 1382400.0, + "field_9023": null, + "field_9018": null, + "field_9035": null, + "field_9039": null, + "field_8996": "12", + "field_9052": null, + "field_9056": null, + "field_9057": null, + "field_9019": null, + "field_8997": "7000", + "field_8998": null, + "field_9026": null, + "field_9043": null + }, + { + "id": 30, + "order": "30.00000000000000000000", + "created_on": "2026-01-14T07:27:14.883389+00:00", + "updated_on": "2026-04-01T11:13:07.844191+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8983": "Resolve audit findings", + "field_8984": "Close final issues", + "field_8985": 3608, + "field_8986": 3612, + "field_8987": [ 1 ], - "field_1859523": [ - 5, - 6 + "field_8988": "2026-05-22", + "field_8989": "2026-06-01", + "field_8990": null, + "field_8991": [ + 10 ], - "field_1859524": null, - "field_1859525": null, - "field_1859526": "Facilitate a workshop to help the client define their brand identity and positioning", - "field_1859527": [ - 18, - 19, - 20, - 21, - 22 + "field_8992": [ + 2 ], - "field_1859528": "23000", - "field_1859556": [ - { - "name": "laSIxqOPuse7l2HFMm8RvXUCJgq7wSCA_e7fa567aac5fdffb5569ad7301a186889981b3f504d39250a6aebbce0ac452d6.pdf", - "visible_name": "contract.pdf", - "original_name": "laSIxqOPuse7l2HFMm8RvXUCJgq7wSCA_e7fa567aac5fdffb5569ad7301a186889981b3f504d39250a6aebbce0ac452d6.pdf" - } + "field_8993": [ + 28, + 29 + ], + "field_8994": [], + "field_9044": null, + "field_8995": 950400.0, + "field_9023": null, + "field_9018": null, + "field_9035": null, + "field_9039": null, + "field_8996": "10", + "field_9052": null, + "field_9056": null, + "field_9057": null, + "field_9019": null, + "field_8997": "5000", + "field_8998": null, + "field_9026": null, + "field_9043": null + }, + { + "id": 31, + "order": "31.00000000000000000000", + "created_on": "2026-01-14T07:27:14.883402+00:00", + "updated_on": "2026-04-01T11:11:09.787941+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8983": "Define target audience", + "field_8984": "Identify customer segments", + "field_8985": 3609, + "field_8986": 3613, + "field_8987": [ + 11 + ], + "field_8988": "2026-02-14", + "field_8989": "2026-02-16", + "field_8990": "2025-03-03", + "field_8991": [ + 11 + ], + "field_8992": [ + 3 + ], + "field_8993": [], + "field_8994": [], + "field_9044": null, + "field_8995": 259200.0, + "field_9023": null, + "field_9018": null, + "field_9035": null, + "field_9039": null, + "field_8996": "4", + "field_9052": null, + "field_9056": null, + "field_9057": null, + "field_9019": null, + "field_8997": "2000", + "field_8998": "1800", + "field_9026": null, + "field_9043": null + }, + { + "id": 32, + "order": "32.00000000000000000000", + "created_on": "2026-01-14T07:27:14.883414+00:00", + "updated_on": "2026-04-01T11:11:09.788034+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8983": "Approve campaign budget", + "field_8984": "Finance sign-off", + "field_8985": 3609, + "field_8986": 3613, + "field_8987": [ + 3 + ], + "field_8988": "2026-02-15", + "field_8989": "2026-02-18", + "field_8990": "2025-03-05", + "field_8991": [ + 11 + ], + "field_8992": [ + 3 + ], + "field_8993": [], + "field_8994": [], + "field_9044": null, + "field_8995": 345600.0, + "field_9023": null, + "field_9018": null, + "field_9035": null, + "field_9039": null, + "field_8996": "4", + "field_9052": null, + "field_9056": null, + "field_9057": null, + "field_9019": null, + "field_8997": "1000", + "field_8998": "900", + "field_9026": null, + "field_9043": null + }, + { + "id": 33, + "order": "33.00000000000000000000", + "created_on": "2026-01-14T07:27:14.883427+00:00", + "updated_on": "2026-04-01T11:11:09.788126+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8983": "Design banners", + "field_8984": "Create visual assets", + "field_8985": 3609, + "field_8986": 3612, + "field_8987": [ + 13 + ], + "field_8988": "2026-02-17", + "field_8989": "2026-03-01", + "field_8990": null, + "field_8991": [ + 12 + ], + "field_8992": [ + 3 + ], + "field_8993": [ + 32, + 31 + ], + "field_8994": [], + "field_9044": null, + "field_8995": 1123200.0, + "field_9023": null, + "field_9018": null, + "field_9035": null, + "field_9039": null, + "field_8996": "8", + "field_9052": null, + "field_9056": null, + "field_9057": null, + "field_9019": null, + "field_8997": "3000", + "field_8998": "3200", + "field_9026": null, + "field_9043": null + }, + { + "id": 34, + "order": "34.00000000000000000000", + "created_on": "2026-01-14T07:27:14.883439+00:00", + "updated_on": "2026-04-01T11:11:09.788228+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8983": "Write ad copy", + "field_8984": "Marketing texts", + "field_8985": 3609, + "field_8986": 3612, + "field_8987": [ + 13 + ], + "field_8988": "2026-02-17", + "field_8989": "2026-03-01", + "field_8990": null, + "field_8991": [ + 12 + ], + "field_8992": [ + 3 + ], + "field_8993": [ + 31, + 32 + ], + "field_8994": [], + "field_9044": null, + "field_8995": 1123200.0, + "field_9023": null, + "field_9018": null, + "field_9035": null, + "field_9039": null, + "field_8996": "8", + "field_9052": null, + "field_9056": null, + "field_9057": null, + "field_9019": null, + "field_8997": "2500", + "field_8998": "2700", + "field_9026": null, + "field_9043": null + }, + { + "id": 35, + "order": "35.00000000000000000000", + "created_on": "2026-01-14T07:27:14.883456+00:00", + "updated_on": "2026-04-01T11:13:07.844285+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8983": "Launch ads", + "field_8984": "Activate digital channels", + "field_8985": 3608, + "field_8986": 3612, + "field_8987": [ + 13 + ], + "field_8988": "2026-03-02", + "field_8989": "2026-03-02", + "field_8990": null, + "field_8991": [ + 13 + ], + "field_8992": [ + 3 + ], + "field_8993": [ + 33, + 34 + ], + "field_8994": [], + "field_9044": null, + "field_8995": 86400.0, + "field_9023": null, + "field_9018": null, + "field_9035": null, + "field_9039": null, + "field_8996": "4", + "field_9052": null, + "field_9056": null, + "field_9057": null, + "field_9019": null, + "field_8997": "4000", + "field_8998": null, + "field_9026": null, + "field_9043": null + }, + { + "id": 36, + "order": "36.00000000000000000000", + "created_on": "2026-01-14T07:27:14.883479+00:00", + "updated_on": "2026-04-01T11:13:07.844377+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8983": "Publish landing page", + "field_8984": "Website live", + "field_8985": 3608, + "field_8986": 3612, + "field_8987": [ + 13 ], - "field_1859557": null, - "field_1859572": null, - "field_1859573": null, - "field_1859574": null, - "field_1859575": null, - "field_1859586": null, - "field_1859644": null + "field_8988": "2026-03-03", + "field_8989": "2026-03-10", + "field_8990": null, + "field_8991": [ + 13 + ], + "field_8992": [ + 3 + ], + "field_8993": [ + 35 + ], + "field_8994": [], + "field_9044": null, + "field_8995": 691200.0, + "field_9023": null, + "field_9018": null, + "field_9035": null, + "field_9039": null, + "field_8996": "6", + "field_9052": null, + "field_9056": null, + "field_9057": null, + "field_9019": null, + "field_8997": "3500", + "field_8998": null, + "field_9026": null, + "field_9043": null + }, + { + "id": 37, + "order": "37.00000000000000000000", + "created_on": "2026-01-14T07:27:14.883501+00:00", + "updated_on": "2026-04-01T11:13:07.844471+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8983": "Collect performance data", + "field_8984": "Gather KPI data", + "field_8985": 3608, + "field_8986": 3613, + "field_8987": [ + 11 + ], + "field_8988": "2026-03-11", + "field_8989": "2026-03-26", + "field_8990": null, + "field_8991": [ + 14 + ], + "field_8992": [ + 3 + ], + "field_8993": [ + 36 + ], + "field_8994": [], + "field_9044": null, + "field_8995": 1382400.0, + "field_9023": null, + "field_9018": null, + "field_9035": null, + "field_9039": null, + "field_8996": "6", + "field_9052": null, + "field_9056": null, + "field_9057": null, + "field_9019": null, + "field_8997": "2000", + "field_8998": null, + "field_9026": null, + "field_9043": null + }, + { + "id": 38, + "order": "38.00000000000000000000", + "created_on": "2026-01-14T07:27:14.883538+00:00", + "updated_on": "2026-04-01T11:11:09.788601+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8983": "Prepare campaign report", + "field_8984": "Analyze results", + "field_8985": 3609, + "field_8986": 3613, + "field_8987": [ + 3 + ], + "field_8988": "2026-03-27", + "field_8989": "2026-04-06", + "field_8990": null, + "field_8991": [ + 14 + ], + "field_8992": [ + 3 + ], + "field_8993": [ + 37 + ], + "field_8994": [], + "field_9044": null, + "field_8995": 950400.0, + "field_9023": null, + "field_9018": null, + "field_9035": null, + "field_9039": null, + "field_8996": "8", + "field_9052": null, + "field_9056": null, + "field_9057": null, + "field_9019": null, + "field_8997": "1500", + "field_8998": "1600", + "field_9026": null, + "field_9043": null + } + ], + "data_sync": null, + "field_rules": [ + { + "start_date_field_id": 8988, + "end_date_field_id": 8989, + "duration_field_id": 8995, + "dependency_linkrow_field_id": 8993, + "dependency_buffer": 0.0, + "dependency_buffer_type": "fixed", + "dependency_connection_type": "end-to-start", + "dependency_linkrow_role": "predecessors", + "include_weekends": true, + "id": 4, + "table_id": 957, + "type": "date_dependency", + "is_active": true, + "is_valid": true, + "error_text": null } ] }, { - "id": 261762, - "name": "Tasks", - "order": 3, + "id": 958, + "name": "Subtasks", + "order": 8, "fields": [ { - "id": 1859529, + "id": 8999, "type": "text", "name": "Name", - "order": 0, + "description": null, + "order": 2, "primary": true, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], "text_default": "" }, { - "id": 1859530, + "id": 9000, "type": "link_row", - "name": "Project", + "name": "Task", + "description": null, "order": 1, "primary": false, - "link_row_table_id": 261761, - "link_row_related_field_id": 1859527, - "has_related_field": true + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "link_row_table_id": 957, + "link_row_related_field_id": 8994, + "link_row_limit_selection_view_id": null, + "has_related_field": true, + "link_row_multiple_relationships": false }, { - "id": 1859532, - "type": "link_row", - "name": "Assignee", + "id": 9001, + "type": "date", + "name": "Start time", + "description": null, "order": 3, "primary": false, - "link_row_table_id": 261764, - "link_row_related_field_id": 1859544, - "has_related_field": true - }, - { - "id": 1859533, - "type": "created_on", - "name": "Created on", - "order": 4, - "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], "date_format": "ISO", "date_include_time": true, "date_time_format": "24", @@ -1883,418 +12770,203 @@ "date_force_timezone": null }, { - "id": 1859534, - "type": "long_text", - "name": "Description", - "order": 5, - "primary": false, - "long_text_enable_rich_text": false - }, - { - "id": 1859558, - "type": "single_select", - "name": "Status", - "order": 6, - "primary": false, - "select_options": [ - { - "id": 1386724, - "value": "Not started", - "color": "red", - "order": 0 - }, - { - "id": 1386725, - "value": "In progress", - "color": "orange", - "order": 1 - }, - { - "id": 1386726, - "value": "Completed", - "color": "dark-green", - "order": 2 - } - ] - }, - { - "id": 1859559, + "id": 9002, "type": "date", - "name": "Start", - "order": 7, + "name": "End time", + "description": null, + "order": 4, "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], "date_format": "ISO", - "date_include_time": false, + "date_include_time": true, "date_time_format": "24", "date_show_tzinfo": false, "date_force_timezone": null }, { - "id": 1859561, - "type": "number", - "name": "Workload in days", - "order": 8, - "primary": false, - "number_decimal_places": 0, - "number_negative": false - }, - { - "id": 1859562, + "id": 9028, "type": "formula", - "name": "Deadline", - "order": 9, + "name": "Duration", + "description": null, + "order": 5, "primary": false, - "date_time_format": "24", - "duration_format": null, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "date_show_tzinfo": null, + "number_prefix": "", + "number_separator": "", + "number_decimal_places": null, + "number_suffix": "", + "duration_format": "h:mm", "nullable": true, - "error": null, - "date_include_time": false, - "date_show_tzinfo": false, + "date_time_format": null, "date_force_timezone": null, - "number_decimal_places": null, "array_formula_type": null, - "date_format": "ISO", - "formula": "field('Start') + date_interval(concat(field('Workload in days'),' days'))", - "formula_type": "date" + "error": null, + "date_format": null, + "date_include_time": null, + "formula": "field('End time') - field('Start time')", + "formula_type": "duration" }, { - "id": 1859563, - "type": "formula", - "name": "Days to go", - "order": 10, + "id": 9003, + "type": "long_text", + "name": "Notes", + "description": null, + "order": 6, "primary": false, - "date_time_format": null, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "long_text_enable_rich_text": false + }, + { + "id": 9029, + "type": "lookup", + "name": "Assignee", + "description": null, + "order": 7, + "primary": false, + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "date_show_tzinfo": null, + "number_prefix": "", + "number_separator": "", + "number_decimal_places": null, + "number_suffix": "", "duration_format": null, "nullable": true, - "error": null, - "date_include_time": null, - "date_show_tzinfo": null, + "date_time_format": null, "date_force_timezone": null, - "number_decimal_places": 0, - "array_formula_type": null, + "array_formula_type": "text", + "error": null, "date_format": null, - "formula": "if(field('Status') != 'Completed', date_diff('dd',now(),field('Deadline')),0)", - "formula_type": "number" + "date_include_time": null, + "through_field_id": 9000, + "through_field_name": "Task", + "target_field_id": 8987, + "target_field_name": "Assignee" }, { - "id": 1859564, - "type": "formula", - "name": "Project name", - "order": 11, + "id": 9004, + "type": "boolean", + "name": "Completed", + "description": null, + "order": 8, "primary": false, - "date_time_format": null, - "duration_format": null, - "nullable": false, - "error": null, - "date_include_time": null, - "date_show_tzinfo": null, - "date_force_timezone": null, - "number_decimal_places": null, - "array_formula_type": null, - "date_format": null, - "formula": "join(lookup('Project','Name'),'')", - "formula_type": "text" + "read_only": false, + "db_index": false, + "immutable_type": false, + "immutable_properties": false, + "field_constraints": [], + "boolean_default": false } ], "views": [ { - "id": 437943, + "id": 4015, "type": "grid", - "name": "All tasks", + "name": "All subtasks", "order": 1, "ownership_type": "collaborative", - "owned_by": null, + "owned_by": "frederik@baserow.io", "filter_type": "AND", "filters_disabled": false, "filters": [], "filter_groups": [], "sortings": [ { - "id": 162305, - "field_id": 1859559, + "id": 2631, + "field_id": 9001, "order": "DESC" } ], "group_bys": [], - "decorations": [ - { - "id": 40245, - "type": "background_color", - "value_provider_type": "conditional_color", - "value_provider_conf": { - "colors": [ - { - "id": "52494500-6ae3-4490-80df-b9ce5285513f", - "color": "red", - "filters": [ - { - "id": "695124ca-e196-4cec-ab19-8d76b34ff172", - "type": "lower_than", - "field": 1859563, - "group": null, - "value": "0" - } - ], - "operator": "AND" - } - ] - }, - "order": 1 - } - ], - "public": false, - "row_identifier_type": "id", - "field_options": [ - { - "id": 3032737, - "field_id": 1859534, - "width": 381, - "hidden": false, - "order": 0, - "aggregation_type": "", - "aggregation_raw_type": "" - }, - { - "id": 3032733, - "field_id": 1859530, - "width": 200, - "hidden": false, - "order": 1, - "aggregation_type": "", - "aggregation_raw_type": "" - }, - { - "id": 3032778, - "field_id": 1859558, - "width": 132, - "hidden": false, - "order": 2, - "aggregation_type": "", - "aggregation_raw_type": "" - }, - { - "id": 3032779, - "field_id": 1859559, - "width": 125, - "hidden": false, - "order": 3, - "aggregation_type": "", - "aggregation_raw_type": "" - }, - { - "id": 3032781, - "field_id": 1859561, - "width": 141, - "hidden": false, - "order": 4, - "aggregation_type": "", - "aggregation_raw_type": "" - }, - { - "id": 3032782, - "field_id": 1859562, - "width": 126, - "hidden": false, - "order": 5, - "aggregation_type": "", - "aggregation_raw_type": "" - }, - { - "id": 3032783, - "field_id": 1859563, - "width": 137, - "hidden": false, - "order": 6, - "aggregation_type": "", - "aggregation_raw_type": "" - }, - { - "id": 3032735, - "field_id": 1859532, - "width": 163, - "hidden": false, - "order": 7, - "aggregation_type": "", - "aggregation_raw_type": "" - }, - { - "id": 3032736, - "field_id": 1859533, - "width": 155, - "hidden": false, - "order": 8, - "aggregation_type": "", - "aggregation_raw_type": "" - }, - { - "id": 3032732, - "field_id": 1859529, - "width": 200, - "hidden": false, - "order": 9, - "aggregation_type": "", - "aggregation_raw_type": "" - }, - { - "id": 3032787, - "field_id": 1859564, - "width": 200, - "hidden": true, - "order": 32767, - "aggregation_type": "", - "aggregation_raw_type": "" - } - ] - }, - { - "id": 438004, - "type": "grid", - "name": "All tasks grouped by project", - "order": 2, - "ownership_type": "collaborative", - "owned_by": null, - "filter_type": "AND", - "filters_disabled": false, - "filters": [], - "filter_groups": [], - "sortings": [ - { - "id": 162306, - "field_id": 1859559, - "order": "DESC" - } - ], - "group_bys": [ - { - "id": 1886, - "field_id": 1859564, - "order": "ASC" - } - ], - "decorations": [ - { - "id": 40246, - "type": "background_color", - "value_provider_type": "conditional_color", - "value_provider_conf": { - "colors": [ - { - "id": "52494500-6ae3-4490-80df-b9ce5285513f", - "color": "red", - "filters": [ - { - "id": "695124ca-e196-4cec-ab19-8d76b34ff172", - "type": "lower_than", - "field": 1859563, - "group": null, - "value": "0" - } - ], - "operator": "AND" - } - ] - }, - "order": 1 - } - ], + "decorations": [], "public": false, "row_identifier_type": "id", + "row_height_size": "small", "field_options": [ { - "id": 3033192, - "field_id": 1859534, - "width": 381, - "hidden": false, - "order": 0, - "aggregation_type": "", - "aggregation_raw_type": "" - }, - { - "id": 3033193, - "field_id": 1859530, + "id": 33389, + "field_id": 9003, "width": 200, "hidden": false, - "order": 1, - "aggregation_type": "", - "aggregation_raw_type": "" - }, - { - "id": 3033194, - "field_id": 1859558, - "width": 132, - "hidden": false, - "order": 2, - "aggregation_type": "", - "aggregation_raw_type": "" - }, - { - "id": 3033195, - "field_id": 1859559, - "width": 125, - "hidden": false, - "order": 3, + "order": 0, "aggregation_type": "", "aggregation_raw_type": "" }, { - "id": 3033196, - "field_id": 1859561, - "width": 141, + "id": 33390, + "field_id": 9000, + "width": 200, "hidden": false, - "order": 4, + "order": 1, "aggregation_type": "", "aggregation_raw_type": "" }, { - "id": 3033197, - "field_id": 1859562, - "width": 126, + "id": 33391, + "field_id": 9029, + "width": 125, "hidden": false, - "order": 5, + "order": 2, "aggregation_type": "", "aggregation_raw_type": "" }, { - "id": 3033198, - "field_id": 1859563, - "width": 137, + "id": 33392, + "field_id": 8999, + "width": 200, "hidden": false, - "order": 6, + "order": 3, "aggregation_type": "", "aggregation_raw_type": "" }, { - "id": 3033199, - "field_id": 1859532, - "width": 163, + "id": 33393, + "field_id": 9001, + "width": 155, "hidden": false, - "order": 7, + "order": 4, "aggregation_type": "", "aggregation_raw_type": "" }, { - "id": 3033200, - "field_id": 1859533, - "width": 155, + "id": 33394, + "field_id": 9002, + "width": 200, "hidden": false, - "order": 8, + "order": 5, "aggregation_type": "", "aggregation_raw_type": "" }, { - "id": 3033201, - "field_id": 1859529, - "width": 200, + "id": 33395, + "field_id": 9028, + "width": 123, "hidden": false, - "order": 9, + "order": 6, "aggregation_type": "", "aggregation_raw_type": "" }, { - "id": 3033202, - "field_id": 1859564, + "id": 33396, + "field_id": 9004, "width": 200, - "hidden": true, + "hidden": false, "order": 32767, "aggregation_type": "", "aggregation_raw_type": "" @@ -2302,2119 +12974,7065 @@ ] }, { - "id": 437944, + "id": 4016, "type": "grid", - "name": "Completed tasks", - "order": 3, + "name": "All subtasks grouped by task", + "order": 2, "ownership_type": "collaborative", - "owned_by": null, + "owned_by": "frederik@baserow.io", "filter_type": "AND", "filters_disabled": false, - "filters": [ + "filters": [], + "filter_groups": [], + "sortings": [ { - "id": 204938, - "field_id": 1859558, - "type": "single_select_equal", - "value": "1386726", - "group": null + "id": 2632, + "field_id": 9001, + "order": "DESC" + } + ], + "group_bys": [ + { + "id": 436, + "field_id": 9000, + "order": "ASC" } ], - "filter_groups": [], - "sortings": [], - "group_bys": [], "decorations": [], "public": false, "row_identifier_type": "id", + "row_height_size": "small", "field_options": [ { - "id": 3032738, - "field_id": 1859529, - "width": 200, - "hidden": false, - "order": 32767, - "aggregation_type": "", - "aggregation_raw_type": "" - }, - { - "id": 3032739, - "field_id": 1859530, - "width": 200, - "hidden": false, - "order": 32767, - "aggregation_type": "", - "aggregation_raw_type": "" - }, - { - "id": 3032741, - "field_id": 1859532, - "width": 200, - "hidden": false, - "order": 32767, - "aggregation_type": "", - "aggregation_raw_type": "" - }, - { - "id": 3032742, - "field_id": 1859533, + "id": 33397, + "field_id": 9003, "width": 200, "hidden": false, - "order": 32767, + "order": 0, "aggregation_type": "", "aggregation_raw_type": "" }, { - "id": 3032743, - "field_id": 1859534, + "id": 33398, + "field_id": 9000, "width": 200, "hidden": false, - "order": 32767, + "order": 1, "aggregation_type": "", "aggregation_raw_type": "" }, { - "id": 3032967, - "field_id": 1859558, + "id": 33399, + "field_id": 9029, "width": 200, "hidden": false, - "order": 32767, + "order": 2, "aggregation_type": "", "aggregation_raw_type": "" }, { - "id": 3032968, - "field_id": 1859559, + "id": 33400, + "field_id": 8999, "width": 200, "hidden": false, - "order": 32767, + "order": 3, "aggregation_type": "", "aggregation_raw_type": "" }, { - "id": 3032969, - "field_id": 1859561, + "id": 33401, + "field_id": 9001, "width": 200, "hidden": false, - "order": 32767, + "order": 4, "aggregation_type": "", "aggregation_raw_type": "" }, { - "id": 3032970, - "field_id": 1859562, + "id": 33402, + "field_id": 9002, "width": 200, "hidden": false, - "order": 32767, + "order": 5, "aggregation_type": "", "aggregation_raw_type": "" }, { - "id": 3032971, - "field_id": 1859563, - "width": 200, + "id": 33403, + "field_id": 9028, + "width": 123, "hidden": false, - "order": 32767, - "aggregation_type": "", - "aggregation_raw_type": "" - }, - { - "id": 3032972, - "field_id": 1859564, - "width": 200, - "hidden": true, - "order": 32767, + "order": 6, "aggregation_type": "", "aggregation_raw_type": "" } ] }, { - "id": 437945, + "id": 4017, "type": "grid", - "name": "Tasks in progress", - "order": 4, + "name": "On-going subtasks", + "order": 5, "ownership_type": "collaborative", - "owned_by": null, + "owned_by": "frederik@baserow.io", "filter_type": "AND", "filters_disabled": false, "filters": [ { - "id": 204939, - "field_id": 1859558, - "type": "single_select_equal", - "value": "1386725", + "id": 2041, + "field_id": 9028, + "type": "empty", + "value": "", "group": null } ], "filter_groups": [], - "sortings": [], + "sortings": [ + { + "id": 2633, + "field_id": 9001, + "order": "DESC" + } + ], "group_bys": [], "decorations": [], "public": false, "row_identifier_type": "id", + "row_height_size": "small", "field_options": [ { - "id": 3032744, - "field_id": 1859529, - "width": 200, - "hidden": false, - "order": 32767, - "aggregation_type": "", - "aggregation_raw_type": "" - }, - { - "id": 3032745, - "field_id": 1859530, - "width": 200, - "hidden": false, - "order": 32767, - "aggregation_type": "", - "aggregation_raw_type": "" - }, - { - "id": 3032747, - "field_id": 1859532, - "width": 200, - "hidden": false, - "order": 32767, - "aggregation_type": "", - "aggregation_raw_type": "" - }, - { - "id": 3032748, - "field_id": 1859533, + "id": 33404, + "field_id": 9003, "width": 200, "hidden": false, - "order": 32767, + "order": 0, "aggregation_type": "", "aggregation_raw_type": "" }, { - "id": 3032749, - "field_id": 1859534, + "id": 33405, + "field_id": 9000, "width": 200, "hidden": false, - "order": 32767, + "order": 1, "aggregation_type": "", "aggregation_raw_type": "" }, { - "id": 3033186, - "field_id": 1859558, + "id": 33406, + "field_id": 9029, "width": 200, "hidden": false, - "order": 32767, + "order": 3, "aggregation_type": "", "aggregation_raw_type": "" }, { - "id": 3033187, - "field_id": 1859559, + "id": 33407, + "field_id": 8999, "width": 200, "hidden": false, - "order": 32767, + "order": 4, "aggregation_type": "", "aggregation_raw_type": "" }, { - "id": 3033188, - "field_id": 1859561, + "id": 33408, + "field_id": 9001, "width": 200, "hidden": false, - "order": 32767, + "order": 5, "aggregation_type": "", "aggregation_raw_type": "" }, { - "id": 3033189, - "field_id": 1859562, + "id": 33409, + "field_id": 9002, "width": 200, "hidden": false, - "order": 32767, + "order": 6, "aggregation_type": "", "aggregation_raw_type": "" }, { - "id": 3033190, - "field_id": 1859563, - "width": 200, + "id": 33410, + "field_id": 9028, + "width": 123, "hidden": false, - "order": 32767, - "aggregation_type": "", - "aggregation_raw_type": "" - }, - { - "id": 3033191, - "field_id": 1859564, - "width": 200, - "hidden": true, - "order": 32767, + "order": 7, "aggregation_type": "", "aggregation_raw_type": "" } ] }, { - "id": 438005, - "type": "kanban", - "name": "By status", - "order": 5, - "ownership_type": "collaborative", - "owned_by": "frederik@baserow.io", - "filter_type": "AND", - "filters_disabled": false, - "filters": [], - "filter_groups": [], - "sortings": [], - "decorations": [], - "public": false, - "single_select_field_id": 1859558, - "field_options": [ - { - "id": 208854, - "field_id": 1859529, - "hidden": false, - "order": 32767 - }, - { - "id": 208855, - "field_id": 1859530, - "hidden": false, - "order": 32767 - }, - { - "id": 208856, - "field_id": 1859532, - "hidden": false, - "order": 32767 - }, - { - "id": 208857, - "field_id": 1859533, - "hidden": true, - "order": 32767 - }, - { - "id": 208858, - "field_id": 1859534, - "hidden": true, - "order": 32767 - }, - { - "id": 208859, - "field_id": 1859558, - "hidden": true, - "order": 32767 - }, - { - "id": 208860, - "field_id": 1859559, - "hidden": false, - "order": 32767 - }, - { - "id": 208861, - "field_id": 1859561, - "hidden": false, - "order": 32767 - }, - { - "id": 208862, - "field_id": 1859562, - "hidden": true, - "order": 32767 - }, - { - "id": 208863, - "field_id": 1859563, - "hidden": true, - "order": 32767 - }, - { - "id": 208864, - "field_id": 1859564, - "hidden": true, - "order": 32767 - } - ] - }, - { - "id": 438006, - "type": "calendar", - "name": "Calendar: all tasks", + "id": 4018, + "type": "form", + "name": "Add new subtask", "order": 6, "ownership_type": "collaborative", "owned_by": "frederik@baserow.io", - "filter_type": "AND", - "filters_disabled": false, - "filters": [], - "filter_groups": [], - "sortings": [], - "decorations": [ - { - "id": 40247, - "type": "left_border_color", - "value_provider_type": "single_select_color", - "value_provider_conf": { - "field_id": 1859558 - }, - "order": 1 - } - ], - "public": false, - "date_field_id": 1859559, + "public": true, + "title": "Add a new subtask", + "description": "Use this form to start a new subtask related to an existing task assigned to you", + "cover_image": null, + "logo_image": null, + "submit_text": "Submit", + "submit_action": "MESSAGE", + "submit_action_message": "The subtask has been added. Set the end time once you completed this task", + "submit_action_redirect_url": "", "field_options": [ { - "id": 9159, - "field_id": 1859529, - "hidden": false, - "order": 32767 - }, - { - "id": 9160, - "field_id": 1859530, - "hidden": true, - "order": 32767 - }, - { - "id": 9161, - "field_id": 1859532, - "hidden": true, - "order": 32767 - }, - { - "id": 9162, - "field_id": 1859533, - "hidden": true, - "order": 32767 + "id": 3701, + "field_id": 9000, + "name": "", + "description": "The task this subtask relates to", + "enabled": true, + "required": true, + "order": 0, + "show_when_matching_conditions": false, + "condition_type": "AND", + "conditions": [], + "condition_groups": [], + "field_component": "default", + "include_all_select_options": true, + "allowed_select_options": [] }, { - "id": 9163, - "field_id": 1859534, - "hidden": true, - "order": 32767 + "id": 3702, + "field_id": 8999, + "name": "Name", + "description": "Short name for the subtask", + "enabled": true, + "required": true, + "order": 1, + "show_when_matching_conditions": false, + "condition_type": "AND", + "conditions": [], + "condition_groups": [], + "field_component": "default", + "include_all_select_options": true, + "allowed_select_options": [] }, { - "id": 9164, - "field_id": 1859558, - "hidden": true, - "order": 32767 + "id": 3703, + "field_id": 9003, + "name": "", + "description": "Add some optional notes for future follow-up", + "enabled": true, + "required": false, + "order": 2, + "show_when_matching_conditions": false, + "condition_type": "AND", + "conditions": [], + "condition_groups": [], + "field_component": "default", + "include_all_select_options": true, + "allowed_select_options": [] }, { - "id": 9165, - "field_id": 1859559, - "hidden": true, - "order": 32767 + "id": 3704, + "field_id": 9001, + "name": "", + "description": "Set the date and time you started the subtask. This information will be used for workload calculation", + "enabled": true, + "required": true, + "order": 3, + "show_when_matching_conditions": false, + "condition_type": "AND", + "conditions": [], + "condition_groups": [], + "field_component": "default", + "include_all_select_options": true, + "allowed_select_options": [] }, { - "id": 9166, - "field_id": 1859561, - "hidden": true, - "order": 32767 + "id": 3705, + "field_id": 9002, + "name": "", + "description": "", + "enabled": false, + "required": true, + "order": 4, + "show_when_matching_conditions": false, + "condition_type": "AND", + "conditions": [], + "condition_groups": [], + "field_component": "default", + "include_all_select_options": true, + "allowed_select_options": [] }, { - "id": 9167, - "field_id": 1859562, - "hidden": true, - "order": 32767 + "id": 3706, + "field_id": 9029, + "name": "", + "description": "", + "enabled": false, + "required": true, + "order": 5, + "show_when_matching_conditions": false, + "condition_type": "AND", + "conditions": [], + "condition_groups": [], + "field_component": "default", + "include_all_select_options": true, + "allowed_select_options": [] }, { - "id": 9168, - "field_id": 1859563, - "hidden": true, - "order": 32767 + "id": 3707, + "field_id": 9028, + "name": "", + "description": "", + "enabled": false, + "required": true, + "order": 6, + "show_when_matching_conditions": false, + "condition_type": "AND", + "conditions": [], + "condition_groups": [], + "field_component": "default", + "include_all_select_options": true, + "allowed_select_options": [] }, { - "id": 9169, - "field_id": 1859564, - "hidden": true, - "order": 32767 + "id": 3708, + "field_id": 9004, + "name": "", + "description": "", + "enabled": false, + "required": true, + "order": 32767, + "show_when_matching_conditions": false, + "condition_type": "AND", + "conditions": [], + "condition_groups": [], + "field_component": "default", + "include_all_select_options": true, + "allowed_select_options": [] } ] } ], "rows": [ { - "id": 3, + "id": 1, "order": "1.00000000000000000000", - "created_on": "2021-07-26T16:54:03.364752+00:00", - "updated_on": "2024-02-29T07:40:56.157407+00:00", + "created_on": "2026-01-14T08:24:59.258816+00:00", + "updated_on": "2026-01-15T14:34:57.420903+00:00", + "created_by": "frederik@baserow.io", "last_modified_by": "frederik@baserow.io", - "field_1859529": "Logo Design", - "field_1859530": [ - 3 - ], - "field_1859532": [ + "field_8999": "Create initial CRM entity list", + "field_9000": [ 1 ], - "field_1859533": null, - "field_1859534": "Create a compelling logo that represents the client's brand", - "field_1859558": 1386726, - "field_1859559": "2023-11-17", - "field_1859561": "7", - "field_1859562": null, - "field_1859563": null, - "field_1859564": null + "field_9001": "2025-02-01T09:00:00+00:00", + "field_9002": "2025-02-01T11:30:00+00:00", + "field_9028": null, + "field_9003": "Identified customers, contacts, deals, incidents and risks", + "field_9029": null, + "field_9004": "false" }, { - "id": 4, + "id": 2, "order": "2.00000000000000000000", - "created_on": "2021-07-26T16:54:03.364879+00:00", - "updated_on": "2024-02-29T07:40:56.157486+00:00", + "created_on": "2026-01-14T08:24:59.258849+00:00", + "updated_on": "2026-01-15T14:34:57.420951+00:00", + "created_by": "frederik@baserow.io", "last_modified_by": "frederik@baserow.io", - "field_1859529": "Color Palette Selection", - "field_1859530": [ - 3 - ], - "field_1859532": [ - 2 + "field_8999": "Define fields and attributes", + "field_9000": [ + 1 ], - "field_1859533": null, - "field_1859534": "Choose a cohesive color palette that aligns with the brand identity", - "field_1859558": 1386726, - "field_1859559": "2023-11-25", - "field_1859561": "3", - "field_1859562": null, - "field_1859563": null, - "field_1859564": null + "field_9001": "2025-02-01T13:00:00+00:00", + "field_9002": "2025-02-01T16:00:00+00:00", + "field_9028": null, + "field_9003": "Added key fields for each entity", + "field_9029": null, + "field_9004": "false" }, { - "id": 5, + "id": 3, "order": "3.00000000000000000000", - "created_on": "2021-07-26T16:54:03.364933+00:00", - "updated_on": "2024-02-29T07:40:56.157519+00:00", + "created_on": "2026-01-14T08:24:59.258859+00:00", + "updated_on": "2026-01-15T14:34:57.420962+00:00", + "created_by": "frederik@baserow.io", "last_modified_by": "frederik@baserow.io", - "field_1859529": "Brand Guidelines Creation", - "field_1859530": [ - 3 - ], - "field_1859532": [ + "field_8999": "Review entities with IT Manager", + "field_9000": [ 1 ], - "field_1859533": null, - "field_1859534": "Develop comprehensive brand guidelines outlining logo usage", - "field_1859558": 1386726, - "field_1859559": "2023-11-27", - "field_1859561": "5", - "field_1859562": null, - "field_1859563": null, - "field_1859564": null + "field_9001": "2025-02-02T10:00:00+00:00", + "field_9002": "2025-02-02T11:00:00+00:00", + "field_9028": null, + "field_9003": "Validated entities with Lucas", + "field_9029": null, + "field_9004": "false" }, { - "id": 6, + "id": 4, "order": "4.00000000000000000000", - "created_on": "2021-07-26T16:54:03.364984+00:00", - "updated_on": "2024-02-29T07:51:48.196309+00:00", + "created_on": "2026-01-14T08:24:59.258868+00:00", + "updated_on": "2026-01-15T14:34:57.420970+00:00", + "created_by": "frederik@baserow.io", "last_modified_by": "frederik@baserow.io", - "field_1859529": "Stationery Design", - "field_1859530": [ - 3 + "field_8999": "Finalize CRM entities", + "field_9000": [ + 1 ], - "field_1859532": [ + "field_9001": "2025-02-02T14:00:00+00:00", + "field_9002": "2025-02-02T15:30:00+00:00", + "field_9028": null, + "field_9003": "Prepared final entity list for approval", + "field_9029": null, + "field_9004": "false" + }, + { + "id": 5, + "order": "5.00000000000000000000", + "created_on": "2026-01-14T08:24:59.258877+00:00", + "updated_on": "2026-01-15T14:34:57.420976+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8999": "Design entity relationships", + "field_9000": [ 2 ], - "field_1859533": null, - "field_1859534": "Design business cards", - "field_1859558": 1386726, - "field_1859559": "2023-11-27", - "field_1859561": "7", - "field_1859562": null, - "field_1859563": null, - "field_1859564": null + "field_9001": "2025-02-03T09:00:00+00:00", + "field_9002": "2025-02-03T12:00:00+00:00", + "field_9028": null, + "field_9003": "Defined customer, deal, incident and risk relationships", + "field_9029": null, + "field_9004": "false" }, { - "id": 7, - "order": "5.00000000000000000000", - "created_on": "2021-07-26T16:54:03.365038+00:00", - "updated_on": "2024-02-29T07:51:48.687669+00:00", + "id": 6, + "order": "6.00000000000000000000", + "created_on": "2026-01-14T08:24:59.258885+00:00", + "updated_on": "2026-01-15T14:34:57.420983+00:00", + "created_by": "frederik@baserow.io", "last_modified_by": "frederik@baserow.io", - "field_1859529": "Brand Presentation", - "field_1859530": [ - 3 + "field_8999": "Create relationship diagram", + "field_9000": [ + 2 ], - "field_1859532": [ + "field_9001": "2025-02-03T13:00:00+00:00", + "field_9002": "2025-02-03T15:30:00+00:00", + "field_9028": null, + "field_9003": "Built ER diagram for CRM", + "field_9029": null, + "field_9004": "false" + }, + { + "id": 7, + "order": "7.00000000000000000000", + "created_on": "2026-01-14T08:24:59.258894+00:00", + "updated_on": "2026-01-15T14:34:57.420989+00:00", + "created_by": "frederik@baserow.io", + "last_modified_by": "frederik@baserow.io", + "field_8999": "Test relationships with sample data", + "field_9000": [ 2 ], - "field_1859533": null, - "field_1859534": "Prepare a presentation to showcase the brand identity concepts to the client", - "field_1859558": 1386726, - "field_1859559": "2023-11-30", - "field_1859561": "4", - "field_1859562": null, - "field_1859563": null, - "field_1859564": null + "field_9001": "2025-02-04T09:00:00+00:00", + "field_9002": "2025-02-04T11:00:00+00:00", + "field_9028": null, + "field_9003": "Validated integrity with dummy records", + "field_9029": null, + "field_9004": "false" }, { "id": 8, - "order": "6.00000000000000000000", - "created_on": "2021-07-26T16:54:03.365091+00:00", - "updated_on": "2024-02-29T07:40:56.157595+00:00", + "order": "8.00000000000000000000", + "created_on": "2026-01-14T08:24:59.258902+00:00", + "updated_on": "2026-01-15T14:34:57.420995+00:00", + "created_by": "frederik@baserow.io", "last_modified_by": "frederik@baserow.io", - "field_1859529": "Audience Analysis", - "field_1859530": [ - 5 - ], - "field_1859532": [ - 5 + "field_8999": "Review relationships with business", + "field_9000": [ + 2 ], - "field_1859533": null, - "field_1859534": "Conduct research to identify the target audience and their preferences", - "field_1859558": 1386725, - "field_1859559": "2024-02-04", - "field_1859561": "5", - "field_1859562": null, - "field_1859563": null, - "field_1859564": null + "field_9001": "2025-02-04T14:00:00+00:00", + "field_9002": "2025-02-04T15:30:00+00:00", + "field_9028": null, + "field_9003": "Confirmed usability with Operations", + "field_9029": null, + "field_9004": "false" }, { "id": 9, - "order": "7.00000000000000000000", - "created_on": "2021-07-26T16:54:03.365143+00:00", - "updated_on": "2024-02-29T07:40:56.157618+00:00", + "order": "9.00000000000000000000", + "created_on": "2026-01-14T08:24:59.258911+00:00", + "updated_on": "2026-01-15T14:34:57.421001+00:00", + "created_by": "frederik@baserow.io", "last_modified_by": "frederik@baserow.io", - "field_1859529": "Content Creation", - "field_1859530": [ - 5 - ], - "field_1859532": [ - 1 + "field_8999": "Prepare data model presentation", + "field_9000": [ + 3 ], - "field_1859533": null, - "field_1859534": "Develop engaging content tailored to the target audience and platform", - "field_1859558": 1386726, - "field_1859559": "2024-03-11", - "field_1859561": "8", - "field_1859562": null, - "field_1859563": null, - "field_1859564": null + "field_9001": "2025-02-10T09:00:00+00:00", + "field_9002": "2025-02-10T10:30:00+00:00", + "field_9028": null, + "field_9003": "Prepared slides and diagrams", + "field_9029": null, + "field_9004": "false" }, { "id": 10, - "order": "8.00000000000000000000", - "created_on": "2021-07-26T16:54:03.365191+00:00", - "updated_on": "2024-02-29T07:40:56.157641+00:00", + "order": "10.00000000000000000000", + "created_on": "2026-01-14T08:24:59.258919+00:00", + "updated_on": "2026-01-15T14:34:57.421008+00:00", + "created_by": "frederik@baserow.io", "last_modified_by": "frederik@baserow.io", - "field_1859529": "Ad Copywriting", - "field_1859530": [ - 5 - ], - "field_1859532": [ + "field_8999": "Run approval meeting", + "field_9000": [ 3 ], - "field_1859533": null, - "field_1859534": "Write persuasive ad copy that drives engagement and conversions", - "field_1859558": 1386725, - "field_1859559": "2024-02-18", - "field_1859561": "4", - "field_1859562": null, - "field_1859563": null, - "field_1859564": null + "field_9001": "2025-02-10T11:00:00+00:00", + "field_9002": "2025-02-10T12:00:00+00:00", + "field_9028": null, + "field_9003": "Reviewed model with stakeholders", + "field_9029": null, + "field_9004": "false" }, { "id": 11, - "order": "9.00000000000000000000", - "created_on": "2021-07-26T16:54:03.365233+00:00", - "updated_on": "2024-02-29T07:51:23.359392+00:00", + "order": "11.00000000000000000000", + "created_on": "2026-01-14T08:24:59.258933+00:00", + "updated_on": "2026-01-15T14:34:57.421015+00:00", + "created_by": "frederik@baserow.io", "last_modified_by": "frederik@baserow.io", - "field_1859529": "Ad Campaign Setup", - "field_1859530": [ - 5 - ], - "field_1859532": [ - 5 + "field_8999": "Collect feedback and changes", + "field_9000": [ + 3 ], - "field_1859533": null, - "field_1859534": "Create and launch targeted advertising campaigns across social media platforms", - "field_1859558": 1386725, - "field_1859559": "2024-03-04", - "field_1859561": "6", - "field_1859562": null, - "field_1859563": null, - "field_1859564": null + "field_9001": "2025-02-10T13:00:00+00:00", + "field_9002": "2025-02-10T14:30:00+00:00", + "field_9028": null, + "field_9003": "Minor changes requested", + "field_9029": null, + "field_9004": "false" }, { "id": 12, - "order": "10.00000000000000000000", - "created_on": "2021-07-26T16:54:03.365276+00:00", - "updated_on": "2024-02-29T07:40:56.157687+00:00", + "order": "12.00000000000000000000", + "created_on": "2026-01-14T08:24:59.258941+00:00", + "updated_on": "2026-04-03T07:18:10.539923+00:00", + "created_by": "frederik@baserow.io", "last_modified_by": "frederik@baserow.io", - "field_1859529": "Campaign Monitoring and Optimization", - "field_1859530": [ - 5 - ], - "field_1859532": [ - 5 + "field_8999": "Confirm final approval", + "field_9000": [ + 3 ], - "field_1859533": null, - "field_1859534": "Monitor campaign performance and make adjustments to optimize results", - "field_1859558": 1386724, - "field_1859559": "2024-02-23", - "field_1859561": "7", - "field_1859562": null, - "field_1859563": null, - "field_1859564": null + "field_9001": "2025-02-15T10:00:00+00:00", + "field_9002": "2025-02-15T12:12:00+00:00", + "field_9028": null, + "field_9003": "Formal approval received", + "field_9029": null, + "field_9004": "false" + } + ], + "data_sync": null, + "field_rules": [] + } + ] + }, + { + "pages": [ + { + "id": 564, + "name": "__shared__", + "order": 1, + "path": "__shared__", + "path_params": [], + "query_params": [], + "shared": true, + "elements": [ + { + "id": 9364, + "order": "1.00000000000000000000", + "type": "header", + "parent_element_id": null, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": {}, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 10, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 10, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 0, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 0, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "share_type": "all", + "pages": [] + }, + { + "id": 9365, + "order": "1.00000000000000000000", + "type": "image", + "parent_element_id": 9364, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": {}, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 10, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 10, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "image_source_type": "upload", + "image_file_id": { + "name": "jSCtzfWNDfTPBHpaACprCIKTsRHJTewD_19f8e94b815ae7415c8032ce03c362000e30184a0bbc4b098debe63087394231.png", + "original_name": "application-header.png" + }, + "image_url": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "alt_text": { + "mode": "simple", + "version": "0.1", + "formula": "" + } + } + ], + "data_sources": [], + "workflow_actions": [], + "visibility": "all", + "role_type": "allow_all", + "roles": [] + }, + { + "id": 565, + "name": "Project details", + "order": 1, + "path": "/project-details/:project_id", + "path_params": [ + { + "name": "project_id", + "type": "numeric" + } + ], + "query_params": [], + "shared": false, + "elements": [ + { + "id": 9368, + "order": "1.00000000000000000000", + "type": "heading", + "parent_element_id": null, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": {}, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 10, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 10, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "get('data_source.1013.field_8972')" + }, + "level": 1 + }, + { + "id": 9369, + "order": "1.00000000000000000000", + "type": "iframe", + "parent_element_id": 9367, + "place_in_container": "1", + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": {}, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 10, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 10, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 0, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 0, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "color", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "source_type": "embed", + "url": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "embed": { + "mode": "simple", + "version": "0.1", + "formula": "concat('','\n','','\n','','\n','
','\n','','\n','
','\n','')" + }, + "height": 350 + }, + { + "id": 9378, + "order": "1.00000000000000000000", + "type": "simple_container", + "parent_element_id": 9366, + "place_in_container": "0", + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": {}, + "style_border_top_color": "primary", + "style_border_top_size": 4, + "style_padding_top": 0, + "style_margin_top": 0, + "style_border_bottom_color": "primary", + "style_border_bottom_size": 4, + "style_padding_bottom": 0, + "style_margin_bottom": 0, + "style_border_left_color": "primary", + "style_border_left_size": 4, + "style_padding_left": 0, + "style_margin_left": 0, + "style_border_right_color": "primary", + "style_border_right_size": 4, + "style_padding_right": 0, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal" + }, + { + "id": 9379, + "order": "1.00000000000000000000", + "type": "simple_container", + "parent_element_id": 9366, + "place_in_container": "1", + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": {}, + "style_border_top_color": "primary", + "style_border_top_size": 4, + "style_padding_top": 0, + "style_margin_top": 0, + "style_border_bottom_color": "primary", + "style_border_bottom_size": 4, + "style_padding_bottom": 0, + "style_margin_bottom": 0, + "style_border_left_color": "primary", + "style_border_left_size": 4, + "style_padding_left": 0, + "style_margin_left": 0, + "style_border_right_color": "primary", + "style_border_right_size": 4, + "style_padding_right": 0, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal" + }, + { + "id": 9380, + "order": "1.00000000000000000000", + "type": "simple_container", + "parent_element_id": 9366, + "place_in_container": "2", + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": {}, + "style_border_top_color": "primary", + "style_border_top_size": 4, + "style_padding_top": 0, + "style_margin_top": 0, + "style_border_bottom_color": "primary", + "style_border_bottom_size": 4, + "style_padding_bottom": 0, + "style_margin_bottom": 0, + "style_border_left_color": "primary", + "style_border_left_size": 4, + "style_padding_left": 0, + "style_margin_left": 0, + "style_border_right_color": "primary", + "style_border_right_size": 4, + "style_padding_right": 0, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal" + }, + { + "id": 9381, + "order": "1.00000000000000000000", + "type": "simple_container", + "parent_element_id": 9366, + "place_in_container": "3", + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": {}, + "style_border_top_color": "primary", + "style_border_top_size": 4, + "style_padding_top": 0, + "style_margin_top": 0, + "style_border_bottom_color": "primary", + "style_border_bottom_size": 4, + "style_padding_bottom": 0, + "style_margin_bottom": 0, + "style_border_left_color": "primary", + "style_border_left_size": 4, + "style_padding_left": 0, + "style_margin_left": 0, + "style_border_right_color": "primary", + "style_border_right_size": 4, + "style_padding_right": 0, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal" + }, + { + "id": 9382, + "order": "1.00000000000000000000", + "type": "simple_container", + "parent_element_id": 9367, + "place_in_container": "0", + "css_classes": "chart__container--status", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": {}, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 0, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 0, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 0, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 0, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal" + }, + { + "id": 9383, + "order": "1.00000000000000000000", + "type": "text", + "parent_element_id": 9378, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": { + "typography": { + "body_font_size": 18, + "body_text_color": "ElMaZ", + "body_font_weight": "semi-bold" + } + }, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 10, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 10, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "color", + "style_background_color": "primary", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "'TIME'" + }, + "format": "plain" + }, + { + "id": 9384, + "order": "1.00000000000000000000", + "type": "iframe", + "parent_element_id": 9382, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": {}, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 10, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 10, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 0, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 0, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "color", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "source_type": "embed", + "url": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "embed": { + "mode": "simple", + "version": "0.1", + "formula": "concat('','\n','','\n','
','\n','','\n','
','\n','')" + }, + "height": 350 + }, + { + "id": 9385, + "order": "1.50000000000000000000", + "type": "text", + "parent_element_id": 9379, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": { + "typography": { + "body_font_size": 18, + "body_text_color": "ElMaZ", + "body_font_weight": "semi-bold" + } + }, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 10, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 10, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "color", + "style_background_color": "primary", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "'WORKLOAD (HOURS)'" + }, + "format": "plain" + }, + { + "id": 9370, + "order": "2.00000000000000000000", + "type": "text", + "parent_element_id": null, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": {}, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 10, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 10, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "get('data_source.1013.field_8973')" + }, + "format": "plain" + }, + { + "id": 9386, + "order": "2.00000000000000000000", + "type": "text", + "parent_element_id": 9378, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": { + "typography": { + "body_font_size": 12 + } + }, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 10, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 0, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "'START OF THE FIRST PHASE'" + }, + "format": "plain" + }, + { + "id": 9387, + "order": "2.00000000000000000000", + "type": "text", + "parent_element_id": 9380, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": { + "typography": { + "body_font_size": 18, + "body_text_color": "ElMaZ", + "body_font_weight": "semi-bold" + } + }, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 10, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 10, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "color", + "style_background_color": "primary", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "'TASKS (AMOUNT)'" + }, + "format": "plain" + }, + { + "id": 9388, + "order": "2.50000000000000000000", + "type": "text", + "parent_element_id": 9379, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": { + "typography": { + "body_font_size": 12 + } + }, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 10, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 0, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "'ESTIMATED WORKLOAD'" + }, + "format": "plain" + }, + { + "id": 9389, + "order": "2.50000000000000000000", + "type": "text", + "parent_element_id": 9381, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": { + "typography": { + "body_font_size": 18, + "body_text_color": "ElMaZ", + "body_font_weight": "semi-bold" + } + }, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 10, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 10, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "color", + "style_background_color": "primary", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "'BUDGET'" + }, + "format": "plain" + }, + { + "id": 9366, + "order": "3.00000000000000000000", + "type": "column", + "parent_element_id": null, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": {}, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 10, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 10, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "column_amount": 4, + "column_gap": 50, + "alignment": "top" + }, + { + "id": 9390, + "order": "3.00000000000000000000", + "type": "text", + "parent_element_id": 9378, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": { + "typography": { + "body_font_weight": "medium", + "body_text_alignment": "right" + } + }, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 0, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 10, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "get('data_source.1013.field_9036')" + }, + "format": "plain" + }, + { + "id": 9391, + "order": "3.00000000000000000000", + "type": "text", + "parent_element_id": 9380, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": { + "typography": { + "body_font_size": 12 + } + }, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 10, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 0, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "'NUMBER OF TASKS'" + }, + "format": "plain" }, { - "id": 13, - "order": "11.00000000000000000000", - "created_on": "2021-07-26T16:54:03.365318+00:00", - "updated_on": "2024-02-29T07:40:56.157712+00:00", - "last_modified_by": "frederik@baserow.io", - "field_1859529": "Ad Creative Production", - "field_1859530": [ - 7 - ], - "field_1859532": [ - 1 - ], - "field_1859533": null, - "field_1859534": "Create visually appealing ad creatives tailored to the campaign objectives", - "field_1859558": 1386725, - "field_1859559": "2024-03-12", - "field_1859561": "5", - "field_1859562": null, - "field_1859563": null, - "field_1859564": null + "id": 9392, + "order": "3.50000000000000000000", + "type": "text", + "parent_element_id": 9379, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": { + "typography": { + "body_font_weight": "medium", + "body_text_alignment": "right" + } + }, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 0, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 10, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "concat(get('data_source.1013.field_9006'),' hours')" + }, + "format": "plain" }, { - "id": 14, - "order": "12.00000000000000000000", - "created_on": "2024-02-29T07:38:42.263217+00:00", - "updated_on": "2024-02-29T07:51:00.437910+00:00", - "created_by": "frederik@baserow.io", - "last_modified_by": "frederik@baserow.io", - "field_1859529": "Campaign Launch", - "field_1859530": [ - 7 - ], - "field_1859532": [ - 1 - ], - "field_1859533": null, - "field_1859534": "Launch the digital advertising campaign across selected platforms", - "field_1859558": 1386725, - "field_1859559": "2024-03-17", - "field_1859561": "3", - "field_1859562": null, - "field_1859563": null, - "field_1859564": null + "id": 9393, + "order": "3.50000000000000000000", + "type": "text", + "parent_element_id": 9381, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": { + "typography": { + "body_font_size": 12 + } + }, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 10, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 0, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "'ESTIMATED BUDGET'" + }, + "format": "plain" }, { - "id": 15, - "order": "13.00000000000000000000", - "created_on": "2024-02-29T07:38:42.263267+00:00", - "updated_on": "2024-02-29T07:51:00.814239+00:00", - "created_by": "frederik@baserow.io", - "last_modified_by": "frederik@baserow.io", - "field_1859529": "Campaign Strategy Development", - "field_1859530": [ - 7 - ], - "field_1859532": [ - 1 - ], - "field_1859533": null, - "field_1859534": "Develop a comprehensive strategy outlining campaign objectives", - "field_1859558": 1386724, - "field_1859559": null, - "field_1859561": "3", - "field_1859562": null, - "field_1859563": null, - "field_1859564": null + "id": 9371, + "order": "4.00000000000000000000", + "type": "heading", + "parent_element_id": null, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": {}, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 10, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 10, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "'Project phases'" + }, + "level": 2 }, { - "id": 16, - "order": "14.00000000000000000000", - "created_on": "2024-02-29T07:38:42.263288+00:00", - "updated_on": "2024-02-29T07:51:01.180564+00:00", - "created_by": "frederik@baserow.io", - "last_modified_by": "frederik@baserow.io", - "field_1859529": "Performance Analysis", - "field_1859530": [ - 7 - ], - "field_1859532": [ - 1 - ], - "field_1859533": null, - "field_1859534": "Analyze campaign performance metrics to measure success and identify areas for improvement", - "field_1859558": 1386724, - "field_1859559": "2024-03-20", - "field_1859561": "7", - "field_1859562": null, - "field_1859563": null, - "field_1859564": null + "id": 9394, + "order": "4.00000000000000000000", + "type": "text", + "parent_element_id": 9378, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": { + "typography": { + "body_font_size": 12 + } + }, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 10, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 0, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "'END OF THE LAST PHASE'" + }, + "format": "plain" }, { - "id": 17, - "order": "15.00000000000000000000", - "created_on": "2024-02-29T07:38:42.263306+00:00", - "updated_on": "2024-02-29T07:51:01.720625+00:00", - "created_by": "frederik@baserow.io", - "last_modified_by": "frederik@baserow.io", - "field_1859529": "Campaign Optimization", - "field_1859530": [ - 7 - ], - "field_1859532": [ - 1 - ], - "field_1859533": null, - "field_1859534": "Optimize ad targeting", - "field_1859558": 1386724, - "field_1859559": null, - "field_1859561": "9", - "field_1859562": null, - "field_1859563": null, - "field_1859564": null + "id": 9395, + "order": "4.00000000000000000000", + "type": "text", + "parent_element_id": 9380, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": { + "typography": { + "body_font_weight": "medium", + "body_text_alignment": "right" + } + }, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 0, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 10, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "get('data_source.1013.field_9016')" + }, + "format": "plain" }, { - "id": 18, - "order": "16.00000000000000000000", - "created_on": "2024-02-29T07:38:42.263324+00:00", - "updated_on": "2024-02-29T07:50:32.650778+00:00", - "created_by": "frederik@baserow.io", - "last_modified_by": "frederik@baserow.io", - "field_1859529": "Client Discovery Session", - "field_1859530": [ - 8 - ], - "field_1859532": [ - 5 - ], - "field_1859533": null, - "field_1859534": "Conduct an initial meeting with the client to understand their brand vision and goals", - "field_1859558": 1386726, - "field_1859559": "2024-03-06", - "field_1859561": "3", - "field_1859562": null, - "field_1859563": null, - "field_1859564": null + "id": 9396, + "order": "4.50000000000000000000", + "type": "text", + "parent_element_id": 9379, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": { + "typography": { + "body_font_size": 12 + } + }, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 10, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 0, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "'COMPLETED WORKLOAD'" + }, + "format": "plain" }, { - "id": 19, - "order": "17.00000000000000000000", - "created_on": "2024-02-29T07:38:42.263341+00:00", - "updated_on": "2024-02-29T07:50:38.784358+00:00", - "created_by": "frederik@baserow.io", - "last_modified_by": "frederik@baserow.io", - "field_1859529": "Brand Identity Workshop", - "field_1859530": [ - 8 - ], - "field_1859532": [ - 6 - ], - "field_1859533": null, - "field_1859534": "Facilitate a workshop with key stakeholders to define brand values", - "field_1859558": 1386724, - "field_1859559": null, - "field_1859561": "4", - "field_1859562": null, - "field_1859563": null, - "field_1859564": null + "id": 9397, + "order": "4.50000000000000000000", + "type": "text", + "parent_element_id": 9381, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": { + "typography": { + "body_font_weight": "medium", + "body_text_alignment": "right" + } + }, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 0, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 10, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "concat('$ ',get('data_source.1013.field_9040'))" + }, + "format": "plain" }, { - "id": 20, - "order": "18.00000000000000000000", - "created_on": "2024-02-29T07:38:42.263359+00:00", - "updated_on": "2024-02-29T07:50:40.266405+00:00", - "created_by": "frederik@baserow.io", - "last_modified_by": "frederik@baserow.io", - "field_1859529": "Competitive Analysis", - "field_1859530": [ - 8 - ], - "field_1859532": [ - 6 + "id": 9372, + "order": "5.00000000000000000000", + "type": "table", + "parent_element_id": null, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": {}, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 10, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 10, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "data_source_id": 1014, + "items_per_page": 20, + "button_load_more_label": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "schema_property": null, + "property_options": [], + "fields": [ + { + "uid": "5aa0fb97-4498-4df7-be43-3a4d6a4ed3f8", + "name": "Name", + "type": "link", + "styles": {}, + "config": { + "navigation_type": "page", + "navigate_to_page_id": 566, + "page_parameters": [ + { + "name": "project_id", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "get('page_parameter.project_id')" + } + }, + { + "name": "phase_id", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "get('current_record.id')" + } + } + ], + "query_parameters": [], + "navigate_to_url": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "target": "self", + "link_name": { + "mode": "simple", + "version": "0.1", + "formula": "get('current_record.field_8979')" + }, + "variant": "link" + } + }, + { + "uid": "31f16a69-817c-460d-94aa-a52f9f9442c1", + "name": "STATUS", + "type": "text", + "styles": {}, + "config": { + "value": { + "mode": "simple", + "version": "0.1", + "formula": "get('current_record.field_9045')" + } + } + }, + { + "uid": "c610283b-304f-4d84-aab1-1e45d780f7a9", + "name": "TIME", + "type": "text", + "styles": {}, + "config": { + "value": { + "mode": "simple", + "version": "0.1", + "formula": "concat(get('current_record.field_9038'),'%')" + } + } + }, + { + "uid": "8886a5f4-abd1-4e2d-8796-e83b380621ba", + "name": "WORKLOAD (HOURS)", + "type": "text", + "styles": {}, + "config": { + "value": { + "mode": "simple", + "version": "0.1", + "formula": "concat(get('current_record.field_9014'),' / ',get('current_record.field_9011'),' (',get('current_record.field_9032'),'%)')" + } + } + }, + { + "uid": "5dfcf4c1-b8bd-49bd-8494-e7bebe4e99ba", + "name": "TASKS (AMOUNT)", + "type": "text", + "styles": {}, + "config": { + "value": { + "mode": "simple", + "version": "0.1", + "formula": "concat(get('current_record.field_9015'),' / ',get('current_record.field_9017'),' ')" + } + } + }, + { + "uid": "4861e4ce-89b9-4459-89e4-9a466b64da90", + "name": "BUDGET", + "type": "text", + "styles": {}, + "config": { + "value": { + "mode": "simple", + "version": "0.1", + "formula": "concat('$ ',get('current_record.field_9025'),' / $ ',get('current_record.field_9024'),' (',get('current_record.field_9042'),'%)')" + } + } + } ], - "field_1859533": null, - "field_1859534": "Research and analyze competitors' branding strategies and market positioning", - "field_1859558": 1386725, - "field_1859559": "2024-03-14", - "field_1859561": "4", - "field_1859562": null, - "field_1859563": null, - "field_1859564": null + "orientation": { + "tablet": "horizontal", + "desktop": "horizontal", + "smartphone": "horizontal" + } }, { - "id": 21, - "order": "19.00000000000000000000", - "created_on": "2024-02-29T07:38:42.263377+00:00", - "updated_on": "2024-02-29T07:50:40.589059+00:00", - "created_by": "frederik@baserow.io", - "last_modified_by": "frederik@baserow.io", - "field_1859529": "Brand Strategy Presentation", - "field_1859530": [ - 8 - ], - "field_1859532": [ - 6 - ], - "field_1859533": null, - "field_1859534": "Prepare and deliver a presentation outlining the recommended brand strategy", - "field_1859558": 1386726, - "field_1859559": "2024-03-18", - "field_1859561": "4", - "field_1859562": null, - "field_1859563": null, - "field_1859564": null + "id": 9398, + "order": "5.00000000000000000000", + "type": "text", + "parent_element_id": 9378, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": { + "typography": { + "body_font_weight": "medium", + "body_text_alignment": "right" + } + }, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 0, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 10, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "get('data_source.1013.field_9037')" + }, + "format": "plain" }, { - "id": 22, - "order": "20.00000000000000000000", - "created_on": "2024-02-29T07:38:42.263394+00:00", - "updated_on": "2024-02-29T07:50:31.104284+00:00", - "created_by": "frederik@baserow.io", - "last_modified_by": "frederik@baserow.io", - "field_1859529": "Feedback Integration", - "field_1859530": [ - 8 - ], - "field_1859532": [ - 5 - ], - "field_1859533": null, - "field_1859534": "Incorporate client feedback and iterate on the brand strategy as needed", - "field_1859558": 1386725, - "field_1859559": "2024-03-22", - "field_1859561": "3", - "field_1859562": null, - "field_1859563": null, - "field_1859564": null + "id": 9399, + "order": "5.00000000000000000000", + "type": "text", + "parent_element_id": 9380, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": { + "typography": { + "body_font_size": 12 + } + }, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 10, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 0, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "'COMPLETED TASKS'" + }, + "format": "plain" }, { - "id": 23, - "order": "21.00000000000000000000", - "created_on": "2024-02-29T07:38:42.263411+00:00", - "updated_on": "2024-02-29T07:50:13.313275+00:00", - "created_by": "frederik@baserow.io", - "last_modified_by": "frederik@baserow.io", - "field_1859529": "Market Research", - "field_1859530": [ - 4 - ], - "field_1859532": [ - 4 - ], - "field_1859533": null, - "field_1859534": "Conduct thorough market research to identify target markets and assess market potential", - "field_1859558": 1386726, - "field_1859559": "2024-03-06", - "field_1859561": "7", - "field_1859562": null, - "field_1859563": null, - "field_1859564": null + "id": 9400, + "order": "5.50000000000000000000", + "type": "text", + "parent_element_id": 9379, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": { + "typography": { + "body_font_weight": "medium", + "body_text_alignment": "right" + } + }, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 0, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 10, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "concat(get('data_source.1013.field_9008'),' hours')" + }, + "format": "plain" }, { - "id": 24, - "order": "22.00000000000000000000", - "created_on": "2024-02-29T07:38:42.263428+00:00", - "updated_on": "2024-02-29T07:50:06.461835+00:00", - "created_by": "frederik@baserow.io", - "last_modified_by": "frederik@baserow.io", - "field_1859529": "Competitor Analysis", - "field_1859530": [ - 4 - ], - "field_1859532": [ - 4 - ], - "field_1859533": null, - "field_1859534": "Analyze competitors' market presence", - "field_1859558": 1386724, - "field_1859559": null, - "field_1859561": "6", - "field_1859562": null, - "field_1859563": null, - "field_1859564": null + "id": 9401, + "order": "5.50000000000000000000", + "type": "text", + "parent_element_id": 9381, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": { + "typography": { + "body_font_size": 12 + } + }, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 10, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 0, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "'ACUTAL EXPENSES'" + }, + "format": "plain" }, { - "id": 25, - "order": "23.00000000000000000000", - "created_on": "2024-02-29T07:38:42.263445+00:00", - "updated_on": "2024-02-29T07:50:08.117298+00:00", - "created_by": "frederik@baserow.io", - "last_modified_by": "frederik@baserow.io", - "field_1859529": "SWOT Analysis", - "field_1859530": [ - 4 - ], - "field_1859532": [ - 4 - ], - "field_1859533": null, - "field_1859534": "Perform a SWOT analysis to identify the client's strengths", - "field_1859558": 1386724, - "field_1859559": null, - "field_1859561": "3", - "field_1859562": null, - "field_1859563": null, - "field_1859564": null + "id": 9402, + "order": "5.50000000000000000000", + "type": "iframe", + "parent_element_id": 9378, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": {}, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 0, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 0, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 0, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 0, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "source_type": "embed", + "url": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "embed": { + "mode": "simple", + "version": "0.1", + "formula": "concat('','\n',concat(''))" + }, + "height": 14 }, { - "id": 26, - "order": "24.00000000000000000000", - "created_on": "2024-02-29T07:38:42.263463+00:00", - "updated_on": "2024-02-29T07:50:08.703137+00:00", - "created_by": "frederik@baserow.io", - "last_modified_by": "frederik@baserow.io", - "field_1859529": "Strategy Formulation", - "field_1859530": [ - 4 - ], - "field_1859532": [ - 4 - ], - "field_1859533": null, - "field_1859534": "Develop a comprehensive market entry strategy based on research findings and analysis", - "field_1859558": 1386725, - "field_1859559": "2024-03-23", - "field_1859561": "8", - "field_1859562": null, - "field_1859563": null, - "field_1859564": null + "id": 9373, + "order": "6.00000000000000000000", + "type": "heading", + "parent_element_id": null, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": {}, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 10, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 10, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "'Tasks'" + }, + "level": 2 }, { - "id": 27, - "order": "25.00000000000000000000", - "created_on": "2024-02-29T07:38:42.263480+00:00", - "updated_on": "2024-02-29T07:50:08.838576+00:00", - "created_by": "frederik@baserow.io", - "last_modified_by": "frederik@baserow.io", - "field_1859529": "Strategy Presentation", - "field_1859530": [ - 4 - ], - "field_1859532": [ - 4 - ], - "field_1859533": null, - "field_1859534": "Prepare and deliver a presentation to the client outlining the recommended market entry strategy", - "field_1859558": 1386724, - "field_1859559": "2024-03-31", - "field_1859561": "5", - "field_1859562": null, - "field_1859563": null, - "field_1859564": null - } - ] - }, - { - "id": 261763, - "name": "Clients", - "order": 4, - "fields": [ + "id": 9403, + "order": "6.00000000000000000000", + "type": "text", + "parent_element_id": 9378, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": { + "typography": { + "body_font_size": 30, + "body_text_color": "secondary", + "body_font_weight": "bold", + "body_text_alignment": "center" + } + }, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 10, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 10, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "advanced", + "version": "0.1", + "formula": "concat(round(get('data_source.1013.field_9047'),0),'%')" + }, + "format": "plain" + }, { - "id": 1859535, + "id": 9404, + "order": "6.00000000000000000000", "type": "text", - "name": "Company name", - "order": 0, - "primary": true, - "text_default": "" + "parent_element_id": 9380, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": { + "typography": { + "body_font_weight": "medium", + "body_text_alignment": "right" + } + }, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 0, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 10, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "get('data_source.1013.field_9010')" + }, + "format": "plain" }, { - "id": 1859536, - "type": "link_row", - "name": "Projects", - "order": 1, - "primary": false, - "link_row_table_id": 261761, - "link_row_related_field_id": 1859521, - "has_related_field": true + "id": 9405, + "order": "6.00000000000000000000", + "type": "iframe", + "parent_element_id": 9379, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": {}, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 0, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 0, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 0, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 0, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "source_type": "embed", + "url": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "embed": { + "mode": "simple", + "version": "0.1", + "formula": "concat('','\n','','\n',concat(''))" + }, + "height": 14 }, { - "id": 1859537, - "type": "long_text", - "name": "About", - "order": 2, - "primary": false, - "long_text_enable_rich_text": false + "id": 9367, + "order": "7.00000000000000000000", + "type": "column", + "parent_element_id": null, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": {}, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 10, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 10, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "column_amount": 2, + "column_gap": 0, + "alignment": "top" }, { - "id": 1859538, + "id": 9406, + "order": "7.00000000000000000000", "type": "text", - "name": "Contact person", - "order": 3, - "primary": false, - "text_default": "" + "parent_element_id": 9379, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": { + "typography": { + "body_font_size": 30, + "body_text_color": "secondary", + "body_font_weight": "bold", + "body_text_alignment": "center" + } + }, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 10, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 10, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "advanced", + "version": "0.1", + "formula": "concat(round(get('data_source.1013.field_9030'),0),'%')" + }, + "format": "plain" }, { - "id": 1859539, - "type": "email", - "name": "Contact email", - "order": 4, - "primary": false + "id": 9407, + "order": "7.00000000000000000000", + "type": "text", + "parent_element_id": 9381, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": { + "typography": { + "body_font_weight": "medium", + "body_text_alignment": "right" + } + }, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 0, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 10, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "concat('$ ',get('data_source.1013.field_9041'))" + }, + "format": "plain" + }, + { + "id": 9408, + "order": "7.00000000000000000000", + "type": "iframe", + "parent_element_id": 9380, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": {}, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 0, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 0, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 0, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 0, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "source_type": "embed", + "url": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "embed": { + "mode": "simple", + "version": "0.1", + "formula": "concat('','\n',concat(''))" + }, + "height": 14 }, { - "id": 1859540, - "type": "url", - "name": "Company website", - "order": 5, - "primary": false + "id": 9374, + "order": "7.25000000000000000000", + "type": "heading", + "parent_element_id": null, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": {}, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 10, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 0, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "'In progress'" + }, + "level": 3 }, { - "id": 1859646, - "type": "rollup", - "name": "Active projects", - "order": 6, - "primary": false, - "date_time_format": null, - "duration_format": null, - "nullable": false, - "error": null, - "date_include_time": null, - "date_show_tzinfo": null, - "date_force_timezone": null, - "number_decimal_places": null, - "array_formula_type": null, - "date_format": null, - "through_field_id": 1859536, - "target_field_id": 1859644, - "rollup_function": "any" - } - ], - "views": [ - { - "id": 437946, - "type": "grid", - "name": "All clients", - "order": 1, - "ownership_type": "collaborative", - "owned_by": null, - "filter_type": "AND", - "filters_disabled": false, - "filters": [], - "filter_groups": [], - "sortings": [ - { - "id": 162276, - "field_id": 1859535, - "order": "ASC" - } - ], - "group_bys": [], - "decorations": [], - "public": false, - "row_identifier_type": "id", - "field_options": [ - { - "id": 3032753, - "field_id": 1859538, - "width": 171, - "hidden": false, - "order": 0, - "aggregation_type": "", - "aggregation_raw_type": "" + "id": 9375, + "order": "7.28571428571428558740", + "type": "table", + "parent_element_id": null, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": {}, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 0, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 10, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "data_source_id": 1016, + "items_per_page": 20, + "button_load_more_label": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "schema_property": null, + "property_options": [], + "fields": [ + { + "uid": "f34f7a5e-bdf9-4503-9edf-1246a8cfba5a", + "name": "Icons", + "type": "text", + "styles": {}, + "config": { + "value": { + "mode": "simple", + "version": "0.1", + "formula": "get('current_record.field_9057')" + } + } }, { - "id": 3032754, - "field_id": 1859539, - "width": 248, - "hidden": false, - "order": 1, - "aggregation_type": "", - "aggregation_raw_type": "" + "uid": "096e8a22-5920-4cfc-8d79-c71491da6859", + "name": "Name", + "type": "text", + "styles": {}, + "config": { + "value": { + "mode": "simple", + "version": "0.1", + "formula": "get('current_record.field_8983')" + } + } }, { - "id": 3032752, - "field_id": 1859537, - "width": 415, - "hidden": false, - "order": 2, - "aggregation_type": "", - "aggregation_raw_type": "" + "uid": "91e79364-662f-499a-b5f3-19bb4ac62a07", + "name": "Priority", + "type": "tags", + "styles": {}, + "config": { + "values": { + "mode": "simple", + "version": "0.1", + "formula": "get('current_record.field_8986.value')" + }, + "colors_is_formula": true, + "colors": { + "mode": "simple", + "version": "0.1", + "formula": "get('current_record.field_8986.color')" + } + } }, { - "id": 3032755, - "field_id": 1859540, - "width": 200, - "hidden": false, - "order": 3, - "aggregation_type": "", - "aggregation_raw_type": "" + "uid": "adc75bbe-9614-4014-ac79-699da49ab8b5", + "name": "Assignee", + "type": "text", + "styles": {}, + "config": { + "value": { + "mode": "simple", + "version": "0.1", + "formula": "get('current_record.field_8987.*.value')" + } + } }, { - "id": 3032751, - "field_id": 1859536, - "width": 200, - "hidden": false, - "order": 4, - "aggregation_type": "", - "aggregation_raw_type": "" + "uid": "f4839d42-41bc-42ab-8d20-79b21449a690", + "name": "Start date", + "type": "text", + "styles": {}, + "config": { + "value": { + "mode": "simple", + "version": "0.1", + "formula": "get('current_record.field_8988')" + } + } }, { - "id": 3032750, - "field_id": 1859535, - "width": 200, - "hidden": false, - "order": 5, - "aggregation_type": "", - "aggregation_raw_type": "" + "uid": "db375270-2ccc-4104-a3c2-656dc5560a47", + "name": "Due date", + "type": "text", + "styles": {}, + "config": { + "value": { + "mode": "simple", + "version": "0.1", + "formula": "get('current_record.field_8989')" + } + } }, { - "id": 3032966, - "field_id": 1859646, - "width": 164, - "hidden": false, - "order": 32767, - "aggregation_type": "", - "aggregation_raw_type": "" + "uid": "dbb0f4e6-1a13-4977-a74d-d9a919fda0cc", + "name": "Phase", + "type": "link", + "styles": {}, + "config": { + "navigation_type": "page", + "navigate_to_page_id": 566, + "page_parameters": [ + { + "name": "project_id", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "get('page_parameter.project_id')" + } + }, + { + "name": "phase_id", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "get('current_record.field_8991.0.id')" + } + } + ], + "query_parameters": [], + "navigate_to_url": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "target": "self", + "link_name": { + "mode": "simple", + "version": "0.1", + "formula": "get('current_record.field_8991.0.value')" + }, + "variant": "link" + } } - ] + ], + "orientation": { + "tablet": "horizontal", + "desktop": "horizontal", + "smartphone": "horizontal" + } }, { - "id": 438021, - "type": "grid", - "name": "Clients with active projects", - "order": 2, - "ownership_type": "collaborative", - "owned_by": null, - "filter_type": "AND", - "filters_disabled": false, - "filters": [ - { - "id": 204947, - "field_id": 1859646, - "type": "boolean", - "value": "1", - "group": null - } - ], - "filter_groups": [], - "sortings": [ + "id": 9376, + "order": "7.29999999999999982236", + "type": "heading", + "parent_element_id": null, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": {}, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 50, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 0, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "'Overdue'" + }, + "level": 3 + }, + { + "id": 9377, + "order": "7.30769230769230748734", + "type": "table", + "parent_element_id": null, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": {}, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 0, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 10, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "data_source_id": 1015, + "items_per_page": 20, + "button_load_more_label": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "schema_property": null, + "property_options": [], + "fields": [ + { + "uid": "1656e49d-588a-4d9e-82f7-40860329b09a", + "name": "Icons", + "type": "text", + "styles": {}, + "config": { + "value": { + "mode": "simple", + "version": "0.1", + "formula": "get('current_record.field_9057')" + } + } + }, { - "id": 162311, - "field_id": 1859535, - "order": "ASC" - } - ], - "group_bys": [], - "decorations": [], - "public": false, - "row_identifier_type": "id", - "field_options": [ + "uid": "164717d8-aebb-4b1f-b57e-97d3de459770", + "name": "Name", + "type": "text", + "styles": {}, + "config": { + "value": { + "mode": "simple", + "version": "0.1", + "formula": "get('current_record.field_8983')" + } + } + }, { - "id": 3033297, - "field_id": 1859538, - "width": 171, - "hidden": false, - "order": 0, - "aggregation_type": "", - "aggregation_raw_type": "" + "uid": "edbcbdaf-b9ea-4b20-91e6-3eed31cbba20", + "name": "Status", + "type": "tags", + "styles": {}, + "config": { + "values": { + "mode": "simple", + "version": "0.1", + "formula": "get('current_record.field_8985.value')" + }, + "colors_is_formula": true, + "colors": { + "mode": "simple", + "version": "0.1", + "formula": "get('current_record.field_8985.color')" + } + } }, { - "id": 3033298, - "field_id": 1859539, - "width": 248, - "hidden": false, - "order": 1, - "aggregation_type": "", - "aggregation_raw_type": "" + "uid": "bd19b151-2575-4a82-ad75-01968d2b8787", + "name": "Priority", + "type": "tags", + "styles": {}, + "config": { + "values": { + "mode": "simple", + "version": "0.1", + "formula": "get('current_record.field_8986.value')" + }, + "colors_is_formula": true, + "colors": { + "mode": "simple", + "version": "0.1", + "formula": "get('current_record.field_8986.color')" + } + } }, { - "id": 3033299, - "field_id": 1859537, - "width": 415, - "hidden": false, - "order": 2, - "aggregation_type": "", - "aggregation_raw_type": "" + "uid": "9f8f93cd-e400-43a5-b008-4dd6fa99b24a", + "name": "Assignee", + "type": "text", + "styles": {}, + "config": { + "value": { + "mode": "simple", + "version": "0.1", + "formula": "get('current_record.field_8987.*.value')" + } + } }, { - "id": 3033300, - "field_id": 1859540, - "width": 200, - "hidden": false, - "order": 3, - "aggregation_type": "", - "aggregation_raw_type": "" + "uid": "de6cfe0d-dd0a-48e4-9478-3203888c6425", + "name": "Start date", + "type": "text", + "styles": {}, + "config": { + "value": { + "mode": "simple", + "version": "0.1", + "formula": "get('current_record.field_8988')" + } + } }, { - "id": 3033301, - "field_id": 1859536, - "width": 200, - "hidden": false, - "order": 4, - "aggregation_type": "", - "aggregation_raw_type": "" + "uid": "9d3dfd28-f234-47b0-bad6-b7824bb04093", + "name": "Due date", + "type": "text", + "styles": {}, + "config": { + "value": { + "mode": "simple", + "version": "0.1", + "formula": "get('current_record.field_8989')" + } + } }, { - "id": 3033302, - "field_id": 1859535, - "width": 200, - "hidden": false, - "order": 5, - "aggregation_type": "", - "aggregation_raw_type": "" + "uid": "8f178a34-76b1-48df-b3e3-5188429ae008", + "name": "Overdue", + "type": "text", + "styles": {}, + "config": { + "value": { + "mode": "advanced", + "version": "0.1", + "formula": "replace(get('current_record.field_9023'),'-','')" + } + } }, { - "id": 3033303, - "field_id": 1859646, - "width": 164, - "hidden": false, - "order": 32767, - "aggregation_type": "", - "aggregation_raw_type": "" + "uid": "f2d7ef34-4e4c-4de8-9155-57ff75f00d73", + "name": "Phase", + "type": "link", + "styles": {}, + "config": { + "navigation_type": "page", + "navigate_to_page_id": 566, + "page_parameters": [ + { + "name": "project_id", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "get('page_parameter.project_id')" + } + }, + { + "name": "phase_id", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "get('current_record.field_8991.0.id')" + } + } + ], + "query_parameters": [], + "navigate_to_url": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "target": "self", + "link_name": { + "mode": "simple", + "version": "0.1", + "formula": "get('current_record.field_8991.0.value')" + }, + "variant": "link" + } } - ] + ], + "orientation": { + "tablet": "horizontal", + "desktop": "horizontal", + "smartphone": "horizontal" + } + }, + { + "id": 9409, + "order": "8.00000000000000000000", + "type": "text", + "parent_element_id": 9380, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": { + "typography": { + "body_font_size": 30, + "body_text_color": "secondary", + "body_font_weight": "bold", + "body_text_alignment": "center" + } + }, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 10, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 10, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "advanced", + "version": "0.1", + "formula": "concat(round(get('data_source.1013.field_9033'),0),'%')" + }, + "format": "plain" + }, + { + "id": 9410, + "order": "8.00000000000000000000", + "type": "iframe", + "parent_element_id": 9381, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": {}, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 0, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 1, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "source_type": "embed", + "url": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "embed": { + "mode": "simple", + "version": "0.1", + "formula": "concat('','\n',concat(''))" + }, + "height": 14 + }, + { + "id": 9411, + "order": "9.00000000000000000000", + "type": "text", + "parent_element_id": 9381, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": { + "typography": { + "body_font_size": 30, + "body_text_color": "secondary", + "body_font_weight": "bold", + "body_text_alignment": "center" + } + }, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 10, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 10, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "advanced", + "version": "0.1", + "formula": "concat(round(get('data_source.1013.field_9049'),0),'%')" + }, + "format": "plain" } ], - "rows": [ + "data_sources": [ { - "id": 3, + "id": 1013, + "name": "Project details", "order": "1.00000000000000000000", - "created_on": "2021-07-26T16:54:03.390280+00:00", - "updated_on": "2024-02-29T07:27:28.660772+00:00", - "last_modified_by": "frederik@baserow.io", - "field_1859535": "Acme Corporation", - "field_1859536": [ - 3 - ], - "field_1859537": "Acme Corporation is a pioneering entity dedicated to excellence in manufacturing and distribution of industrial equipment. With a commitment to innovation and customer satisfaction, we strive to streamline processes and optimize productivity for businesses worldwide. Our mission is to enhance efficiency and profitability through cutting-edge solutions.", - "field_1859538": "Eugene Keith", - "field_1859539": "eugene@acme.corp", - "field_1859540": "https://acme.corp", - "field_1859646": null + "service": { + "id": 1883, + "integration_id": 192, + "type": "local_baserow_get_row", + "sample_data": null, + "table_id": 955, + "view_id": null, + "search_query": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "filter_type": "AND", + "filters": [], + "row_id": { + "mode": "simple", + "version": "0.1", + "formula": "get('page_parameter.project_id')" + } + } }, { - "id": 4, + "id": 1014, + "name": "Phases", "order": "2.00000000000000000000", - "created_on": "2021-07-26T16:54:03.390395+00:00", - "updated_on": "2024-02-29T07:27:38.352560+00:00", - "last_modified_by": "frederik@baserow.io", - "field_1859535": "Globex Corporation", - "field_1859536": [ - 4, - 8 - ], - "field_1859537": "Globex Corporation is a global leader in software development and technology solutions, offering cutting-edge software products and IT services to meet diverse needs. Our team is driven by a passion for technological advancement and customer success. At Globex, we believe in harnessing the power of technology to drive positive change and empower businesses globally.", - "field_1859538": "Gladys P. Burchfield", - "field_1859539": "gbp@globex.co", - "field_1859540": "https://globex.co", - "field_1859646": null + "service": { + "id": 1884, + "integration_id": 192, + "type": "local_baserow_list_rows", + "sample_data": null, + "table_id": 956, + "view_id": null, + "sortings": [], + "search_query": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "filter_type": "AND", + "filters": [ + { + "field_id": 8981, + "type": "link_row_has", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "get('page_parameter.project_id')" + }, + "value_is_formula": true + } + ], + "default_result_count": 20 + } + }, + { + "id": 1015, + "name": "Overdue tasks", + "order": "4.00000000000000000000", + "service": { + "id": 1885, + "integration_id": 192, + "type": "local_baserow_list_rows", + "sample_data": null, + "table_id": 957, + "view_id": 3997, + "sortings": [], + "search_query": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "filter_type": "AND", + "filters": [ + { + "field_id": 8992, + "type": "link_row_has", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "get('page_parameter.project_id')" + }, + "value_is_formula": true + } + ], + "default_result_count": 20 + } + }, + { + "id": 1016, + "name": "Active tasks", + "order": "5.00000000000000000000", + "service": { + "id": 1886, + "integration_id": 192, + "type": "local_baserow_list_rows", + "sample_data": null, + "table_id": 957, + "view_id": 3998, + "sortings": [], + "search_query": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "filter_type": "AND", + "filters": [ + { + "field_id": 8992, + "type": "link_row_has", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "get('page_parameter.project_id')" + }, + "value_is_formula": true + } + ], + "default_result_count": 20 + } + }, + { + "id": 1017, + "name": "To do", + "order": "6.00000000000000000000", + "service": { + "id": 1887, + "integration_id": 192, + "type": "local_baserow_aggregate_rows", + "sample_data": null, + "table_id": 957, + "view_id": 3996, + "search_query": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "filter_type": "AND", + "filters": [ + { + "field_id": 8992, + "type": "link_row_has", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "get('page_parameter.project_id')" + }, + "value_is_formula": true + }, + { + "field_id": 8985, + "type": "single_select_equal", + "value": { + "mode": "raw", + "version": "0.1", + "formula": "3608" + }, + "value_is_formula": false + } + ], + "field_id": 8983, + "aggregation_type": "count" + } + }, + { + "id": 1018, + "name": "In progress", + "order": "7.00000000000000000000", + "service": { + "id": 1888, + "integration_id": 192, + "type": "local_baserow_aggregate_rows", + "sample_data": null, + "table_id": 957, + "view_id": 3996, + "search_query": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "filter_type": "AND", + "filters": [ + { + "field_id": 8992, + "type": "link_row_has", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "get('page_parameter.project_id')" + }, + "value_is_formula": true + }, + { + "field_id": 8985, + "type": "single_select_equal", + "value": { + "mode": "raw", + "version": "0.1", + "formula": "3609" + }, + "value_is_formula": false + } + ], + "field_id": 8983, + "aggregation_type": "count" + } + }, + { + "id": 1019, + "name": "Done", + "order": "8.00000000000000000000", + "service": { + "id": 1889, + "integration_id": 192, + "type": "local_baserow_aggregate_rows", + "sample_data": null, + "table_id": 957, + "view_id": 3996, + "search_query": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "filter_type": "AND", + "filters": [ + { + "field_id": 8992, + "type": "link_row_has", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "get('page_parameter.project_id')" + }, + "value_is_formula": true + }, + { + "field_id": 8985, + "type": "single_select_equal", + "value": { + "mode": "raw", + "version": "0.1", + "formula": "3610" + }, + "value_is_formula": false + } + ], + "field_id": 8983, + "aggregation_type": "count" + } + }, + { + "id": 1020, + "name": "Overdue", + "order": "9.00000000000000000000", + "service": { + "id": 1890, + "integration_id": 192, + "type": "local_baserow_aggregate_rows", + "sample_data": null, + "table_id": 957, + "view_id": 3996, + "search_query": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "filter_type": "AND", + "filters": [ + { + "field_id": 8992, + "type": "link_row_has", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "get('page_parameter.project_id')" + }, + "value_is_formula": true + }, + { + "field_id": 9039, + "type": "not_empty", + "value": { + "mode": "raw", + "version": "0.1", + "formula": "" + }, + "value_is_formula": false + } + ], + "field_id": 8983, + "aggregation_type": "count" + } + }, + { + "id": 1021, + "name": "Over budget", + "order": "10.00000000000000000000", + "service": { + "id": 1891, + "integration_id": 192, + "type": "local_baserow_aggregate_rows", + "sample_data": null, + "table_id": 957, + "view_id": 3996, + "search_query": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "filter_type": "AND", + "filters": [ + { + "field_id": 8992, + "type": "link_row_has", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "get('page_parameter.project_id')" + }, + "value_is_formula": true + }, + { + "field_id": 9043, + "type": "not_empty", + "value": { + "mode": "raw", + "version": "0.1", + "formula": "" + }, + "value_is_formula": false + } + ], + "field_id": 8983, + "aggregation_type": "count" + } + }, + { + "id": 1022, + "name": "Over workload", + "order": "11.00000000000000000000", + "service": { + "id": 1892, + "integration_id": 192, + "type": "local_baserow_aggregate_rows", + "sample_data": null, + "table_id": 957, + "view_id": 3996, + "search_query": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "filter_type": "AND", + "filters": [ + { + "field_id": 8992, + "type": "link_row_has", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "get('page_parameter.project_id')" + }, + "value_is_formula": true + }, + { + "field_id": 9056, + "type": "not_empty", + "value": { + "mode": "raw", + "version": "0.1", + "formula": "" + }, + "value_is_formula": false + } + ], + "field_id": 8983, + "aggregation_type": "count" + } + } + ], + "workflow_actions": [], + "visibility": "all", + "role_type": "allow_all", + "roles": [] + }, + { + "id": 566, + "name": "Phase details", + "order": 3, + "path": "/phase-details/:project_id/:phase_id", + "path_params": [ + { + "name": "project_id", + "type": "numeric" + }, + { + "name": "phase_id", + "type": "numeric" + } + ], + "query_params": [], + "shared": false, + "elements": [ + { + "id": 9413, + "order": "1.00000000000000000000", + "type": "heading", + "parent_element_id": null, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": {}, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 10, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 10, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "get('data_source.1023.field_8972')" + }, + "level": 1 + }, + { + "id": 9422, + "order": "1.00000000000000000000", + "type": "simple_container", + "parent_element_id": 9412, + "place_in_container": "0", + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": {}, + "style_border_top_color": "primary", + "style_border_top_size": 4, + "style_padding_top": 0, + "style_margin_top": 0, + "style_border_bottom_color": "primary", + "style_border_bottom_size": 4, + "style_padding_bottom": 0, + "style_margin_bottom": 0, + "style_border_left_color": "primary", + "style_border_left_size": 4, + "style_padding_left": 0, + "style_margin_left": 0, + "style_border_right_color": "primary", + "style_border_right_size": 4, + "style_padding_right": 0, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal" + }, + { + "id": 9423, + "order": "1.00000000000000000000", + "type": "simple_container", + "parent_element_id": 9412, + "place_in_container": "1", + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": {}, + "style_border_top_color": "primary", + "style_border_top_size": 4, + "style_padding_top": 0, + "style_margin_top": 0, + "style_border_bottom_color": "primary", + "style_border_bottom_size": 4, + "style_padding_bottom": 0, + "style_margin_bottom": 0, + "style_border_left_color": "primary", + "style_border_left_size": 4, + "style_padding_left": 0, + "style_margin_left": 0, + "style_border_right_color": "primary", + "style_border_right_size": 4, + "style_padding_right": 0, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal" + }, + { + "id": 9424, + "order": "1.00000000000000000000", + "type": "simple_container", + "parent_element_id": 9412, + "place_in_container": "2", + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": {}, + "style_border_top_color": "primary", + "style_border_top_size": 4, + "style_padding_top": 0, + "style_margin_top": 0, + "style_border_bottom_color": "primary", + "style_border_bottom_size": 4, + "style_padding_bottom": 0, + "style_margin_bottom": 0, + "style_border_left_color": "primary", + "style_border_left_size": 4, + "style_padding_left": 0, + "style_margin_left": 0, + "style_border_right_color": "primary", + "style_border_right_size": 4, + "style_padding_right": 0, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal" + }, + { + "id": 9425, + "order": "1.00000000000000000000", + "type": "simple_container", + "parent_element_id": 9412, + "place_in_container": "3", + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": {}, + "style_border_top_color": "primary", + "style_border_top_size": 4, + "style_padding_top": 0, + "style_margin_top": 0, + "style_border_bottom_color": "primary", + "style_border_bottom_size": 4, + "style_padding_bottom": 0, + "style_margin_bottom": 0, + "style_border_left_color": "primary", + "style_border_left_size": 4, + "style_padding_left": 0, + "style_margin_left": 0, + "style_border_right_color": "primary", + "style_border_right_size": 4, + "style_padding_right": 0, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal" + }, + { + "id": 9426, + "order": "1.00000000000000000000", + "type": "text", + "parent_element_id": 9422, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": { + "typography": { + "body_font_size": 18, + "body_text_color": "ElMaZ", + "body_font_weight": "semi-bold" + } + }, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 10, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 10, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "color", + "style_background_color": "primary", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "'TIME'" + }, + "format": "plain" }, { - "id": 5, - "order": "3.00000000000000000000", - "created_on": "2021-07-26T16:54:03.390445+00:00", - "updated_on": "2024-02-29T07:28:12.631786+00:00", - "last_modified_by": "frederik@baserow.io", - "field_1859535": "Soylent Corp", - "field_1859536": [ - 5 - ], - "field_1859537": "Soylent Corp is dedicated to revolutionizing the food industry, providing convenient and nutritious meal replacement products for modern lifestyles. Our mission is to improve health and convenience through science-driven nutrition. With a focus on sustainability and affordability, Soylent Corp is shaping the future of food consumption and redefining the way people eat.", - "field_1859538": "Marty Sanford", - "field_1859539": "marty.sanford@soylent.com", - "field_1859540": "https://soylent.com", - "field_1859646": null + "id": 9427, + "order": "1.50000000000000000000", + "type": "text", + "parent_element_id": 9423, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": { + "typography": { + "body_font_size": 18, + "body_text_color": "ElMaZ", + "body_font_weight": "semi-bold" + } + }, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 10, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 10, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "color", + "style_background_color": "primary", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "'WORKLOAD (HOURS)'" + }, + "format": "plain" }, { - "id": 6, - "order": "4.00000000000000000000", - "created_on": "2021-07-26T16:54:03.390491+00:00", - "updated_on": "2024-02-29T07:27:57.049746+00:00", - "last_modified_by": "frederik@baserow.io", - "field_1859535": "Initech", - "field_1859536": [ - 6 - ], - "field_1859537": "Initech is a trusted name in financial services, known for our dedication to providing comprehensive financial solutions and exceptional client service. Our innovative solutions are designed to optimize financial performance and drive sustainable growth for businesses of all sizes. At Initech, we prioritize integrity, reliability, and client satisfaction in everything we do.", - "field_1859538": "Steven. Walters", - "field_1859539": "swalters@initech.com", - "field_1859540": "https://initech.com", - "field_1859646": null + "id": 9414, + "order": "2.00000000000000000000", + "type": "text", + "parent_element_id": null, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": {}, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 10, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 10, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "get('data_source.1023.field_8973')" + }, + "format": "plain" }, { - "id": 7, - "order": "5.00000000000000000000", - "created_on": "2021-07-26T16:54:03.390536+00:00", - "updated_on": "2024-02-29T07:28:20.796935+00:00", - "last_modified_by": "frederik@baserow.io", - "field_1859535": "Umbrella Corporation", - "field_1859536": [ - 7 - ], - "field_1859537": "Umbrella Corporation is a leading provider of cybersecurity solutions, known for our commitment to protecting businesses from digital threats and cyber attacks. Our comprehensive solutions are designed to safeguard sensitive data and ensure business continuity in an increasingly digital world. At Umbrella, we prioritize integrity, innovation, and unparalleled protection for our clients' digital assets.", - "field_1859538": "Karen D. Smith", - "field_1859539": "karends@umbrella.net", - "field_1859540": "https://umbrella.net", - "field_1859646": null + "id": 9428, + "order": "2.00000000000000000000", + "type": "text", + "parent_element_id": 9422, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": { + "typography": { + "body_font_size": 12 + } + }, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 10, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 0, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "'START OF THE FIRST TASK'" + }, + "format": "plain" }, { - "id": 8, - "order": "6.00000000000000000000", - "created_on": "2021-07-26T16:54:03.390580+00:00", - "updated_on": "2024-02-29T07:27:45.692918+00:00", - "last_modified_by": "frederik@baserow.io", - "field_1859535": "Hooli", - "field_1859536": [], - "field_1859537": "Hooli is at the forefront of artificial intelligence research and development, delivering exceptional AI-driven products and services. Our dedicated team is committed to pushing the boundaries of innovation and shaping the future of technology. With a focus on groundbreaking research and ethical AI practices, Hooli continues to redefine industry standards and pave the way for a smarter tomorrow.", - "field_1859538": "Amy Wyllie", - "field_1859539": "amy@hooli.com", - "field_1859540": "https://hooli.com", - "field_1859646": null + "id": 9429, + "order": "2.00000000000000000000", + "type": "text", + "parent_element_id": 9424, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": { + "typography": { + "body_font_size": 18, + "body_text_color": "ElMaZ", + "body_font_weight": "semi-bold" + } + }, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 10, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 10, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "color", + "style_background_color": "primary", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "'TASKS (AMOUNT)'" + }, + "format": "plain" }, { - "id": 9, - "order": "7.00000000000000000000", - "created_on": "2021-07-26T16:54:03.390625+00:00", - "updated_on": "2024-02-29T07:28:30.104891+00:00", - "last_modified_by": "frederik@baserow.io", - "field_1859535": "Vehement Capital Partners", - "field_1859536": [ - 9 + "id": 9415, + "order": "2.33333333333333348136", + "type": "link", + "parent_element_id": null, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": {}, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 10, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 4, + "style_padding_bottom": 10, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "navigation_type": "page", + "navigate_to_page_id": 565, + "page_parameters": [ + { + "name": "project_id", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "get('page_parameter.project_id')" + } + } ], - "field_1859537": "Vehement Capital Partners is a trusted partner in venture capital and private equity investment, offering strategic investment solutions to high-growth companies and entrepreneurs. Our team is dedicated to fostering innovation and driving sustainable growth across various industries. With a focus on strategic partnerships and value creation, Vehement Capital Partners delivers tailored investment solutions to fuel success and unlock potential.", - "field_1859538": "Donna D. Bain", - "field_1859539": "donna@vcp.vc", - "field_1859540": "https://vcp.vc", - "field_1859646": null + "query_parameters": [], + "navigate_to_url": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "target": "self", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "'<- Back to project overview'" + }, + "variant": "link" }, { - "id": 10, - "order": "8.00000000000000000000", - "created_on": "2021-07-26T16:54:03.390666+00:00", - "updated_on": "2024-02-29T07:28:04.146532+00:00", - "last_modified_by": "frederik@baserow.io", - "field_1859535": "Massive Dynamic", - "field_1859536": [ - 10 - ], - "field_1859537": "Massive Dynamic is a dynamic force in the renewable energy sector, offering innovative solutions tailored to meet the growing demand for sustainable energy sources. Our team combines expertise with creativity to develop cutting-edge renewable energy technologies and infrastructure projects. With a focus on sustainability and environmental stewardship, Massive Dynamic leads the way in creating a cleaner, greener future.", - "field_1859538": "Stephanie Lee", - "field_1859539": "stephanielee@massivedynamic.com", - "field_1859540": "https://massivedynamic.com", - "field_1859646": null - } - ] - }, - { - "id": 261764, - "name": "Team", - "order": 5, - "fields": [ + "id": 9416, + "order": "2.50000000000000000000", + "type": "heading", + "parent_element_id": null, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": {}, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 10, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 10, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "concat('Phase: ',get('data_source.1024.field_8979'))" + }, + "level": 2 + }, { - "id": 1859541, + "id": 9430, + "order": "2.50000000000000000000", "type": "text", - "name": "Name", - "order": 0, - "primary": true, - "text_default": "" + "parent_element_id": 9423, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": { + "typography": { + "body_font_size": 12 + } + }, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 10, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 0, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "'ESTIMATED WORKLOAD'" + }, + "format": "plain" }, { - "id": 1859542, - "type": "link_row", - "name": "Lead on projects", - "order": 1, - "primary": false, - "link_row_table_id": 261761, - "link_row_related_field_id": 1859522, - "has_related_field": true + "id": 9431, + "order": "2.50000000000000000000", + "type": "text", + "parent_element_id": 9425, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": { + "typography": { + "body_font_size": 18, + "body_text_color": "ElMaZ", + "body_font_weight": "semi-bold" + } + }, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 10, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 10, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "color", + "style_background_color": "primary", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "'BUDGET'" + }, + "format": "plain" }, { - "id": 1859543, - "type": "link_row", - "name": "Projects served as team member", - "order": 2, - "primary": false, - "link_row_table_id": 261761, - "link_row_related_field_id": 1859523, - "has_related_field": true + "id": 9412, + "order": "3.00000000000000000000", + "type": "column", + "parent_element_id": null, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": {}, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 10, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 10, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "column_amount": 4, + "column_gap": 50, + "alignment": "top" }, { - "id": 1859544, - "type": "link_row", - "name": "Tasks", - "order": 3, - "primary": false, - "link_row_table_id": 261762, - "link_row_related_field_id": 1859532, - "has_related_field": true + "id": 9432, + "order": "3.00000000000000000000", + "type": "text", + "parent_element_id": 9422, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": { + "typography": { + "body_font_weight": "medium", + "body_text_alignment": "right" + } + }, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 0, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 10, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "get('data_source.1024.field_9021')" + }, + "format": "plain" }, { - "id": 1859545, - "type": "single_select", - "name": "Role", - "order": 4, - "primary": false, - "select_options": [ - { - "id": 1386719, - "value": "Designer", - "color": "dark-orange", - "order": 0 - }, - { - "id": 1386720, - "value": "Developer", - "color": "green", - "order": 1 - }, - { - "id": 1386721, - "value": "Manager", - "color": "blue", - "order": 2 - }, - { - "id": 1386722, - "value": "Sales", - "color": "gray", - "order": 3 - }, - { - "id": 1386723, - "value": "Marketer", - "color": "light-red", - "order": 4 + "id": 9433, + "order": "3.00000000000000000000", + "type": "text", + "parent_element_id": 9424, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": { + "typography": { + "body_font_size": 12 } - ] + }, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 10, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 0, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "'NUMBER OF TASKS'" + }, + "format": "plain" }, { - "id": 1859546, - "type": "file", - "name": "Photo", - "order": 5, - "primary": false + "id": 9434, + "order": "3.50000000000000000000", + "type": "text", + "parent_element_id": 9423, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": { + "typography": { + "body_font_weight": "medium", + "body_text_alignment": "right" + } + }, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 0, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 10, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "concat(get('data_source.1024.field_9011'),' hours')" + }, + "format": "plain" }, { - "id": 1859547, - "type": "phone_number", - "name": "Phone number", - "order": 6, - "primary": false + "id": 9435, + "order": "3.50000000000000000000", + "type": "text", + "parent_element_id": 9425, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": { + "typography": { + "body_font_size": 12 + } + }, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 10, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 0, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "'ESTIMATED BUDGET'" + }, + "format": "plain" }, { - "id": 1859548, - "type": "email", - "name": "Email", - "order": 7, - "primary": false + "id": 9417, + "order": "4.00000000000000000000", + "type": "heading", + "parent_element_id": null, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": {}, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 10, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 10, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "'Task overview'" + }, + "level": 3 }, { - "id": 1859549, - "type": "count", - "name": "Tasks count", - "order": 8, - "primary": false, - "date_time_format": null, - "duration_format": null, - "nullable": false, - "error": null, - "date_include_time": null, - "date_show_tzinfo": null, - "date_force_timezone": null, - "number_decimal_places": 0, - "array_formula_type": null, - "date_format": null, - "through_field_id": 1859544 + "id": 9436, + "order": "4.00000000000000000000", + "type": "text", + "parent_element_id": 9422, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": { + "typography": { + "body_font_size": 12 + } + }, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 10, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 0, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "'END OF THE LAST TASK'" + }, + "format": "plain" }, { - "id": 1859550, - "type": "count", - "name": "Projects count", - "order": 9, - "primary": false, - "date_time_format": null, - "duration_format": null, - "nullable": false, - "error": null, - "date_include_time": null, - "date_show_tzinfo": null, - "date_force_timezone": null, - "number_decimal_places": 0, - "array_formula_type": null, - "date_format": null, - "through_field_id": 1859543 - } - ], - "views": [ - { - "id": 437947, - "type": "grid", - "name": "All members", - "order": 1, - "ownership_type": "collaborative", - "owned_by": null, - "filter_type": "AND", - "filters_disabled": false, - "filters": [], - "filter_groups": [], - "sortings": [ - { - "id": 162277, - "field_id": 1859541, - "order": "ASC" - } - ], - "group_bys": [], - "decorations": [], - "public": false, - "row_identifier_type": "id", - "field_options": [ - { - "id": 3032761, - "field_id": 1859546, - "width": 124, - "hidden": false, - "order": 0, - "aggregation_type": "", - "aggregation_raw_type": "" - }, - { - "id": 3032760, - "field_id": 1859545, - "width": 115, - "hidden": false, - "order": 1, - "aggregation_type": "", - "aggregation_raw_type": "" - }, - { - "id": 3032762, - "field_id": 1859547, - "width": 168, - "hidden": false, - "order": 2, - "aggregation_type": "", - "aggregation_raw_type": "" - }, - { - "id": 3032763, - "field_id": 1859548, - "width": 200, - "hidden": false, - "order": 3, - "aggregation_type": "", - "aggregation_raw_type": "" - }, - { - "id": 3032757, - "field_id": 1859542, - "width": 299, - "hidden": false, - "order": 4, - "aggregation_type": "", - "aggregation_raw_type": "" - }, - { - "id": 3032758, - "field_id": 1859543, - "width": 295, - "hidden": false, - "order": 5, - "aggregation_type": "", - "aggregation_raw_type": "" - }, - { - "id": 3032759, - "field_id": 1859544, - "width": 394, - "hidden": false, - "order": 6, - "aggregation_type": "", - "aggregation_raw_type": "" - }, - { - "id": 3032756, - "field_id": 1859541, - "width": 146, - "hidden": false, - "order": 7, - "aggregation_type": "", - "aggregation_raw_type": "" - }, - { - "id": 3032764, - "field_id": 1859549, - "width": 144, - "hidden": false, - "order": 32767, - "aggregation_type": "min", - "aggregation_raw_type": "min" - }, - { - "id": 3032765, - "field_id": 1859550, - "width": 159, - "hidden": false, - "order": 32767, - "aggregation_type": "max", - "aggregation_raw_type": "max" + "id": 9437, + "order": "4.00000000000000000000", + "type": "text", + "parent_element_id": 9424, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": { + "typography": { + "body_font_weight": "medium", + "body_text_alignment": "right" } - ] + }, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 0, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 10, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "get('data_source.1024.field_9017')" + }, + "format": "plain" }, { - "id": 437948, - "type": "grid", - "name": "Experienced", - "order": 2, - "ownership_type": "collaborative", - "owned_by": null, - "filter_type": "AND", - "filters_disabled": false, - "filters": [ - { - "id": 204904, - "field_id": 1859550, - "type": "higher_than", - "value": "1", - "group": null + "id": 9418, + "order": "4.50000000000000000000", + "type": "heading", + "parent_element_id": null, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": {}, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 10, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 10, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "'All tasks'" + }, + "level": 4 + }, + { + "id": 9438, + "order": "4.50000000000000000000", + "type": "text", + "parent_element_id": 9423, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": { + "typography": { + "body_font_size": 12 } - ], - "filter_groups": [], - "sortings": [ - { - "id": 162278, - "field_id": 1859541, - "order": "ASC" + }, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 10, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 0, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "'COMPLETED WORKLOAD'" + }, + "format": "plain" + }, + { + "id": 9439, + "order": "4.50000000000000000000", + "type": "text", + "parent_element_id": 9425, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": { + "typography": { + "body_font_weight": "medium", + "body_text_alignment": "right" } - ], - "group_bys": [], - "decorations": [], - "public": false, - "row_identifier_type": "id", - "field_options": [ - { - "id": 3032771, - "field_id": 1859546, - "width": 102, - "hidden": false, - "order": 0, - "aggregation_type": "", - "aggregation_raw_type": "" - }, - { - "id": 3032770, - "field_id": 1859545, - "width": 118, - "hidden": false, - "order": 1, - "aggregation_type": "", - "aggregation_raw_type": "" - }, - { - "id": 3032772, - "field_id": 1859547, - "width": 160, - "hidden": false, - "order": 2, - "aggregation_type": "", - "aggregation_raw_type": "" - }, - { - "id": 3032773, - "field_id": 1859548, - "width": 200, - "hidden": false, - "order": 3, - "aggregation_type": "", - "aggregation_raw_type": "" + }, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 0, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 10, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "concat('$ ',get('data_source.1024.field_9024'))" + }, + "format": "plain" + }, + { + "id": 9419, + "order": "5.00000000000000000000", + "type": "table", + "parent_element_id": null, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": {}, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 10, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 10, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "data_source_id": 1025, + "items_per_page": 200, + "button_load_more_label": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "schema_property": null, + "property_options": [], + "fields": [ + { + "uid": "da03dcf6-a5e7-466b-84da-589dedce5ee4", + "name": "Icons", + "type": "text", + "styles": {}, + "config": { + "value": { + "mode": "simple", + "version": "0.1", + "formula": "get('current_record.field_9057')" + } + } }, { - "id": 3032768, - "field_id": 1859543, - "width": 282, - "hidden": false, - "order": 4, - "aggregation_type": "", - "aggregation_raw_type": "" + "uid": "d60ed630-78ea-4a28-b3c7-2d076ae960dc", + "name": "Name", + "type": "text", + "styles": {}, + "config": { + "value": { + "mode": "simple", + "version": "0.1", + "formula": "get('current_record.field_8983')" + } + } }, { - "id": 3032767, - "field_id": 1859542, - "width": 168, - "hidden": true, - "order": 5, - "aggregation_type": "", - "aggregation_raw_type": "" + "uid": "de8e7b23-f9df-4cd3-ae16-39d1a110ee1f", + "name": "Status", + "type": "tags", + "styles": {}, + "config": { + "values": { + "mode": "simple", + "version": "0.1", + "formula": "get('current_record.field_8985.value')" + }, + "colors_is_formula": true, + "colors": { + "mode": "simple", + "version": "0.1", + "formula": "get('current_record.field_8985.color')" + } + } }, { - "id": 3032769, - "field_id": 1859544, - "width": 329, - "hidden": false, - "order": 6, - "aggregation_type": "", - "aggregation_raw_type": "" + "uid": "577cbfc2-2428-438b-96f7-881a08138415", + "name": "Priority", + "type": "tags", + "styles": {}, + "config": { + "values": { + "mode": "simple", + "version": "0.1", + "formula": "get('current_record.field_8986.value')" + }, + "colors_is_formula": true, + "colors": { + "mode": "simple", + "version": "0.1", + "formula": "get('current_record.field_8986.color')" + } + } }, { - "id": 3032774, - "field_id": 1859549, - "width": 171, - "hidden": false, - "order": 7, - "aggregation_type": "", - "aggregation_raw_type": "" + "uid": "da2c45f6-bec8-49a2-a1e6-b5f3783feb85", + "name": "Assignee", + "type": "text", + "styles": {}, + "config": { + "value": { + "mode": "simple", + "version": "0.1", + "formula": "get('current_record.field_8987.*.value')" + } + } }, { - "id": 3032775, - "field_id": 1859550, - "width": 200, - "hidden": false, - "order": 8, - "aggregation_type": "", - "aggregation_raw_type": "" + "uid": "92b571db-e96e-4dec-8461-dd08c5b66aa8", + "name": "Start date", + "type": "text", + "styles": {}, + "config": { + "value": { + "mode": "simple", + "version": "0.1", + "formula": "get('current_record.field_8988')" + } + } }, { - "id": 3032766, - "field_id": 1859541, - "width": 156, - "hidden": false, - "order": 9, - "aggregation_type": "", - "aggregation_raw_type": "" + "uid": "1dddf3b7-f800-466c-9ee4-3a1de7d69b37", + "name": "Due date", + "type": "text", + "styles": {}, + "config": { + "value": { + "mode": "simple", + "version": "0.1", + "formula": "get('current_record.field_8989')" + } + } } - ] + ], + "orientation": { + "tablet": "horizontal", + "desktop": "horizontal", + "smartphone": "horizontal" + } }, { - "id": 437949, - "type": "form", - "name": "New team member", - "order": 3, - "ownership_type": "collaborative", - "owned_by": null, - "public": false, - "title": "New team member", - "description": "Include all information here", - "cover_image": null, - "logo_image": { - "name": "esP6hUf6rKb5PnPZqtCSKGrq2tDJJeqi_40464fe9e3131c0612d982478830ea9ca15e82c09b91cf906e646eeefb63e36e.jpeg", - "original_name": "team.jpeg" + "id": 9440, + "order": "5.00000000000000000000", + "type": "text", + "parent_element_id": 9422, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" }, - "submit_text": "Submit", - "submit_action": "MESSAGE", - "submit_action_message": "Welcome to the team!", - "submit_action_redirect_url": "", - "field_options": [ - { - "id": 338966, - "field_id": 1859541, - "name": "", - "description": "", - "enabled": true, - "required": true, - "order": 32767, - "show_when_matching_conditions": false, - "condition_type": "AND", - "conditions": [], - "field_component": "default" - }, - { - "id": 338967, - "field_id": 1859542, - "name": "", - "description": "", - "enabled": false, - "required": true, - "order": 32767, - "show_when_matching_conditions": false, - "condition_type": "AND", - "conditions": [], - "field_component": "default" - }, - { - "id": 338968, - "field_id": 1859543, - "name": "", - "description": "", - "enabled": false, - "required": true, - "order": 32767, - "show_when_matching_conditions": false, - "condition_type": "AND", - "conditions": [], - "field_component": "default" - }, - { - "id": 338969, - "field_id": 1859544, - "name": "", - "description": "", - "enabled": false, - "required": true, - "order": 32767, - "show_when_matching_conditions": false, - "condition_type": "AND", - "conditions": [], - "field_component": "default" + "role_type": "allow_all", + "roles": [], + "styles": { + "typography": { + "body_font_weight": "medium", + "body_text_alignment": "right" + } + }, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 0, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 10, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "get('data_source.1024.field_9022')" + }, + "format": "plain" + }, + { + "id": 9441, + "order": "5.00000000000000000000", + "type": "text", + "parent_element_id": 9424, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": { + "typography": { + "body_font_size": 12 + } + }, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 10, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 0, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "'COMPLETED TASKS'" + }, + "format": "plain" + }, + { + "id": 9442, + "order": "5.50000000000000000000", + "type": "text", + "parent_element_id": 9423, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": { + "typography": { + "body_font_weight": "medium", + "body_text_alignment": "right" + } + }, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 0, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 10, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "concat(get('data_source.1024.field_9014'),' hours')" + }, + "format": "plain" + }, + { + "id": 9443, + "order": "5.50000000000000000000", + "type": "text", + "parent_element_id": 9425, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": { + "typography": { + "body_font_size": 12 + } + }, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 10, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 0, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "'ACUTAL EXPENSES'" + }, + "format": "plain" + }, + { + "id": 9444, + "order": "5.50000000000000000000", + "type": "iframe", + "parent_element_id": 9422, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": {}, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 0, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 0, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 0, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 0, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "source_type": "embed", + "url": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "embed": { + "mode": "simple", + "version": "0.1", + "formula": "concat('','\n',concat(''))" + }, + "height": 14 + }, + { + "id": 9420, + "order": "6.00000000000000000000", + "type": "heading", + "parent_element_id": null, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": {}, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 10, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 10, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "'Overdue tasks'" + }, + "level": 4 + }, + { + "id": 9445, + "order": "6.00000000000000000000", + "type": "text", + "parent_element_id": 9422, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": { + "typography": { + "body_font_size": 30, + "body_text_color": "secondary", + "body_font_weight": "bold", + "body_text_alignment": "center" + } + }, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 10, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 10, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "advanced", + "version": "0.1", + "formula": "concat(round(get('data_source.1024.field_9038'),0),'%')" + }, + "format": "plain" + }, + { + "id": 9446, + "order": "6.00000000000000000000", + "type": "text", + "parent_element_id": 9424, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": { + "typography": { + "body_font_weight": "medium", + "body_text_alignment": "right" + } + }, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 0, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 10, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "get('data_source.1024.field_9015')" + }, + "format": "plain" + }, + { + "id": 9447, + "order": "6.00000000000000000000", + "type": "iframe", + "parent_element_id": 9423, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": {}, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 0, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 0, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 0, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 0, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "source_type": "embed", + "url": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "embed": { + "mode": "simple", + "version": "0.1", + "formula": "concat('','\n','','\n',concat(''))" + }, + "height": 14 + }, + { + "id": 9421, + "order": "7.00000000000000000000", + "type": "table", + "parent_element_id": null, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": {}, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 10, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 10, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "data_source_id": 1026, + "items_per_page": 20, + "button_load_more_label": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "schema_property": null, + "property_options": [], + "fields": [ + { + "uid": "ef0782f9-ded4-4fea-afe9-98ac2a053733", + "name": "Name", + "type": "text", + "styles": {}, + "config": { + "value": { + "mode": "simple", + "version": "0.1", + "formula": "get('current_record.field_8983')" + } + } }, { - "id": 338970, - "field_id": 1859545, - "name": "", - "description": "", - "enabled": true, - "required": true, - "order": 32767, - "show_when_matching_conditions": false, - "condition_type": "AND", - "conditions": [], - "field_component": "default" + "uid": "054cfcbe-ca81-4cf8-9934-d0a1636d592d", + "name": "Status", + "type": "text", + "styles": {}, + "config": { + "value": { + "mode": "simple", + "version": "0.1", + "formula": "get('current_record.field_8985.value')" + } + } }, { - "id": 338971, - "field_id": 1859546, - "name": "", - "description": "", - "enabled": false, - "required": true, - "order": 32767, - "show_when_matching_conditions": false, - "condition_type": "AND", - "conditions": [], - "field_component": "default" + "uid": "d2cb572a-49cb-4467-ab1c-2b8a9f3536a5", + "name": "Priority", + "type": "text", + "styles": {}, + "config": { + "value": { + "mode": "simple", + "version": "0.1", + "formula": "get('current_record.field_8986.value')" + } + } }, { - "id": 338972, - "field_id": 1859547, - "name": "", - "description": "", - "enabled": true, - "required": true, - "order": 32767, - "show_when_matching_conditions": false, - "condition_type": "AND", - "conditions": [], - "field_component": "default" + "uid": "13dea972-08d7-4049-a6a2-30cdd1d1ee6b", + "name": "Assignee", + "type": "text", + "styles": {}, + "config": { + "value": { + "mode": "simple", + "version": "0.1", + "formula": "get('current_record.field_8987.*.value')" + } + } }, { - "id": 338973, - "field_id": 1859548, - "name": "", - "description": "", - "enabled": true, - "required": true, - "order": 32767, - "show_when_matching_conditions": false, - "condition_type": "AND", - "conditions": [], - "field_component": "default" + "uid": "869d61a8-7c65-4a0e-8ab2-4b195c3a94b3", + "name": "Start date", + "type": "text", + "styles": {}, + "config": { + "value": { + "mode": "simple", + "version": "0.1", + "formula": "get('current_record.field_8988')" + } + } }, { - "id": 338974, - "field_id": 1859549, - "name": "", - "description": "", - "enabled": false, - "required": true, - "order": 32767, - "show_when_matching_conditions": false, - "condition_type": "AND", - "conditions": [], - "field_component": "default" + "uid": "75a27971-a84c-4a5e-a4cd-cfde437f0aef", + "name": "Due date", + "type": "text", + "styles": {}, + "config": { + "value": { + "mode": "simple", + "version": "0.1", + "formula": "get('current_record.field_8989')" + } + } }, - { - "id": 338975, - "field_id": 1859550, - "name": "", - "description": "", - "enabled": false, - "required": true, - "order": 32767, - "show_when_matching_conditions": false, - "condition_type": "AND", - "conditions": [], - "field_component": "default" + { + "uid": "ec7f5a15-ace6-4e76-abf2-792220819deb", + "name": "Overdue", + "type": "text", + "styles": {}, + "config": { + "value": { + "mode": "advanced", + "version": "0.1", + "formula": "replace(get('current_record.field_9023'),'-','')" + } + } } - ] + ], + "orientation": { + "tablet": "horizontal", + "desktop": "horizontal", + "smartphone": "horizontal" + } + }, + { + "id": 9448, + "order": "7.00000000000000000000", + "type": "text", + "parent_element_id": 9423, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": { + "typography": { + "body_font_size": 30, + "body_text_color": "secondary", + "body_font_weight": "bold", + "body_text_alignment": "center" + } + }, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 10, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 10, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "advanced", + "version": "0.1", + "formula": "concat(round(get('data_source.1024.field_9032'),0),'%')" + }, + "format": "plain" + }, + { + "id": 9449, + "order": "7.00000000000000000000", + "type": "text", + "parent_element_id": 9425, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": { + "typography": { + "body_font_weight": "medium", + "body_text_alignment": "right" + } + }, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 0, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 10, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "concat('$ ',get('data_source.1024.field_9025'))" + }, + "format": "plain" + }, + { + "id": 9450, + "order": "7.00000000000000000000", + "type": "iframe", + "parent_element_id": 9424, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": {}, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 0, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 0, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "source_type": "embed", + "url": { + "mode": "simple", + "version": "0.1", + "formula": "concat('','\n',concat(''))" + }, + "embed": { + "mode": "simple", + "version": "0.1", + "formula": "concat('','\n',concat(''))" + }, + "height": 14 + }, + { + "id": 9451, + "order": "8.00000000000000000000", + "type": "iframe", + "parent_element_id": 9425, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": {}, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 0, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 1, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "source_type": "embed", + "url": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "embed": { + "mode": "simple", + "version": "0.1", + "formula": "concat('','\n',concat(''))" + }, + "height": 14 + }, + { + "id": 9452, + "order": "8.00000000000000000000", + "type": "text", + "parent_element_id": 9424, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": { + "typography": { + "body_font_size": 30, + "body_text_color": "secondary", + "body_font_weight": "bold", + "body_text_alignment": "center" + } + }, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 10, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 10, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "advanced", + "version": "0.1", + "formula": "concat(round(get('data_source.1024.field_9034'),0),'%')" + }, + "format": "plain" + }, + { + "id": 9453, + "order": "9.00000000000000000000", + "type": "text", + "parent_element_id": 9425, + "place_in_container": null, + "css_classes": "", + "visibility": "all", + "visibility_condition": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "role_type": "allow_all", + "roles": [], + "styles": { + "typography": { + "body_font_size": 30, + "body_text_color": "secondary", + "body_font_weight": "bold", + "body_text_alignment": "center" + } + }, + "style_border_top_color": "border", + "style_border_top_size": 0, + "style_padding_top": 10, + "style_margin_top": 0, + "style_border_bottom_color": "border", + "style_border_bottom_size": 0, + "style_padding_bottom": 10, + "style_margin_bottom": 0, + "style_border_left_color": "border", + "style_border_left_size": 0, + "style_padding_left": 20, + "style_margin_left": 0, + "style_border_right_color": "border", + "style_border_right_size": 0, + "style_padding_right": 20, + "style_margin_right": 0, + "style_background_radius": 0, + "style_border_radius": 0, + "style_background": "none", + "style_background_color": "#ffffffff", + "style_background_file_id": null, + "style_background_mode": "fill", + "style_width": "normal", + "style_width_child": "normal", + "value": { + "mode": "advanced", + "version": "0.1", + "formula": "concat(round(get('data_source.1024.field_9042'),0),'%')" + }, + "format": "plain" } ], - "rows": [ + "data_sources": [ { - "id": 1, + "id": 1023, + "name": "Project details", "order": "1.00000000000000000000", - "created_on": "2021-07-26T16:54:03.404791+00:00", - "updated_on": "2022-05-22T23:36:52.345346+00:00", - "field_1859541": "Gordon Brickhouse", - "field_1859542": [ - 8 - ], - "field_1859543": [ - 3, - 5, - 6, - 7 - ], - "field_1859544": [ - 3, - 5, - 9, - 13, - 14, - 15, - 16, - 17 - ], - "field_1859545": 1386719, - "field_1859546": [ - { - "name": "ri6hhJKcnVNZj5cZ5X1eFUTBS8iO4xfe_49b76e923ba3a5b7452bed27343306fbd2f721263ec75b47f789fe5bef70d4de.jpeg", - "visible_name": "man2.jpeg", - "original_name": "ri6hhJKcnVNZj5cZ5X1eFUTBS8iO4xfe_49b76e923ba3a5b7452bed27343306fbd2f721263ec75b47f789fe5bef70d4de.jpeg" + "service": { + "id": 1893, + "integration_id": 192, + "type": "local_baserow_get_row", + "sample_data": null, + "table_id": 955, + "view_id": null, + "search_query": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "filter_type": "AND", + "filters": [], + "row_id": { + "mode": "simple", + "version": "0.1", + "formula": "get('page_parameter.project_id')" } - ], - "field_1859547": "(803) 996-6704", - "field_1859548": "gordonb@company.com", - "field_1859549": null, - "field_1859550": null + } }, { - "id": 2, + "id": 1024, + "name": "Phase details", "order": "2.00000000000000000000", - "created_on": "2021-07-26T16:54:03.405008+00:00", - "updated_on": "2022-05-22T23:37:02.941157+00:00", - "field_1859541": "Susan R. Glaze", - "field_1859542": [], - "field_1859543": [ - 3, - 10 - ], - "field_1859544": [ - 4, - 6, - 7 - ], - "field_1859545": 1386723, - "field_1859546": [ - { - "name": "h7Z13FOfXzHfBe5v5rjmzfu9QWLFNUTa_85aef1679043f58fa55c51346e8c5d3b81b3b9464276029dd8972c57d43cd8bd.jpeg", - "visible_name": "man5.jpeg", - "original_name": "h7Z13FOfXzHfBe5v5rjmzfu9QWLFNUTa_85aef1679043f58fa55c51346e8c5d3b81b3b9464276029dd8972c57d43cd8bd.jpeg" + "service": { + "id": 1894, + "integration_id": 192, + "type": "local_baserow_get_row", + "sample_data": null, + "table_id": 956, + "view_id": null, + "search_query": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "filter_type": "AND", + "filters": [], + "row_id": { + "mode": "simple", + "version": "0.1", + "formula": "get('page_parameter.phase_id')" } - ], - "field_1859547": "(317) 996-2721", - "field_1859548": "susanglaze@company.com", - "field_1859549": null, - "field_1859550": null + } }, { - "id": 3, + "id": 1025, + "name": "Related tasks", "order": "3.00000000000000000000", - "created_on": "2021-07-26T16:54:03.405114+00:00", - "updated_on": "2022-05-22T23:36:56.177992+00:00", - "field_1859541": "Kimberly Wagner", - "field_1859542": [ - 3, - 4, - 6 - ], - "field_1859543": [ - 9 - ], - "field_1859544": [ - 10 - ], - "field_1859545": 1386721, - "field_1859546": [ - { - "name": "DVM8xBLlQHvEeMRZxTf1ELoH3pci5z0O_9bec6d7b525a459bff816b1fbce8918044728bf6bcdac33dd7cde869a5897b8e.jpeg", - "visible_name": "woman2.jpeg", - "original_name": "DVM8xBLlQHvEeMRZxTf1ELoH3pci5z0O_9bec6d7b525a459bff816b1fbce8918044728bf6bcdac33dd7cde869a5897b8e.jpeg" - } - ], - "field_1859547": "(406) 892-0740", - "field_1859548": "kimberly@company.com", - "field_1859549": null, - "field_1859550": null + "service": { + "id": 1895, + "integration_id": 192, + "type": "local_baserow_list_rows", + "sample_data": null, + "table_id": 957, + "view_id": 3996, + "sortings": [], + "search_query": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "filter_type": "AND", + "filters": [ + { + "field_id": 8991, + "type": "link_row_has", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "get('page_parameter.phase_id')" + }, + "value_is_formula": true + } + ], + "default_result_count": 20 + } }, { - "id": 4, + "id": 1026, + "name": "Overdue tasks", "order": "4.00000000000000000000", - "created_on": "2021-07-26T16:54:03.405181+00:00", - "updated_on": "2022-05-22T23:36:49.092342+00:00", - "field_1859541": "Donn Moore", - "field_1859542": [], - "field_1859543": [ - 4, - 6 - ], - "field_1859544": [ - 24, - 25, - 26, - 27, - 23 - ], - "field_1859545": 1386722, - "field_1859546": [ - { - "name": "3GqVQbf5DcaQLe7ei9fure9DH4lHuTru_4d7034577c7c8aec543493baf40841b6f7e7feb5134c6f1257f46acf4626d050.jpeg", - "visible_name": "man1.jpeg", - "original_name": "3GqVQbf5DcaQLe7ei9fure9DH4lHuTru_4d7034577c7c8aec543493baf40841b6f7e7feb5134c6f1257f46acf4626d050.jpeg" - } - ], - "field_1859547": "(508) 398-0845", - "field_1859548": "donnmoore@company.com", - "field_1859549": null, - "field_1859550": null + "service": { + "id": 1896, + "integration_id": 192, + "type": "local_baserow_list_rows", + "sample_data": null, + "table_id": 957, + "view_id": 3996, + "sortings": [], + "search_query": { + "mode": "simple", + "version": "0.1", + "formula": "" + }, + "filter_type": "AND", + "filters": [ + { + "field_id": 8991, + "type": "link_row_has", + "value": { + "mode": "simple", + "version": "0.1", + "formula": "get('page_parameter.phase_id')" + }, + "value_is_formula": true + }, + { + "field_id": 9039, + "type": "not_empty", + "value": { + "mode": "raw", + "version": "0.1", + "formula": "" + }, + "value_is_formula": false + } + ], + "default_result_count": 20 + } + } + ], + "workflow_actions": [], + "visibility": "all", + "role_type": "allow_all", + "roles": [] + } + ], + "integrations": [ + { + "id": 192, + "name": "Local Baserow", + "order": "1.00000000000000000000", + "type": "local_baserow", + "authorized_user": null + } + ], + "theme": { + "primary_color": "#4e5cfe", + "secondary_color": "#2bc3f1", + "border_color": "#ededed", + "main_success_color": "#12d452", + "main_warning_color": "#ffd269", + "main_error_color": "#ff5a44", + "custom_colors": [ + { + "name": "Custom 1", + "color": "#ffffff", + "value": "ElMaZ" + }, + { + "name": "Custom 2", + "color": "#202128", + "value": "zoOtT" + }, + { + "name": "Custom 3", + "color": "#6a6b70", + "value": "V6EVv" + } + ], + "body_font_family": "inter", + "body_font_size": 14, + "body_font_weight": "regular", + "body_text_color": "zoOtT", + "body_text_alignment": "left", + "heading_1_font_family": "inter", + "heading_1_font_size": 32, + "heading_1_font_weight": "bold", + "heading_1_text_color": "zoOtT", + "heading_1_text_alignment": "left", + "heading_1_text_decoration": [ + false, + false, + false, + false + ], + "heading_2_font_family": "inter", + "heading_2_font_size": 24, + "heading_2_font_weight": "bold", + "heading_2_text_color": "zoOtT", + "heading_2_text_alignment": "left", + "heading_2_text_decoration": [ + false, + false, + false, + false + ], + "heading_3_font_family": "inter", + "heading_3_font_size": 24, + "heading_3_font_weight": "semi-bold", + "heading_3_text_color": "zoOtT", + "heading_3_text_alignment": "left", + "heading_3_text_decoration": [ + false, + false, + false, + false + ], + "heading_4_font_family": "inter", + "heading_4_font_size": 20, + "heading_4_font_weight": "semi-bold", + "heading_4_text_color": "zoOtT", + "heading_4_text_alignment": "left", + "heading_4_text_decoration": [ + false, + false, + false, + false + ], + "heading_5_font_family": "inter", + "heading_5_font_size": 16, + "heading_5_font_weight": "semi-bold", + "heading_5_text_color": "zoOtT", + "heading_5_text_alignment": "left", + "heading_5_text_decoration": [ + false, + false, + false, + false + ], + "heading_6_font_family": "inter", + "heading_6_font_size": 14, + "heading_6_font_weight": "semi-bold", + "heading_6_text_color": "zoOtT", + "heading_6_text_alignment": "left", + "heading_6_text_decoration": [ + false, + false, + false, + false + ], + "button_font_family": "inter", + "button_font_size": 12, + "button_font_weight": "semi-bold", + "button_alignment": "left", + "button_text_alignment": "center", + "button_width": "auto", + "button_background_color": "primary", + "button_text_color": "ElMaZ", + "button_border_color": "border", + "button_border_size": 0, + "button_border_radius": 6, + "button_vertical_padding": 10, + "button_horizontal_padding": 12, + "button_hover_background_color": "#4653e5", + "button_hover_text_color": "ElMaZ", + "button_hover_border_color": "border", + "button_active_background_color": "primary", + "button_active_text_color": "ElMaZ", + "button_active_border_color": "border", + "image_alignment": "left", + "image_max_width": 100, + "image_max_height": null, + "image_border_radius": 0, + "image_constraint": "contain", + "page_background_color": "#fafafa", + "page_background_file_id": null, + "page_background_mode": "tile", + "label_font_family": "inter", + "label_text_color": "zoOtT", + "label_font_size": 13, + "label_font_weight": "medium", + "input_font_family": "inter", + "input_font_size": 14, + "input_font_weight": "regular", + "input_text_color": "zoOtT", + "input_background_color": "#ffffff", + "input_border_color": "#d7d8d9", + "input_border_size": 1, + "input_border_radius": 6, + "input_vertical_padding": 12, + "input_horizontal_padding": 16, + "table_border_color": "border", + "table_border_size": 1, + "table_border_radius": 6, + "table_header_background_color": "#f7f7f7", + "table_header_text_color": "V6EVv", + "table_header_font_size": 13, + "table_header_font_weight": "semi-bold", + "table_header_font_family": "inter", + "table_header_text_alignment": "left", + "table_cell_background_color": "ElMaZ", + "table_cell_alternate_background_color": "ElMaZ", + "table_cell_alignment": "left", + "table_cell_vertical_padding": 18, + "table_cell_horizontal_padding": 24, + "table_vertical_separator_color": "#000000FF", + "table_vertical_separator_size": 0, + "table_horizontal_separator_color": "border", + "table_horizontal_separator_size": 1, + "link_font_family": "inter", + "link_font_size": 14, + "link_font_weight": "regular", + "link_text_alignment": "left", + "link_text_color": "primary", + "link_hover_text_color": "#4653e5", + "link_active_text_color": "primary", + "link_default_text_decoration": [ + true, + false, + false, + false + ], + "link_hover_text_decoration": [ + true, + false, + false, + false + ], + "link_active_text_decoration": [ + true, + false, + false, + false + ] + }, + "user_sources": [], + "favicon_file": null, + "login_page": null, + "id": 343, + "name": "Dashboard", + "order": 2, + "type": "builder", + "scripts": [], + "custom_code": { + "css": "", + "js": "" + } + }, + { + "workflows": [ + { + "id": 52, + "name": "Set completion date", + "order": 1, + "nodes": [ + { + "id": 548, + "type": "local_baserow_rows_updated", + "label": "", + "service": { + "id": 1897, + "integration_id": 193, + "type": "local_baserow_rows_updated", + "sample_data": { + "data": { + "results": [ + { + "id": 5, + "Name": "Build sales pipeline", + "Icons": "\u26d4", + "Phase": [ + { + "id": 2, + "order": "2.00000000000000000000", + "value": "Core CRM Implemented" + } + ], + "order": "5.00000000000000000000", + "Status": { + "id": 3360, + "color": "light-green", + "value": "Done" + }, + "Project": [ + { + "id": 1, + "order": "1.00000000000000000000", + "value": "CRM System Upgrade" + } + ], + "Subtask": { + "url": "https://your-baserow-instance/form/Fs4SSZ0qA78L0_JAMcY4NcPFJf4RDjoSGSvwt0EhXfY?prefill_Task=Build%20sales%20pipeline&prefill_Start%20time=2026-04-01%2012:20", + "label": "Add new subtask" + }, + "Assignee": [ + { + "id": 14, + "order": "14.00000000000000000000", + "value": "Lane Mahon" + } + ], + "Due date": "2026-03-20", + "Priority": { + "id": 3362, + "color": "dark-yellow", + "value": "High" + }, + "Subtasks": [], + "Blocked by": [ + { + "id": 4, + "value": "Build customer module" + } + ], + "Depends on": [ + { + "id": 4, + "order": "4.00000000000000000000", + "value": "Build customer module" + } + ], + "Start date": "2026-03-04", + "Budget icon": "", + "Description": "Create deals and stages", + "Blocked icon": "\u26d4", + "Overdue icon": "", + "Task duration": 1468800.0, + "Actual expenses": 6800, + "Completion date": null, + "Difference icon": "", + "Estimated budget": 7000, + "Budget difference": "200", + "Estimated workload": 10, + "Days until due date": "0", + "Registered workload": 0.0, + "Workload difference": -36000.0 + } + ], + "has_next_page": false + }, + "status": 200, + "output_uid": "" + }, + "table_id": 957 + }, + "workflow_id": 52 }, { - "id": 5, - "order": "5.00000000000000000000", - "created_on": "2021-07-26T16:54:03.405252+00:00", - "updated_on": "2022-05-22T23:37:01.037969+00:00", - "field_1859541": "Steve Gray", - "field_1859542": [], - "field_1859543": [ - 5, - 8 - ], - "field_1859544": [ - 8, - 12, - 22, - 18, - 11 - ], - "field_1859545": 1386720, - "field_1859546": [ - { - "name": "wCPnfnenpWTYkAoOrwDCw1axYMj8SCFQ_801ea1dea381e8ce4c413449fd9228598a55dd6509f1ff8a21bc24aa7273d6d2.jpeg", - "visible_name": "man4.jpeg", - "original_name": "wCPnfnenpWTYkAoOrwDCw1axYMj8SCFQ_801ea1dea381e8ce4c413449fd9228598a55dd6509f1ff8a21bc24aa7273d6d2.jpeg" + "id": 549, + "type": "iterator", + "label": "Loop over updates tasks", + "service": { + "id": 1898, + "integration_id": null, + "type": "iterator", + "sample_data": { + "data": { + "results": [ + { + "id": 5, + "Name": "Build sales pipeline", + "Icons": "\u26d4", + "Phase": [ + { + "id": 2, + "order": "2.00000000000000000000", + "value": "Core CRM Implemented" + } + ], + "order": "5.00000000000000000000", + "Status": { + "id": 3360, + "color": "light-green", + "value": "Done" + }, + "Project": [ + { + "id": 1, + "order": "1.00000000000000000000", + "value": "CRM System Upgrade" + } + ], + "Subtask": { + "url": "https://your-baserow-instance/form/Fs4SSZ0qA78L0_JAMcY4NcPFJf4RDjoSGSvwt0EhXfY?prefill_Task=Build%20sales%20pipeline&prefill_Start%20time=2026-04-01%2012:20", + "label": "Add new subtask" + }, + "Assignee": [ + { + "id": 14, + "order": "14.00000000000000000000", + "value": "Lane Mahon" + } + ], + "Due date": "2026-03-20", + "Priority": { + "id": 3362, + "color": "dark-yellow", + "value": "High" + }, + "Subtasks": [], + "Blocked by": [ + { + "id": 4, + "value": "Build customer module" + } + ], + "Depends on": [ + { + "id": 4, + "order": "4.00000000000000000000", + "value": "Build customer module" + } + ], + "Start date": "2026-03-04", + "Budget icon": "", + "Description": "Create deals and stages", + "Blocked icon": "\u26d4", + "Overdue icon": "", + "Task duration": 1468800.0, + "Actual expenses": 6800, + "Completion date": null, + "Difference icon": "", + "Estimated budget": 7000, + "Budget difference": "200", + "Estimated workload": 10, + "Days until due date": "0", + "Registered workload": 0.0, + "Workload difference": -36000.0 + } + ], + "has_next_page": false + }, + "status": 200, + "output_uid": "" + }, + "source": { + "mode": "simple", + "version": "0.1", + "formula": "get('previous_node.548')" } - ], - "field_1859547": "(541) 884-3680", - "field_1859548": "stevegray@company.com", - "field_1859549": null, - "field_1859550": null + }, + "workflow_id": 52 }, { - "id": 6, - "order": "6.00000000000000000000", - "created_on": "2021-07-26T16:54:03.405320+00:00", - "updated_on": "2022-05-22T23:36:58.738344+00:00", - "field_1859541": "Janet Cook", - "field_1859542": [ - 5, - 8 - ], - "field_1859543": [ - 8 - ], - "field_1859544": [ - 19, - 20, - 21 - ], - "field_1859545": 1386720, - "field_1859546": [ - { - "name": "CdKzGQbskhs9dnVQMXXYteecwbY0aTAc_617eb2585bd65586c5b4d5d71de856b73a53c06f1d82abb8c25d75e7c038505d.jpeg", - "visible_name": "janetcook", - "original_name": "CdKzGQbskhs9dnVQMXXYteecwbY0aTAc_617eb2585bd65586c5b4d5d71de856b73a53c06f1d82abb8c25d75e7c038505d.jpeg" + "id": 550, + "type": "router", + "label": "Check date and status", + "service": { + "id": 1899, + "integration_id": null, + "type": "router", + "sample_data": { + "data": { + "edge": { + "label": "Needs update" + } + }, + "status": 200, + "output_uid": "7cf53010-8299-4639-ab59-0d387e2f5f19" + }, + "edges": [ + { + "label": "Needs update", + "uid": "f7651fb3-8fe4-4136-9da5-2f14e9566a3c", + "condition": { + "mode": "advanced", + "version": "0.1", + "formula": "get('current_iteration.549.item.Status.value') = 'Done'" + } + } + ], + "default_edge_label": "" + }, + "workflow_id": 52 + }, + { + "id": 551, + "type": "local_baserow_update_row", + "label": "Set completion date", + "service": { + "id": 1900, + "integration_id": 193, + "type": "local_baserow_upsert_row", + "sample_data": { + "data": { + "id": 5, + "Name": "Build sales pipeline", + "Icons": "\u26d4", + "Phase": [ + { + "id": 2, + "order": "2.00000000000000000000", + "value": "Core CRM Implemented" + } + ], + "order": "5.00000000000000000000", + "Status": { + "id": 3360, + "color": "light-green", + "value": "Done" + }, + "Project": [ + { + "id": 1, + "order": "1.00000000000000000000", + "value": "CRM System Upgrade" + } + ], + "Subtask": { + "url": "https://your-baserow-instance/form/Fs4SSZ0qA78L0_JAMcY4NcPFJf4RDjoSGSvwt0EhXfY?prefill_Task=Build%20sales%20pipeline&prefill_Start%20time=2026-04-01%2012:20", + "label": "Add new subtask" + }, + "Assignee": [ + { + "id": 14, + "order": "14.00000000000000000000", + "value": "Lane Mahon" + } + ], + "Due date": "2026-03-20", + "Priority": { + "id": 3362, + "color": "dark-yellow", + "value": "High" + }, + "Subtasks": [], + "Blocked by": [ + { + "id": 4, + "value": "Build customer module" + } + ], + "Depends on": [ + { + "id": 4, + "order": "4.00000000000000000000", + "value": "Build customer module" + } + ], + "Start date": "2026-03-04", + "Budget icon": "", + "Description": "Create deals and stages", + "Blocked icon": "\u26d4", + "Overdue icon": "", + "Task duration": 1468800.0, + "Actual expenses": 6800, + "Completion date": "2026-04-01", + "Difference icon": "", + "Estimated budget": 7000, + "Budget difference": "200", + "Estimated workload": 10, + "Days until due date": "0", + "Registered workload": 0.0, + "Workload difference": -36000.0 + }, + "status": 200, + "output_uid": "" + }, + "table_id": 957, + "row_id": { + "mode": "simple", + "version": "0.1", + "formula": "get('current_iteration.549.item.id')" + }, + "field_mappings": [ + { + "field_id": 8990, + "value": { + "mode": "advanced", + "version": "0.1", + "formula": "today()" + }, + "enabled": true + } + ] + }, + "workflow_id": 52 + } + ], + "state": "draft", + "graph": { + "0": 548, + "548": { + "next": { + "": [ + 549 + ] + } + }, + "549": { + "children": [ + 550 + ] + }, + "550": { + "next": { + "f7651fb3-8fe4-4136-9da5-2f14e9566a3c": [ + 551 + ] + } + }, + "551": {} + } + }, + { + "id": 53, + "name": "Close subtask", + "order": 2, + "nodes": [ + { + "id": 552, + "type": "local_baserow_rows_updated", + "label": "", + "service": { + "id": 1901, + "integration_id": 193, + "type": "local_baserow_rows_updated", + "sample_data": { + "data": { + "results": [ + { + "id": 26, + "Name": "This is a test", + "Task": [ + { + "id": 1, + "order": "1.00000000000000000000", + "value": "Define CRM entities" + } + ], + "Notes": "", + "order": "13.00000000000000000000", + "Assignee": [ + { + "ids": { + "database_table_878": 2, + "database_table_883": 1 + }, + "value": "Bran Lopez" + } + ], + "Duration": 880.426132, + "End time": "2026-04-01T07:54:40.426132Z", + "Completed": false, + "Start time": "2026-04-01T07:40:00Z" + } + ], + "has_next_page": false + }, + "status": 200, + "output_uid": "" + }, + "table_id": 958 + }, + "workflow_id": 53 + }, + { + "id": 553, + "type": "iterator", + "label": "Loop over updated subtasks", + "service": { + "id": 1902, + "integration_id": null, + "type": "iterator", + "sample_data": { + "data": { + "results": [ + { + "id": 26, + "Name": "This is a test", + "Task": [ + { + "id": 1, + "order": "1.00000000000000000000", + "value": "Define CRM entities" + } + ], + "Notes": "", + "order": "13.00000000000000000000", + "Assignee": [ + { + "ids": { + "database_table_878": 2, + "database_table_883": 1 + }, + "value": "Bran Lopez" + } + ], + "Duration": 880.426132, + "End time": "2026-04-01T07:54:40.426132Z", + "Completed": false, + "Start time": "2026-04-01T07:40:00Z" + } + ], + "has_next_page": false + }, + "status": 200, + "output_uid": "" + }, + "source": { + "mode": "simple", + "version": "0.1", + "formula": "get('previous_node.552')" } - ], - "field_1859547": "(269) 445-2068", - "field_1859548": "janetcook@company.com", - "field_1859549": null, - "field_1859550": null + }, + "workflow_id": 53 + }, + { + "id": 554, + "type": "router", + "label": "Check completed", + "service": { + "id": 1903, + "integration_id": null, + "type": "router", + "sample_data": { + "data": { + "edge": { + "label": "Completed unchecked" + } + }, + "status": 200, + "output_uid": "" + }, + "edges": [ + { + "label": "Completed checked", + "uid": "8d274166-8d9e-4223-a5df-db6380e0573b", + "condition": { + "mode": "advanced", + "version": "0.1", + "formula": "get('current_iteration.553.item.Completed')" + } + } + ], + "default_edge_label": "Completed unchecked" + }, + "workflow_id": 53 + }, + { + "id": 555, + "type": "local_baserow_update_row", + "label": "Set end date", + "service": { + "id": 1904, + "integration_id": 193, + "type": "local_baserow_upsert_row", + "sample_data": { + "data": { + "id": 26, + "Name": "This is a test", + "Task": [ + { + "id": 1, + "order": "1.00000000000000000000", + "value": "Define CRM entities" + } + ], + "Notes": "", + "order": "13.00000000000000000000", + "Assignee": [ + { + "ids": { + "database_table_878": 2, + "database_table_883": 1 + }, + "value": "Bran Lopez" + } + ], + "Duration": 785.557031, + "End time": "2026-04-01T07:53:05.557031Z", + "Completed": false, + "Start time": "2026-04-01T07:40:00Z" + }, + "status": 200, + "output_uid": "" + }, + "table_id": 958, + "row_id": { + "mode": "simple", + "version": "0.1", + "formula": "get('current_iteration.553.item.id')" + }, + "field_mappings": [ + { + "field_id": 9002, + "value": { + "mode": "advanced", + "version": "0.1", + "formula": "now()" + }, + "enabled": true + } + ] + }, + "workflow_id": 53 } - ] + ], + "state": "draft", + "graph": { + "0": 552, + "552": { + "next": { + "": [ + 553 + ] + } + }, + "553": { + "children": [ + 554 + ] + }, + "554": { + "next": { + "8d274166-8d9e-4223-a5df-db6380e0573b": [ + 555 + ] + } + }, + "555": {} + } } - ] + ], + "integrations": [ + { + "id": 193, + "name": "Local Baserow", + "order": "1.00000000000000000000", + "type": "local_baserow", + "authorized_user": null + } + ], + "id": 344, + "name": "Update field values", + "order": 3, + "type": "automation" } ] } \ No newline at end of file diff --git a/backend/templates/project-management.zip b/backend/templates/project-management.zip index 9ecd794a3d..e7035cb9ee 100644 Binary files a/backend/templates/project-management.zip and b/backend/templates/project-management.zip differ diff --git a/backend/tests/baserow/contrib/database/api/rows/test_row_views.py b/backend/tests/baserow/contrib/database/api/rows/test_row_views.py index 8db5b551d8..5d8316042b 100644 --- a/backend/tests/baserow/contrib/database/api/rows/test_row_views.py +++ b/backend/tests/baserow/contrib/database/api/rows/test_row_views.py @@ -21,6 +21,10 @@ HTTP_409_CONFLICT, ) +from baserow.contrib.database.api.rows.serializers import ( + RowSerializer, + get_row_serializer_class, +) from baserow.contrib.database.fields.handler import FieldHandler from baserow.contrib.database.fields.models import SelectOption from baserow.contrib.database.fields.registries import field_type_registry @@ -29,6 +33,7 @@ from baserow.contrib.database.search.handler import ALL_SEARCH_MODES from baserow.contrib.database.table.cache import invalidate_table_in_model_cache from baserow.contrib.database.tokens.handler import TokenHandler +from baserow.contrib.database.views.handler import ViewHandler from baserow.core.action.handler import ActionHandler from baserow.core.action.registries import action_type_registry from baserow.test_utils.helpers import ( @@ -4770,3 +4775,257 @@ def test_update_single_field_does_not_affect_others(api_client, data_fixture): # Update original_values for next iteration original_values[field_id] = updated_data[f"field_{field_id}"] + + +@pytest.mark.django_db +def test_create_row_with_view_default_values(api_client, data_fixture): + user, token = data_fixture.create_user_and_token() + table = data_fixture.create_database_table(user=user) + text_field = data_fixture.create_text_field(table=table) + view = data_fixture.create_grid_view(user=user, table=table) + + ViewHandler().update_view_default_values( + user=user, + view=view, + items=[{"field": text_field.id, "enabled": True, "value": "api default"}], + ) + + # Create a row with the view context — no explicit field value. + response = api_client.post( + reverse("api:database:rows:list", kwargs={"table_id": table.id}) + + f"?view={view.id}", + {}, + format="json", + HTTP_AUTHORIZATION=f"JWT {token}", + ) + assert response.status_code == HTTP_200_OK + assert response.json()[f"field_{text_field.id}"] == "api default" + + +@pytest.mark.django_db +def test_create_row_api_default_value_priority(api_client, data_fixture): + """Test priority: empty < field default < view default < user value via API.""" + + user, token = data_fixture.create_user_and_token() + table = data_fixture.create_database_table(user=user) + text_field = data_fixture.create_text_field( + table=table, text_default="field default" + ) + view = data_fixture.create_grid_view(user=user, table=table) + + # Set view default. + ViewHandler().update_view_default_values( + user=user, + view=view, + items=[{"field": text_field.id, "enabled": True, "value": "view default"}], + ) + + # 1. No view, no value -> field default + response = api_client.post( + reverse("api:database:rows:list", kwargs={"table_id": table.id}), + {}, + format="json", + HTTP_AUTHORIZATION=f"JWT {token}", + ) + assert response.status_code == HTTP_200_OK + assert response.json()[f"field_{text_field.id}"] == "field default" + + # 2. With view, no value -> view default + response = api_client.post( + reverse("api:database:rows:list", kwargs={"table_id": table.id}) + + f"?view={view.id}", + {}, + format="json", + HTTP_AUTHORIZATION=f"JWT {token}", + ) + assert response.status_code == HTTP_200_OK + assert response.json()[f"field_{text_field.id}"] == "view default" + + # 3. With view, user value -> user value wins + response = api_client.post( + reverse("api:database:rows:list", kwargs={"table_id": table.id}) + + f"?view={view.id}", + {f"field_{text_field.id}": "user value"}, + format="json", + HTTP_AUTHORIZATION=f"JWT {token}", + ) + assert response.status_code == HTTP_200_OK + assert response.json()[f"field_{text_field.id}"] == "user value" + + +@pytest.mark.django_db +def test_batch_create_rows_with_view_default_values(api_client, data_fixture): + user, token = data_fixture.create_user_and_token() + table = data_fixture.create_database_table(user=user) + text_field = data_fixture.create_text_field(table=table) + number_field = data_fixture.create_number_field(table=table) + view = data_fixture.create_grid_view(user=user, table=table) + + ViewHandler().update_view_default_values( + user=user, + view=view, + items=[ + {"field": text_field.id, "enabled": True, "value": "default text"}, + {"field": number_field.id, "enabled": True, "value": 99}, + ], + ) + + # Row 1: provides text, so only number should get the default. + # Row 2: provides number, so only text should get the default. + response = api_client.post( + reverse("api:database:rows:batch", kwargs={"table_id": table.id}) + + f"?view={view.id}", + { + "items": [ + {f"field_{text_field.id}": "custom text"}, + {f"field_{number_field.id}": 42}, + ] + }, + format="json", + HTTP_AUTHORIZATION=f"JWT {token}", + ) + assert response.status_code == HTTP_200_OK, response.json() + rows = response.json()["items"] + + # Row 1: user-provided text, default number. + assert rows[0][f"field_{text_field.id}"] == "custom text" + assert rows[0][f"field_{number_field.id}"] == "99" + + # Row 2: default text, user-provided number. + assert rows[1][f"field_{text_field.id}"] == "default text" + assert rows[1][f"field_{number_field.id}"] == "42" + + +@pytest.mark.django_db +def test_create_row_with_interesting_table_default_values(api_client, data_fixture): + table, user, row, _, context = setup_interesting_test_table(data_fixture) + token = data_fixture.generate_token(user) + view = data_fixture.create_grid_view(user=user, table=table) + + model = table.get_model() + row = model.objects.all().enhance_by_fields().get(id=row.id) + + # Serialize the existing row in response format, then convert to + # request format so we can set them as default values. + response_serializer = get_row_serializer_class( + model, RowSerializer, is_response=True + ) + row_data = response_serializer(row).data + + items = [] + comparable_field_ids = [] + input_values_by_field_name = {} + field_type_by_id = {} + for field_object in model.get_field_objects(): + field = field_object["field"] + field_type = field_object["type"] + field_name = f"field_{field.id}" + + if field.read_only or field_type.read_only: + continue + + if field_name not in row_data: + continue + + value = row_data[field_name] + + # Convert response format → request format. + if isinstance(value, dict) and "id" in value and "value" in value: + value = value["id"] + elif isinstance(value, list) and value and isinstance(value[0], dict): + if "id" in value[0]: + value = [item["id"] for item in value] + + items.append({"field": field.id, "enabled": True, "value": value}) + input_values_by_field_name[field_name] = value + comparable_field_ids.append(field.id) + field_type_by_id[field.id] = field_type.type + + assert len(items) > 0, "Expected at least some writable fields" + + # Set the default values via the API. + patch_response = api_client.patch( + reverse("api:database:views:default_values", kwargs={"view_id": view.id}), + items, + format="json", + HTTP_AUTHORIZATION=f"JWT {token}", + ) + assert patch_response.status_code == HTTP_200_OK, patch_response.json() + + # Verify the default values are returned correctly via the list views endpoint. + list_response = api_client.get( + reverse("api:database:views:list", kwargs={"table_id": table.id}) + + "?include=default_row_values", + HTTP_AUTHORIZATION=f"JWT {token}", + ) + assert list_response.status_code == HTTP_200_OK + view_data = next(v for v in list_response.json() if v["id"] == view.id) + stored_defaults = {dv["field"]: dv for dv in view_data["default_row_values"]} + for item in items: + field_id = item["field"] + assert field_id in stored_defaults, ( + f"field_{field_id}: missing from view default_row_values" + ) + stored = stored_defaults[field_id] + assert stored["enabled"] is True + assert stored["value"] == item["value"], ( + f"field_{field_id}: stored value {stored['value']!r} != " + f"sent value {item['value']!r}" + ) + + # Create a new row without providing any field values. + create_response = api_client.post( + reverse("api:database:rows:list", kwargs={"table_id": table.id}) + + f"?view={view.id}", + {}, + format="json", + HTTP_AUTHORIZATION=f"JWT {token}", + ) + assert create_response.status_code == HTTP_200_OK, create_response.json() + created_row = create_response.json() + + # Verify that every comparable field on the created row matches the + # default value that was set. + for field_id in comparable_field_ids: + field_name = f"field_{field_id}" + created_value = created_row[field_name] + sent_value = input_values_by_field_name[field_name] + ft = field_type_by_id[field_id] + + # Password: response is a boolean indicating whether a password is set. + if ft == "password": + assert created_value is True, ( + f"{field_name}: expected password to be set (True)" + ) + continue + + # File: compare by the sorted list of file names. + if ft == "file": + created_names = sorted(f["name"] for f in created_value) + sent_names = sorted( + f["name"] if isinstance(f, dict) else f for f in sent_value + ) + assert created_names == sent_names, ( + f"{field_name}: file names {created_names!r} != {sent_names!r}" + ) + continue + + # Single select: response is an object, input was an ID. + if isinstance(created_value, dict) and "id" in created_value: + created_value = created_value["id"] + # Multiple select / link row / multiple collaborators: response is a + # list of objects, input was a list of IDs. + elif ( + isinstance(created_value, list) + and created_value + and isinstance(created_value[0], dict) + and "id" in created_value[0] + ): + created_value = sorted(item["id"] for item in created_value) + if isinstance(sent_value, list): + sent_value = sorted(sent_value) + + assert created_value == sent_value, ( + f"{field_name}: created row value {created_value!r} != " + f"default value {sent_value!r}" + ) diff --git a/backend/tests/baserow/contrib/database/api/views/test_view_views.py b/backend/tests/baserow/contrib/database/api/views/test_view_views.py index 0ab327954b..df5e99c860 100644 --- a/backend/tests/baserow/contrib/database/api/views/test_view_views.py +++ b/backend/tests/baserow/contrib/database/api/views/test_view_views.py @@ -17,6 +17,10 @@ ) from baserow.contrib.database.api.constants import PUBLIC_PLACEHOLDER_ENTITY_ID +from baserow.contrib.database.api.rows.serializers import ( + RowSerializer, + get_row_serializer_class, +) from baserow.contrib.database.rows.handler import RowHandler from baserow.contrib.database.views.handler import ViewHandler, ViewIndexingHandler from baserow.contrib.database.views.models import ( @@ -28,7 +32,7 @@ from baserow.contrib.database.views.registries import view_type_registry from baserow.contrib.database.views.view_types import GridViewType from baserow.core.trash.handler import TrashHandler -from baserow.test_utils.helpers import AnyStr +from baserow.test_utils.helpers import AnyStr, setup_interesting_test_table @pytest.fixture(autouse=True) @@ -300,6 +304,40 @@ def test_get_view(api_client, data_fixture): assert response.json()["error"] == "ERROR_VIEW_DOES_NOT_EXIST" +@pytest.mark.django_db +def test_get_view_default_row_values(api_client, data_fixture): + user, token = data_fixture.create_user_and_token() + table = data_fixture.create_database_table(user=user) + text_field = data_fixture.create_text_field(table=table) + view = data_fixture.create_grid_view(user=user, table=table) + + ViewHandler().update_view_default_values( + user=user, + view=view, + items=[{"field": text_field.id, "enabled": True, "value": "test default"}], + ) + + url = reverse("api:database:views:item", kwargs={"view_id": view.id}) + + # Without include param - should NOT have default_row_values. + response = api_client.get(url, HTTP_AUTHORIZATION=f"JWT {token}") + assert response.status_code == HTTP_200_OK + assert "default_row_values" not in response.json() + + # With include param - should have default_row_values. + response = api_client.get( + f"{url}?include=default_row_values", + HTTP_AUTHORIZATION=f"JWT {token}", + ) + assert response.status_code == HTTP_200_OK + data = response.json() + assert "default_row_values" in data + assert isinstance(data["default_row_values"], list) + assert len(data["default_row_values"]) == 1 + assert data["default_row_values"][0]["field"] == text_field.id + assert data["default_row_values"][0]["value"] == "test default" + + @pytest.mark.django_db def test_delete_view(api_client, data_fixture): user, token = data_fixture.create_user_and_token() @@ -1435,3 +1473,316 @@ def test_get_public_row(api_client, data_fixture): "order": AnyStr(), f"field_{text_field.id}": "Green", } + + +@pytest.mark.django_db +def test_patch_default_values(api_client, data_fixture): + user, token = data_fixture.create_user_and_token() + table = data_fixture.create_database_table(user=user) + text_field = data_fixture.create_text_field(table=table) + view = data_fixture.create_grid_view(user=user, table=table) + + response = api_client.patch( + reverse("api:database:views:default_values", kwargs={"view_id": view.id}), + [{"field": text_field.id, "enabled": True, "value": "new default"}], + format="json", + HTTP_AUTHORIZATION=f"JWT {token}", + ) + assert response.status_code == HTTP_200_OK + data = response.json() + assert isinstance(data, list) + assert len(data) == 1 + assert data[0]["field"] == text_field.id + assert data[0]["value"] == "new default" + assert data[0]["enabled"] is True + + +@pytest.mark.django_db +def test_patch_default_values_with_now_function(api_client, data_fixture): + user, token = data_fixture.create_user_and_token() + table = data_fixture.create_database_table(user=user) + date_field = data_fixture.create_date_field(table=table, date_include_time=True) + view = data_fixture.create_grid_view(user=user, table=table) + + response = api_client.patch( + reverse("api:database:views:default_values", kwargs={"view_id": view.id}), + [{"field": date_field.id, "enabled": True, "function": "now"}], + format="json", + HTTP_AUTHORIZATION=f"JWT {token}", + ) + assert response.status_code == HTTP_200_OK + data = response.json() + assert isinstance(data, list) + assert len(data) == 1 + assert data[0]["field"] == date_field.id + assert data[0]["function"] == "now" + + +@pytest.mark.django_db +def test_default_values_included_in_view_listing(api_client, data_fixture): + user, token = data_fixture.create_user_and_token() + table = data_fixture.create_database_table(user=user) + text_field = data_fixture.create_text_field(table=table) + view = data_fixture.create_grid_view(user=user, table=table) + + ViewHandler().update_view_default_values( + user=user, + view=view, + items=[{"field": text_field.id, "enabled": True, "value": "listing default"}], + ) + + # Without include param - should NOT have default_row_values. + response = api_client.get( + reverse("api:database:views:list", kwargs={"table_id": table.id}), + HTTP_AUTHORIZATION=f"JWT {token}", + ) + assert response.status_code == HTTP_200_OK + assert "default_row_values" not in response.json()[0] + + # With include param - should have default_row_values. + response = api_client.get( + reverse("api:database:views:list", kwargs={"table_id": table.id}) + + "?include=default_row_values", + HTTP_AUTHORIZATION=f"JWT {token}", + ) + assert response.status_code == HTTP_200_OK + data = response.json()[0] + assert "default_row_values" in data + assert isinstance(data["default_row_values"], list) + assert len(data["default_row_values"]) == 1 + assert data["default_row_values"][0]["field"] == text_field.id + assert data["default_row_values"][0]["value"] == "listing default" + + +@pytest.mark.django_db +def test_patch_default_values_empty(api_client, data_fixture): + """ + Sending an empty PATCH (no values, no enabled fields) should succeed + and return empty defaults. Reproduces the real scenario where the user + opens the modal and saves without enabling any field. + """ + + user, token = data_fixture.create_user_and_token() + table = data_fixture.create_database_table(user=user) + data_fixture.create_text_field(table=table) + view = data_fixture.create_grid_view(user=user, table=table) + + response = api_client.patch( + reverse("api:database:views:default_values", kwargs={"view_id": view.id}), + [], + format="json", + HTTP_AUTHORIZATION=f"JWT {token}", + ) + assert response.status_code == HTTP_200_OK + data = response.json() + assert isinstance(data, list) + assert len(data) == 0 + + +@pytest.mark.django_db +def test_patch_default_values_empty_succeeds(api_client, data_fixture): + """ + Sending an empty PATCH on a fresh table should succeed and return empty + defaults without any errors. + """ + + user, token = data_fixture.create_user_and_token() + table = data_fixture.create_database_table(user=user) + data_fixture.create_text_field(table=table) + view = data_fixture.create_grid_view(user=user, table=table) + + response = api_client.patch( + reverse("api:database:views:default_values", kwargs={"view_id": view.id}), + [], + format="json", + HTTP_AUTHORIZATION=f"JWT {token}", + ) + assert response.status_code == HTTP_200_OK + data = response.json() + assert isinstance(data, list) + assert len(data) == 0 + + +@pytest.mark.django_db +def test_patch_default_values_with_interesting_table(api_client, data_fixture): + """ + Sets default values for every writable field in the interesting test table + via the API endpoint. This covers all field types and ensures the + serialization / deserialization round-trip works for each one. + """ + + table, user, row, _, context = setup_interesting_test_table(data_fixture) + token = data_fixture.generate_token(user) + view = data_fixture.create_grid_view(user=user, table=table) + + model = table.get_model() + row = model.objects.all().enhance_by_fields().get(id=row.id) + + # Serialize the row in response format, then convert to request format + # for fields where the two differ (link_row, single_select, etc.). + response_serializer = get_row_serializer_class( + model, RowSerializer, is_response=True + ) + row_data = response_serializer(row).data + + items = [] + for field_object in model.get_field_objects(): + field = field_object["field"] + field_type = field_object["type"] + field_name = f"field_{field.id}" + + if field.read_only or field_type.read_only: + continue + + if field_name not in row_data: + continue + + value = row_data[field_name] + + # Convert response format → request format for specific field types. + # Single select: {"id": 1, "value": "A", "color": "blue"} → 1 + if isinstance(value, dict) and "id" in value and "value" in value: + value = value["id"] + # Link row / multiple select / multiple collaborators: + # [{"id": 1, ...}, ...] → [1, 2, ...] + elif isinstance(value, list) and value and isinstance(value[0], dict): + if "id" in value[0]: + value = [item["id"] for item in value] + + items.append({"field": field.id, "enabled": True, "value": value}) + + assert len(items) > 0, "Expected at least some writable fields" + + response = api_client.patch( + reverse("api:database:views:default_values", kwargs={"view_id": view.id}), + items, + format="json", + HTTP_AUTHORIZATION=f"JWT {token}", + ) + assert response.status_code == HTTP_200_OK, response.json() + data = response.json() + assert isinstance(data, list) + returned_field_ids = {item["field"] for item in data} + expected_field_ids = {item["field"] for item in items} + assert returned_field_ids == expected_field_ids + + # Verify that a second update (editing existing records) also works. + response = api_client.patch( + reverse("api:database:views:default_values", kwargs={"view_id": view.id}), + items, + format="json", + HTTP_AUTHORIZATION=f"JWT {token}", + ) + assert response.status_code == HTTP_200_OK, response.json() + + +@pytest.mark.django_db +def test_default_values_stored_in_request_format(api_client, data_fixture): + """ + Sets default values from the interesting test table's existing row, then + verifies that the stored default values are returned in the same request + format that was sent to the API. + """ + + table, user, row, _, context = setup_interesting_test_table(data_fixture) + token = data_fixture.generate_token(user) + view = data_fixture.create_grid_view(user=user, table=table) + + model = table.get_model() + row = model.objects.all().enhance_by_fields().get(id=row.id) + + # Serialize the existing row to get the response format, then convert to + # request format (input) so we can set them as default values. + response_serializer = get_row_serializer_class( + model, RowSerializer, is_response=True + ) + row_data = response_serializer(row).data + + # Field types whose response serialization cannot be round-tripped + # (e.g. password returns True/False/None, AI returns generated text). + non_roundtrip_types = {"password", "ai", "ai_choice"} + + items = [] + comparable_field_ids = [] + input_values_by_field_id = {} + for field_object in model.get_field_objects(): + field = field_object["field"] + field_type = field_object["type"] + field_name = f"field_{field.id}" + + if field.read_only or field_type.read_only: + continue + + if field_name not in row_data: + continue + + value = row_data[field_name] + + # Convert response format → request format for specific field types. + if isinstance(value, dict) and "id" in value and "value" in value: + value = value["id"] + elif isinstance(value, list) and value and isinstance(value[0], dict): + if "id" in value[0]: + value = [item["id"] for item in value] + + items.append({"field": field.id, "enabled": True, "value": value}) + input_values_by_field_id[field.id] = value + if field_type.type not in non_roundtrip_types: + comparable_field_ids.append(field.id) + + # Set the default values via the API. + patch_response = api_client.patch( + reverse("api:database:views:default_values", kwargs={"view_id": view.id}), + items, + format="json", + HTTP_AUTHORIZATION=f"JWT {token}", + ) + assert patch_response.status_code == HTTP_200_OK, patch_response.json() + + # Fetch the views list with default_row_values included. + views_response = api_client.get( + reverse("api:database:views:list", kwargs={"table_id": table.id}) + + "?include=default_row_values", + HTTP_AUTHORIZATION=f"JWT {token}", + ) + assert views_response.status_code == HTTP_200_OK + views_data = views_response.json() + target_view = next(v for v in views_data if v["id"] == view.id) + default_row_values = target_view["default_row_values"] + + # Build a lookup by field ID from the returned list. + stored_by_field_id = {item["field"]: item["value"] for item in default_row_values} + + # Values are stored and returned in request format (the same format + # that was sent to the PATCH endpoint). + for field_id in comparable_field_ids: + sent_value = input_values_by_field_id[field_id] + stored_value = stored_by_field_id[field_id] + assert stored_value == sent_value, ( + f"field_{field_id}: stored value {stored_value!r} != sent value {sent_value!r}" + ) + + +@pytest.mark.django_db +def test_patch_default_values_invalid_single_select_option(api_client, data_fixture): + user, token = data_fixture.create_user_and_token() + table = data_fixture.create_database_table(user=user) + single_select_field = data_fixture.create_single_select_field(table=table) + data_fixture.create_select_option(field=single_select_field, value="Valid") + view = data_fixture.create_grid_view(user=user, table=table) + + response = api_client.patch( + reverse("api:database:views:default_values", kwargs={"view_id": view.id}), + [ + { + "field": single_select_field.id, + "enabled": True, + "value": 999999, + } + ], + format="json", + HTTP_AUTHORIZATION=f"JWT {token}", + ) + assert response.status_code == HTTP_400_BAD_REQUEST + response_json = response.json() + assert response_json["error"] == "ERROR_REQUEST_BODY_VALIDATION" diff --git a/backend/tests/baserow/contrib/database/rows/test_rows_handler.py b/backend/tests/baserow/contrib/database/rows/test_rows_handler.py index 86781ddac9..1a6558580d 100644 --- a/backend/tests/baserow/contrib/database/rows/test_rows_handler.py +++ b/backend/tests/baserow/contrib/database/rows/test_rows_handler.py @@ -20,6 +20,7 @@ from baserow.contrib.database.fields.models import SelectOption from baserow.contrib.database.rows.exceptions import RowDoesNotExist from baserow.contrib.database.rows.handler import RowHandler +from baserow.contrib.database.views.handler import ViewHandler from baserow.core.exceptions import UserNotInWorkspace from baserow.core.trash.handler import TrashHandler @@ -1948,3 +1949,88 @@ def test_update_rows_only_create_or_delete_differences_for_m2m_fields(data_fixtu assert set(multiselect_through.objects.values_list("id", flat=True)) == {2} assert set(multicollab_through.objects.values_list("id", flat=True)) == {2} assert set(link_through.objects.values_list("id", flat=True)) == {3} + + +@pytest.mark.django_db +def test_create_row_handler_applies_view_defaults(data_fixture): + user = data_fixture.create_user() + table = data_fixture.create_database_table(user=user) + text_field = data_fixture.create_text_field(table=table) + view = data_fixture.create_grid_view(user=user, table=table) + + ViewHandler().update_view_default_values( + user=user, + view=view, + items=[{"field": text_field.id, "enabled": True, "value": "view default"}], + ) + + row = RowHandler().create_row(user, table, values={}, view=view) + assert getattr(row, f"field_{text_field.id}") == "view default" + + +@pytest.mark.django_db +def test_create_row_handler_user_values_override(data_fixture): + user = data_fixture.create_user() + table = data_fixture.create_database_table(user=user) + text_field = data_fixture.create_text_field(table=table) + view = data_fixture.create_grid_view(user=user, table=table) + + ViewHandler().update_view_default_values( + user=user, + view=view, + items=[{"field": text_field.id, "enabled": True, "value": "view default"}], + ) + + row = RowHandler().create_row( + user, table, values={f"field_{text_field.id}": "user value"}, view=view + ) + assert getattr(row, f"field_{text_field.id}") == "user value" + + +@pytest.mark.django_db +def test_create_rows_handler_applies_view_defaults(data_fixture): + user = data_fixture.create_user() + table = data_fixture.create_database_table(user=user) + text_field = data_fixture.create_text_field(table=table) + view = data_fixture.create_grid_view(user=user, table=table) + + ViewHandler().update_view_default_values( + user=user, + view=view, + items=[{"field": text_field.id, "enabled": True, "value": "batch default"}], + ) + + result = RowHandler().create_rows(user, table, rows_values=[{}, {}], view=view) + for row in result.created_rows: + assert getattr(row, f"field_{text_field.id}") == "batch default" + + +@pytest.mark.django_db +def test_create_row_handler_default_value_priority(data_fixture): + """Test: empty < field default < view default < user value.""" + + user = data_fixture.create_user() + table = data_fixture.create_database_table(user=user) + text_field = data_fixture.create_text_field( + table=table, text_default="field default" + ) + view = data_fixture.create_grid_view(user=user, table=table) + + # 1. No view, no user value -> field default + row1 = RowHandler().create_row(user, table, values={}) + assert getattr(row1, f"field_{text_field.id}") == "field default" + + ViewHandler().update_view_default_values( + user=user, + view=view, + items=[{"field": text_field.id, "enabled": True, "value": "view default"}], + ) + + row2 = RowHandler().create_row(user, table, values={}, view=view) + assert getattr(row2, f"field_{text_field.id}") == "view default" + + # 3. User value provided -> user value wins + row3 = RowHandler().create_row( + user, table, values={f"field_{text_field.id}": "user value"}, view=view + ) + assert getattr(row3, f"field_{text_field.id}") == "user value" diff --git a/backend/tests/baserow/contrib/database/trash/test_database_trash_types.py b/backend/tests/baserow/contrib/database/trash/test_database_trash_types.py index b0970af8a9..489c0b6a79 100644 --- a/backend/tests/baserow/contrib/database/trash/test_database_trash_types.py +++ b/backend/tests/baserow/contrib/database/trash/test_database_trash_types.py @@ -30,6 +30,7 @@ RelatedTableTrashedException, ) from baserow.core.trash.handler import TrashHandler +from baserow.test_utils.helpers import setup_interesting_test_table @pytest.mark.django_db @@ -1572,3 +1573,149 @@ def test_trash_and_restore_rows_in_batch_will_restore_formula_fields( restored_row = send_mock.call_args[1]["rows"][0] assert getattr(restored_row, f_name.db_column) == "John" assert getattr(restored_row, f_f_name.db_column) == "John" + + +@pytest.mark.django_db +def test_trash_and_restore_table_with_diverse_field_types(data_fixture): + """ + Uses setup_interesting_test_table (which creates every field type and + sub-type), trashes the table, restores it, and verifies: + - all row values come back identical + - reverse link row fields on linked tables are trashed / restored + - a lookup field on a linked table becomes invalid when the table is + trashed and recovers after restore + """ + + table, user, row, blank_row, context = setup_interesting_test_table(data_fixture) + database = table.database + name_to_field_id = context["name_to_field_id"] + link_table = context["tables"]["link_table"] + + # -- Create a lookup on link_table that depends on the main table -- + # link_table has a reverse link row field from the "link_row" field on the + # main table. We create a lookup through that reverse field targeting the + # main table's "text" field so we can verify cross-table formula invalidation. + link_row_field = LinkRowField.objects.get(id=name_to_field_id["link_row"]) + reverse_link_field = link_row_field.link_row_related_field + assert reverse_link_field is not None + + text_field = Field.objects.get(id=name_to_field_id["text"]) + cross_table_lookup = FieldHandler().create_field( + user=user, + table=link_table, + type_name="lookup", + name="lookup_main_text", + through_field_id=reverse_link_field.id, + target_field_id=text_field.id, + ) + assert cross_table_lookup.formula_type == "array" + assert cross_table_lookup.error is None + + # Collect all reverse link row field ids on linked tables that should be + # trashed when the main table is trashed. + link_row_field_names = [ + "link_row", + "decimal_link_row", + "file_link_row", + "multiple_collaborators_link_row", + ] + reverse_field_ids = {} + for name in link_row_field_names: + lr = LinkRowField.objects.get(id=name_to_field_id[name]) + if lr.link_row_related_field_id: + reverse_field_ids[name] = lr.link_row_related_field_id + + # Snapshot row values before trashing. + model = table.get_model() + row_before = model.objects.all().enhance_by_fields().get(id=row.id) + blank_before = model.objects.all().enhance_by_fields().get(id=blank_row.id) + + field_objects = model._field_objects + m2m_field_names = set() + values_before = {} + blank_values_before = {} + for fo in field_objects.values(): + field = fo["field"] + col = field.db_column + model_field = model._meta.get_field(col) + if model_field.many_to_many: + m2m_field_names.add(col) + values_before[col] = sorted( + getattr(row_before, col).values_list("id", flat=True) + ) + blank_values_before[col] = sorted( + getattr(blank_before, col).values_list("id", flat=True) + ) + else: + values_before[col] = getattr(row_before, col) + blank_values_before[col] = getattr(blank_before, col) + + field_names_before = set( + Field.objects.filter(table=table).values_list("name", flat=True) + ) + field_count_before = len(field_names_before) + + # -- Trash the table -- + TrashHandler.trash(user, database.workspace, database, table) + + # All fields in the main table should be trashed. + assert not Field.objects.filter(table=table).exists() + assert ( + Field.objects_and_trash.filter(table=table, trashed=True).count() + == field_count_before + ) + + # Reverse link row fields on linked tables should be trashed. + for name, rev_id in reverse_field_ids.items(): + rev = Field.objects_and_trash.get(id=rev_id) + assert rev.trashed, f"Reverse field for {name} should be trashed" + + # The cross-table lookup on link_table should be invalidated. + cross_table_lookup.refresh_from_db() + assert cross_table_lookup.formula_type == "invalid" + + # -- Restore the table -- + TrashHandler.restore_item(user, "table", table.id) + + # All fields should be back. + field_names_after = set( + Field.objects.filter(table=table).values_list("name", flat=True) + ) + assert field_names_after == field_names_before + + # Reverse link row fields should be restored. + for name, rev_id in reverse_field_ids.items(): + rev = Field.objects_and_trash.get(id=rev_id) + assert not rev.trashed, f"Reverse field for {name} should be restored" + + # The cross-table lookup should recover after restore. + cross_table_lookup.refresh_from_db() + assert cross_table_lookup.formula_type == "array" + + # Re-fetch rows and compare every field value. + model = table.get_model() + row_after = model.objects.all().enhance_by_fields().get(id=row.id) + blank_after = model.objects.all().enhance_by_fields().get(id=blank_row.id) + + for fo in model._field_objects.values(): + field = fo["field"] + col = field.db_column + if col in m2m_field_names: + after_ids = sorted(getattr(row_after, col).values_list("id", flat=True)) + assert after_ids == values_before[col], ( + f"Row m2m mismatch on {field.name} ({col}): " + f"{after_ids} != {values_before[col]}" + ) + blank_ids = sorted(getattr(blank_after, col).values_list("id", flat=True)) + assert blank_ids == blank_values_before[col], ( + f"Blank m2m mismatch on {field.name} ({col})" + ) + else: + assert getattr(row_after, col) == values_before[col], ( + f"Row value mismatch on {field.name} ({col}): " + f"{getattr(row_after, col)!r} != {values_before[col]!r}" + ) + assert getattr(blank_after, col) == blank_values_before[col], ( + f"Blank value mismatch on {field.name} ({col}): " + f"{getattr(blank_after, col)!r} != {blank_values_before[col]!r}" + ) diff --git a/backend/tests/baserow/contrib/database/view/test_view_handler.py b/backend/tests/baserow/contrib/database/view/test_view_handler.py index 97ea025676..b68aaa4549 100755 --- a/backend/tests/baserow/contrib/database/view/test_view_handler.py +++ b/backend/tests/baserow/contrib/database/view/test_view_handler.py @@ -3,11 +3,17 @@ from unittest.mock import patch from django.core.exceptions import ValidationError +from django.db.models import prefetch_related_objects from django.test import override_settings import pytest +from freezegun import freeze_time from pytest_unordered import unordered +from baserow.contrib.database.api.rows.serializers import ( + RowSerializer, + get_row_serializer_class, +) from baserow.contrib.database.fields.exceptions import ( FieldNotInTable, FilterFieldNotFound, @@ -18,12 +24,14 @@ from baserow.contrib.database.rows.handler import RowHandler from baserow.contrib.database.search.handler import ALL_SEARCH_MODES from baserow.contrib.database.table.handler import TableHandler +from baserow.contrib.database.views.actions import UpdateViewDefaultValuesActionType from baserow.contrib.database.views.exceptions import ( CannotShareViewTypeError, FormViewFieldTypeIsNotSupported, GridViewAggregationDoesNotSupportField, UnrelatedFieldError, ViewDoesNotExist, + ViewDoesNotSupportDefaultValues, ViewDoesNotSupportFieldOptions, ViewDoesNotSupportListingRows, ViewFilterDoesNotExist, @@ -51,6 +59,7 @@ GridView, GridViewFieldOptions, View, + ViewDefaultValue, ViewFilter, ViewFilterGroup, ViewGroupBy, @@ -68,9 +77,12 @@ ) from baserow.contrib.database.views.view_types import GridViewType from baserow.contrib.database.ws.views.rows.handler import ViewRealtimeRowsHandler +from baserow.core.action.registries import action_type_registry from baserow.core.db import get_collation_name from baserow.core.exceptions import PermissionDenied, UserNotInWorkspace +from baserow.core.registries import ImportExportConfig from baserow.core.trash.handler import TrashHandler +from baserow.core.utils import MirrorDict from baserow.test_utils.helpers import setup_interesting_test_table @@ -4484,3 +4496,659 @@ def test_can_duplicate_views_with_multiple_collaborator_has_filter(data_fixture) assert list( getattr(new_results[0], field.db_column).values_list("id", flat=True) ) == [user_1.id] + + +@pytest.mark.django_db +def test_get_view_default_values_empty(data_fixture): + user = data_fixture.create_user() + table = data_fixture.create_database_table(user=user) + view = data_fixture.create_grid_view(user=user, table=table) + + handler = ViewHandler() + result = handler.get_view_default_values(view) + assert result.count() == 0 + + +@pytest.mark.django_db +def test_update_view_default_values(data_fixture): + user = data_fixture.create_user() + table = data_fixture.create_database_table(user=user) + text_field = data_fixture.create_text_field(table=table) + number_field = data_fixture.create_number_field(table=table) + view = data_fixture.create_grid_view(user=user, table=table) + + handler = ViewHandler() + + # Set default values for the text field only. + records = handler.update_view_default_values( + user=user, + view=view, + items=[{"field": text_field.id, "enabled": True, "value": "default text"}], + ) + + assert records.filter(field_id=text_field.id).exists() + record = records.get(field_id=text_field.id) + assert record.value == "default text" + assert not records.filter(field_id=number_field.id).exists() + + dv = ViewDefaultValue.objects.get(view=view, field=text_field) + assert dv.value == "default text" + assert dv.field_type == "text" + + +@pytest.mark.django_db +def test_update_view_default_values_field_not_in_table(data_fixture): + user = data_fixture.create_user() + table = data_fixture.create_database_table(user=user) + other_table = data_fixture.create_database_table(user=user) + other_field = data_fixture.create_text_field(table=other_table) + view = data_fixture.create_grid_view(user=user, table=table) + + handler = ViewHandler() + + with pytest.raises(FieldNotInTable): + handler.update_view_default_values( + user=user, + view=view, + items=[{"field": other_field.id, "enabled": True, "value": "test"}], + ) + + # Also test with a completely non-existent field ID. + with pytest.raises(FieldNotInTable): + handler.update_view_default_values( + user=user, + view=view, + items=[{"field": 99999, "enabled": True, "value": "test"}], + ) + + # Ensure no records were created. + assert not ViewDefaultValue.objects.filter(view=view).exists() + + +@pytest.mark.django_db +def test_update_view_default_values_with_function(data_fixture): + user = data_fixture.create_user() + table = data_fixture.create_database_table(user=user) + date_field = data_fixture.create_date_field(table=table, date_include_time=True) + view = data_fixture.create_grid_view(user=user, table=table) + + handler = ViewHandler() + records = handler.update_view_default_values( + user=user, + view=view, + items=[{"field": date_field.id, "enabled": True, "function": "now"}], + ) + + record = records.get(field_id=date_field.id) + assert record.function == "now" + + # When resolving for row creation, should return current time. + with freeze_time("2024-01-15 12:00:00"): + resolved = handler.get_view_default_values_for_row_creation(view) + assert f"field_{date_field.id}" in resolved + + +@pytest.mark.django_db +def test_form_view_cannot_set_default_values(data_fixture): + user = data_fixture.create_user() + table = data_fixture.create_database_table(user=user) + view = data_fixture.create_form_view(user=user, table=table) + + handler = ViewHandler() + with pytest.raises(ViewDoesNotSupportDefaultValues): + handler.get_view_default_values(view) + + with pytest.raises(ViewDoesNotSupportDefaultValues): + handler.update_view_default_values(user=user, view=view, items=[]) + + +@pytest.mark.django_db +def test_default_values_do_not_create_table_rows(data_fixture): + user = data_fixture.create_user() + table = data_fixture.create_database_table(user=user) + text_field = data_fixture.create_text_field(table=table) + view = data_fixture.create_grid_view(user=user, table=table) + + handler = ViewHandler() + + # Create a normal row. + row_handler = RowHandler() + row_handler.force_create_row(user, table, {f"field_{text_field.id}": "normal row"}) + + # Set default values — should NOT create any rows in the table. + handler.update_view_default_values( + user=user, + view=view, + items=[{"field": text_field.id, "enabled": True, "value": "default"}], + ) + + model = table.get_model() + # Only the normal row should exist. + assert model.objects.count() == 1 + assert model.objects_and_trash.filter(trashed=False).count() == 1 + + +@pytest.mark.django_db +def test_view_deletion_cleans_up_default_values(data_fixture): + user = data_fixture.create_user() + table = data_fixture.create_database_table(user=user) + text_field = data_fixture.create_text_field(table=table) + view = data_fixture.create_grid_view(user=user, table=table) + + handler = ViewHandler() + handler.update_view_default_values( + user=user, + view=view, + items=[{"field": text_field.id, "enabled": True, "value": "default"}], + ) + + assert ViewDefaultValue.objects.filter(view=view).count() == 1 + + # Trashing the view should keep the records (for potential restore). + handler.delete_view(user, view) + assert ViewDefaultValue.objects.filter(view_id=view.id).count() == 1 + + View.objects_and_trash.filter(id=view.id).delete() + assert ViewDefaultValue.objects.filter(view_id=view.id).count() == 0 + + +@pytest.mark.django_db +def test_field_hard_deletion_cascades_to_view_default_value(data_fixture): + user = data_fixture.create_user() + table = data_fixture.create_database_table(user=user) + text_field = data_fixture.create_text_field(table=table) + view = data_fixture.create_grid_view(user=user, table=table) + + handler = ViewHandler() + handler.update_view_default_values( + user=user, + view=view, + items=[{"field": text_field.id, "enabled": True, "value": "default"}], + ) + + assert ViewDefaultValue.objects.filter(view=view, field=text_field).count() == 1 + + # Hard-delete the field to trigger FK cascade. + Field.objects.filter(id=text_field.id).delete() + + # ViewDefaultValue record should be cascade-deleted. + assert ViewDefaultValue.objects.filter(view=view).count() == 0 + + +@pytest.mark.django_db +def test_prefetch_view_default_values(data_fixture): + user = data_fixture.create_user() + table = data_fixture.create_database_table(user=user) + text_field = data_fixture.create_text_field(table=table) + view1 = data_fixture.create_grid_view(user=user, table=table) + view2 = data_fixture.create_grid_view(user=user, table=table) + + handler = ViewHandler() + + # Set defaults for view1 only. + handler.update_view_default_values( + user=user, + view=view1, + items=[{"field": text_field.id, "enabled": True, "value": "view1 default"}], + ) + + views = list( + View.objects.filter(id__in=[view1.id, view2.id]) + .order_by("id") + .prefetch_related("view_default_values") + ) + + v1_defaults = list(views[0].view_default_values.all()) + assert len(v1_defaults) == 1 + assert v1_defaults[0].field_id == text_field.id + assert v1_defaults[0].value == "view1 default" + + v2_defaults = list(views[1].view_default_values.all()) + assert len(v2_defaults) == 0 + + +@pytest.mark.django_db +def test_duplicate_view_copies_default_values(data_fixture): + user = data_fixture.create_user() + table = data_fixture.create_database_table(user=user) + text_field = data_fixture.create_text_field(table=table) + number_field = data_fixture.create_number_field(table=table) + view = data_fixture.create_grid_view(user=user, table=table) + + handler = ViewHandler() + + # Set default values on the original view. + handler.update_view_default_values( + user=user, + view=view, + items=[ + {"field": text_field.id, "enabled": True, "value": "dup default"}, + {"field": number_field.id, "enabled": True, "value": 42}, + ], + ) + + # Duplicate the view. + duplicated_view = handler.duplicate_view(user, view) + + # Check that the duplicated view has default values. + dup_defaults = handler.get_view_default_values(duplicated_view) + record_text = dup_defaults.get(field_id=text_field.id) + assert record_text.value == "dup default" + record_number = dup_defaults.get(field_id=number_field.id) + assert record_number.value == 42 + + assert ViewDefaultValue.objects.filter(view=view).count() == 2 + assert ViewDefaultValue.objects.filter(view=duplicated_view).count() == 2 + + +@pytest.mark.django_db +def test_duplicate_view_copies_default_values_with_function(data_fixture): + user = data_fixture.create_user() + table = data_fixture.create_database_table(user=user) + date_field = data_fixture.create_date_field(table=table, date_include_time=True) + view = data_fixture.create_grid_view(user=user, table=table) + + handler = ViewHandler() + handler.update_view_default_values( + user=user, + view=view, + items=[{"field": date_field.id, "enabled": True, "function": "now"}], + ) + + duplicated_view = handler.duplicate_view(user, view) + dup_defaults = handler.get_view_default_values(duplicated_view) + + record = dup_defaults.get(field_id=date_field.id) + assert record.function == "now" + + +@pytest.mark.django_db +def test_export_import_view_with_default_values(data_fixture): + user = data_fixture.create_user() + table = data_fixture.create_database_table(user=user) + text_field = data_fixture.create_text_field(table=table) + view = data_fixture.create_grid_view(user=user, table=table) + + handler = ViewHandler() + handler.update_view_default_values( + user=user, + view=view, + items=[{"field": text_field.id, "enabled": True, "value": "export test"}], + ) + + view_type = view_type_registry.get_by_model(view) + config = ImportExportConfig(include_permission_data=True) + cache = {} + + serialized = view_type.export_serialized(view, config, cache) + assert "default_row_values" in serialized + assert str(text_field.id) in serialized["default_row_values"] + assert ( + serialized["default_row_values"][str(text_field.id)]["value"] == "export test" + ) + + # Import into the same table (simulating duplication). + id_mapping = { + "workspace_id": table.database.workspace.id, + "database_fields": MirrorDict(), + "database_field_select_options": MirrorDict(), + } + serialized["name"] = "imported view" + imported_view = view_type.import_serialized(table, serialized, config, id_mapping) + + # Verify imported default values. + imported_defaults = handler.get_view_default_values(imported_view) + record = imported_defaults.get(field_id=text_field.id) + assert record.value == "export test" + + +@pytest.mark.django_db +def test_update_view_default_values_twice(data_fixture): + """Updating default values a second time should work without errors.""" + + user = data_fixture.create_user() + table = data_fixture.create_database_table(user=user) + text_field = data_fixture.create_text_field(table=table) + view = data_fixture.create_grid_view(user=user, table=table) + + handler = ViewHandler() + + # First update — creates the record. + records = handler.update_view_default_values( + user=user, + view=view, + items=[{"field": text_field.id, "enabled": True, "value": "first"}], + ) + assert records.get(field_id=text_field.id).value == "first" + + # Second update — updates the existing record. + records = handler.update_view_default_values( + user=user, + view=view, + items=[{"field": text_field.id, "enabled": True, "value": "second"}], + ) + assert records.get(field_id=text_field.id).value == "second" + + assert ViewDefaultValue.objects.filter(view=view).count() == 1 + + +@pytest.mark.django_db +def test_field_type_change_invalidates_default_value(data_fixture): + """ + When a field's type changes (e.g. text → single_select), the stored + default value should no longer be returned because the field_type no + longer matches. + """ + + user = data_fixture.create_user() + table = data_fixture.create_database_table(user=user) + text_field = data_fixture.create_text_field(table=table) + view = data_fixture.create_grid_view(user=user, table=table) + + handler = ViewHandler() + + # Set a text default value. + handler.update_view_default_values( + user=user, + view=view, + items=[{"field": text_field.id, "enabled": True, "value": "hello"}], + ) + + result = handler.get_view_default_values(view) + assert result.filter(field_id=text_field.id).exists() + assert result.get(field_id=text_field.id).value == "hello" + + # Convert the field from text to single_select. + FieldHandler().update_field(user, text_field, new_type_name="single_select") + + # The record still exists in the DB (field_type mismatch is handled at + # serialization / row-creation time, not by deletion). The raw queryset + # will still contain the record, but row creation should skip it. + resolved = handler.get_view_default_values_for_row_creation(view) + assert f"field_{text_field.id}" not in resolved + + +@pytest.mark.django_db +def test_duplicate_view_remaps_single_select_default_value(data_fixture): + user = data_fixture.create_user() + table = data_fixture.create_database_table(user=user) + field = data_fixture.create_single_select_field(table=table) + option_a = data_fixture.create_select_option(field=field, value="A") + view = data_fixture.create_grid_view(user=user, table=table) + + handler = ViewHandler() + handler.update_view_default_values( + user=user, + view=view, + items=[{"field": field.id, "enabled": True, "value": option_a.id}], + ) + + # Verify the stored value is the option ID. + record = ViewDefaultValue.objects.get(view=view, field=field) + assert record.value == option_a.id + + # Duplicate the view. + duplicated_view = handler.duplicate_view(user, view) + + # The duplicated record should have the same option ID because + # duplicate_view uses MirrorDict (IDs stay the same). + dup_record = ViewDefaultValue.objects.get(view=duplicated_view, field=field) + assert dup_record.value == option_a.id + assert dup_record.enabled is True + + # Creating a row with the duplicated view should apply the default. + row = RowHandler().create_row(user, table, values={}, view=duplicated_view) + assert getattr(row, f"field_{field.id}_id") == option_a.id + + +@pytest.mark.django_db +def test_duplicate_view_remaps_multiple_select_default_value(data_fixture): + user = data_fixture.create_user() + table = data_fixture.create_database_table(user=user) + field = data_fixture.create_multiple_select_field(table=table) + option_a = data_fixture.create_select_option(field=field, value="A") + option_b = data_fixture.create_select_option(field=field, value="B") + view = data_fixture.create_grid_view(user=user, table=table) + + handler = ViewHandler() + handler.update_view_default_values( + user=user, + view=view, + items=[ + { + "field": field.id, + "enabled": True, + "value": [option_a.id, option_b.id], + } + ], + ) + + record = ViewDefaultValue.objects.get(view=view, field=field) + assert record.value == [option_a.id, option_b.id] + + # Duplicate the view. + duplicated_view = handler.duplicate_view(user, view) + + dup_record = ViewDefaultValue.objects.get(view=duplicated_view, field=field) + assert dup_record.value == [option_a.id, option_b.id] + assert dup_record.enabled is True + + # Creating a row with the duplicated view should apply the defaults. + row = RowHandler().create_row(user, table, values={}, view=duplicated_view) + m2m_ids = list(getattr(row, f"field_{field.id}").values_list("id", flat=True)) + assert set(m2m_ids) == {option_a.id, option_b.id} + + +@pytest.mark.django_db +def test_export_import_remaps_single_select_default_value(data_fixture): + user = data_fixture.create_user() + table = data_fixture.create_database_table(user=user) + field = data_fixture.create_single_select_field(table=table) + option_a = data_fixture.create_select_option(field=field, value="A") + view = data_fixture.create_grid_view(user=user, table=table) + + handler = ViewHandler() + handler.update_view_default_values( + user=user, + view=view, + items=[{"field": field.id, "enabled": True, "value": option_a.id}], + ) + + # Export the view. + view_type = view_type_registry.get_by_model(view) + config = ImportExportConfig(include_permission_data=True) + + prefetch_related_objects([view], "view_default_values") + serialized = view_type.export_serialized(view, config, {}) + + assert serialized["default_row_values"][str(field.id)]["value"] == option_a.id + + # Simulate import with a new option ID. + new_option_id = option_a.id + 1000 + id_mapping = { + "workspace_id": table.database.workspace.id, + "database_fields": {field.id: field.id}, + "database_field_select_options": {option_a.id: new_option_id}, + } + serialized["name"] = "imported view" + imported_view = view_type.import_serialized(table, serialized, config, id_mapping) + + # The imported default value should have the remapped option ID. + imported_record = ViewDefaultValue.objects.get(view=imported_view, field=field) + assert imported_record.value == new_option_id + + +@pytest.mark.django_db +def test_export_import_remaps_multiple_select_default_value(data_fixture): + user = data_fixture.create_user() + table = data_fixture.create_database_table(user=user) + field = data_fixture.create_multiple_select_field(table=table) + option_a = data_fixture.create_select_option(field=field, value="A") + option_b = data_fixture.create_select_option(field=field, value="B") + view = data_fixture.create_grid_view(user=user, table=table) + + handler = ViewHandler() + handler.update_view_default_values( + user=user, + view=view, + items=[ + { + "field": field.id, + "enabled": True, + "value": [option_a.id, option_b.id], + } + ], + ) + + # Export the view. + view_type = view_type_registry.get_by_model(view) + config = ImportExportConfig(include_permission_data=True) + + prefetch_related_objects([view], "view_default_values") + serialized = view_type.export_serialized(view, config, {}) + + assert serialized["default_row_values"][str(field.id)]["value"] == [ + option_a.id, + option_b.id, + ] + + # Simulate import with new option IDs. + new_a_id = option_a.id + 1000 + new_b_id = option_b.id + 1000 + id_mapping = { + "workspace_id": table.database.workspace.id, + "database_fields": {field.id: field.id}, + "database_field_select_options": { + option_a.id: new_a_id, + option_b.id: new_b_id, + }, + } + serialized["name"] = "imported view" + imported_view = view_type.import_serialized(table, serialized, config, id_mapping) + + imported_record = ViewDefaultValue.objects.get(view=imported_view, field=field) + assert imported_record.value == [new_a_id, new_b_id] + + +@pytest.mark.django_db +def test_update_view_default_values_action_stores_new_values(data_fixture): + user = data_fixture.create_user() + table = data_fixture.create_database_table(user=user) + text_field = data_fixture.create_text_field(table=table) + view = data_fixture.create_grid_view(user=user, table=table) + + captured = {} + + original_register = UpdateViewDefaultValuesActionType.register_action.__func__ + + def mock_register(cls, user, params, scope, workspace=None): + captured["params"] = params + return original_register(cls, user, params, scope, workspace) + + with patch.object( + UpdateViewDefaultValuesActionType, + "register_action", + classmethod(mock_register), + ): + action_type_registry.get(UpdateViewDefaultValuesActionType.type).do( + user=user, + view=view, + items=[{"field": text_field.id, "enabled": True, "value": "hello"}], + ) + + params = captured["params"] + assert str(text_field.id) in params.new_values + record_params = params.new_values[str(text_field.id)] + assert record_params["value"] == "hello" + assert record_params["enabled"] is True + assert record_params["field_type"] == "text" + assert record_params["function"] is None + + +@pytest.mark.django_db +def test_export_import_default_values_for_all_field_types(data_fixture): + table, user, row, _, context = setup_interesting_test_table(data_fixture) + view = data_fixture.create_grid_view(user=user, table=table) + + model = table.get_model() + row = model.objects.all().enhance_by_fields().get(id=row.id) + + # Serialize the populated row in response format, then convert to request + # format (the format default values are stored in). + response_serializer = get_row_serializer_class( + model, RowSerializer, is_response=True + ) + row_data = response_serializer(row).data + + items = [] + for field_object in model.get_field_objects(): + field = field_object["field"] + field_type = field_object["type"] + field_name = f"field_{field.id}" + + if field.read_only or field_type.read_only: + continue + + if field_name not in row_data: + continue + + value = row_data[field_name] + + # Convert response format → request format for specific field types. + # Single select: {"id": 1, "value": "A", "color": "blue"} → 1 + if isinstance(value, dict) and "id" in value and "value" in value: + value = value["id"] + # Link row / multiple select / multiple collaborators: + # [{"id": 1, ...}, ...] → [1, 2, ...] + elif isinstance(value, list) and value and isinstance(value[0], dict): + if "id" in value[0]: + value = [item["id"] for item in value] + + items.append({"field": field.id, "enabled": True, "value": value}) + + assert len(items) > 0, "Expected at least some writable fields" + + handler = ViewHandler() + handler.update_view_default_values(user=user, view=view, items=items) + + # Export the view. + view_type = view_type_registry.get_by_model(view) + config = ImportExportConfig(include_permission_data=True) + prefetch_related_objects([view], "view_default_values") + serialized = view_type.export_serialized(view, config, {}) + + assert "default_row_values" in serialized + assert len(serialized["default_row_values"]) == len(items) + + # Import the view back into the same table using MirrorDict so IDs stay + # the same (simulating duplication within the same database). + id_mapping = { + "workspace_id": table.database.workspace.id, + "database_fields": MirrorDict(), + "database_field_select_options": MirrorDict(), + } + serialized["name"] = "imported view" + imported_view = view_type.import_serialized(table, serialized, config, id_mapping) + + # Verify imported default values. + imported_defaults = { + dv.field_id: dv for dv in ViewDefaultValue.objects.filter(view=imported_view) + } + original_defaults = { + dv.field_id: dv for dv in ViewDefaultValue.objects.filter(view=view) + } + + assert set(imported_defaults.keys()) == set(original_defaults.keys()), ( + f"Field ID mismatch: imported={set(imported_defaults.keys())}, " + f"original={set(original_defaults.keys())}" + ) + + for field_id, original in original_defaults.items(): + imported = imported_defaults[field_id] + assert imported.value == original.value, ( + f"field_{field_id} ({original.field_type}): " + f"imported={imported.value!r} != original={original.value!r}" + ) + assert imported.enabled == original.enabled + assert imported.field_type == original.field_type + assert imported.function == original.function diff --git a/changelog/entries/unreleased/bug/fix_read_only_link_row_edit_modal.json b/changelog/entries/unreleased/bug/fix_read_only_link_row_edit_modal.json new file mode 100644 index 0000000000..4a91942cc1 --- /dev/null +++ b/changelog/entries/unreleased/bug/fix_read_only_link_row_edit_modal.json @@ -0,0 +1,9 @@ +{ + "type": "bug", + "message": "Fix bug where it was not possible to open the row edit modal if the user did not have access to the related table.", + "issue_origin": "github", + "issue_number": null, + "domain": "database", + "bullet_points": [], + "created_at": "2026-04-02" +} diff --git a/changelog/entries/unreleased/refactor/optimize_table_trash_n_plus_1_queries.json b/changelog/entries/unreleased/refactor/optimize_table_trash_n_plus_1_queries.json new file mode 100644 index 0000000000..3affe8ddc2 --- /dev/null +++ b/changelog/entries/unreleased/refactor/optimize_table_trash_n_plus_1_queries.json @@ -0,0 +1,9 @@ +{ + "type": "refactor", + "message": "Optimized table deletion (trash) by batching field operations.", + "issue_origin": "github", + "issue_number": null, + "domain": "database", + "bullet_points": [], + "created_at": "2026-03-31" +} diff --git a/enterprise/backend/src/baserow_enterprise/role/default_roles.py b/enterprise/backend/src/baserow_enterprise/role/default_roles.py index 90cf708275..b059966c65 100755 --- a/enterprise/backend/src/baserow_enterprise/role/default_roles.py +++ b/enterprise/backend/src/baserow_enterprise/role/default_roles.py @@ -174,6 +174,7 @@ ReadAdjacentViewRowOperationType, ReadAggregationsViewOperationType, ReadViewDecorationOperationType, + ReadViewDefaultValuesOperationType, ReadViewFieldOptionsOperationType, ReadViewFilterGroupOperationType, ReadViewFilterOperationType, @@ -184,6 +185,7 @@ ReadViewSortOperationType, RestoreViewOperationType, UpdateViewDecorationOperationType, + UpdateViewDefaultValuesOperationType, UpdateViewFieldOptionsOperationType, UpdateViewFilterGroupOperationType, UpdateViewFilterOperationType, @@ -426,6 +428,7 @@ CreateViewRowOperationType, UpdateViewRowOperationType, DeleteViewRowOperationType, + ReadViewDefaultValuesOperationType, ] ) default_roles[BUILDER_ROLE_UID].extend( @@ -471,6 +474,7 @@ ReadWebhookOperationType, OrderViewsOperationType, UpdateViewFieldOptionsOperationType, + UpdateViewDefaultValuesOperationType, CreateApplicationsWorkspaceOperationType, DeleteViewSortOperationType, UpdateViewSlugOperationType, diff --git a/enterprise/backend/src/baserow_enterprise/view_ownership_types.py b/enterprise/backend/src/baserow_enterprise/view_ownership_types.py index 8e0c7138b8..98866d6f06 100644 --- a/enterprise/backend/src/baserow_enterprise/view_ownership_types.py +++ b/enterprise/backend/src/baserow_enterprise/view_ownership_types.py @@ -1,4 +1,4 @@ -from typing import Optional, Set +from typing import List, Optional, Set from django.contrib.auth.models import AbstractUser from django.db.models import QuerySet @@ -7,6 +7,7 @@ from baserow.contrib.database.views.models import View from baserow.contrib.database.views.operations import ( CreateViewFilterOperationType, + ReadViewDefaultValuesOperationType, UpdateViewFieldOptionsOperationType, ) from baserow.contrib.database.views.registries import ( @@ -70,10 +71,22 @@ def get_hidden_field_ids_for_user( view_type = view_type_registry.get_by_model(view.specific_class) return view_type.get_hidden_fields(view.specific) - def prepare_views_for_user(self, user, views): + def prepare_views_for_user( + self, + user: Optional["AbstractUser"], + views: List["View"], + includes: Optional[Set[str]] = None, + ) -> List["View"]: if len(views) == 0 or user is None: return views + include_default_row_values = ( + includes is None or "default_row_values" in includes + ) + include_sortings = includes is None or "sortings" in includes + include_group_bys = includes is None or "group_bys" in includes + include_decorations = includes is None or "decorations" in includes + permission_checks = {} for view in views: permission_checks[f"filter{view.id}"] = PermissionCheck( @@ -86,19 +99,26 @@ def prepare_views_for_user(self, user, views): UpdateViewFieldOptionsOperationType.type, context=view, ) + if include_default_row_values: + permission_checks[f"read_default_values{view.id}"] = PermissionCheck( + user, + ReadViewDefaultValuesOperationType.type, + context=view, + ) check_results = CoreHandler().check_multiple_permissions( permission_checks.values(), workspace=views[0].table.database.workspace ) for view in views: + if not hasattr(view, "_prefetched_objects_cache"): + view._prefetched_objects_cache = {} + filter_check_result = check_results[permission_checks[f"filter{view.id}"]] # If the user does not have create view filter permissions for the provided - # view, then the filters are omitted because the they're forcefully applied + # view, then the filters are omitted because they're forcefully applied # so that the user can only see the rows that match the filter. if not filter_check_result: - if not hasattr(view, "_prefetched_objects_cache"): - view._prefetched_objects_cache = {} view._prefetched_objects_cache["viewfilter_set"] = [] view._prefetched_objects_cache["filter_groups"] = [] @@ -109,8 +129,6 @@ def prepare_views_for_user(self, user, views): # provided view, then the hidden fields are omitted because they should not # be exposed to the user. if not field_options_check_result: - if not hasattr(view, "_prefetched_objects_cache"): - view._prefetched_objects_cache = {} # Cache hidden field IDs to avoid repeated permission checks. view_type = view_type_registry.get_by_model(view.specific_class) # This could cause N number of queries, but if the views are fetched @@ -123,32 +141,63 @@ def prepare_views_for_user(self, user, views): # Remove sorts and group_bys that reference hidden fields so # that editors don't see them in the API response. if hidden_field_ids: - if "viewsort_set" not in view._prefetched_objects_cache: - view._prefetched_objects_cache["viewsort_set"] = list( - view.viewsort_set.all() - ) - view._prefetched_objects_cache["viewsort_set"] = [ - s - for s in view._prefetched_objects_cache["viewsort_set"] - if s.field_id not in hidden_field_ids - ] - - if "viewgroupby_set" not in view._prefetched_objects_cache: - view._prefetched_objects_cache["viewgroupby_set"] = list( - view.viewgroupby_set.all() - ) - view._prefetched_objects_cache["viewgroupby_set"] = [ - g - for g in view._prefetched_objects_cache["viewgroupby_set"] - if g.field_id not in hidden_field_ids - ] - - # Remove all decorations for editors because decorations may have - # conditions referencing hidden fields, which would cause errors on - # the frontend. - view._prefetched_objects_cache["viewdecoration_set"] = [] + if include_sortings: + if "viewsort_set" not in view._prefetched_objects_cache: + view._prefetched_objects_cache["viewsort_set"] = list( + view.viewsort_set.all() + ) + view._prefetched_objects_cache["viewsort_set"] = [ + s + for s in view._prefetched_objects_cache["viewsort_set"] + if s.field_id not in hidden_field_ids + ] + + if include_group_bys: + if "viewgroupby_set" not in view._prefetched_objects_cache: + view._prefetched_objects_cache["viewgroupby_set"] = list( + view.viewgroupby_set.all() + ) + view._prefetched_objects_cache["viewgroupby_set"] = [ + g + for g in view._prefetched_objects_cache["viewgroupby_set"] + if g.field_id not in hidden_field_ids + ] + + if include_decorations: + # Remove all decorations for editors because decorations + # may have conditions referencing hidden fields, which + # would cause errors on the frontend. + view._prefetched_objects_cache["viewdecoration_set"] = [] else: view._hidden_field_ids = None + hidden_field_ids = set() + + # Determine which default row values to expose based on the user's + # permissions. Builders and admins (who have UpdateViewFieldOptions) can + # see all default values. Editors (who have ReadViewDefaultValues) can + # see default values for visible fields only. Commenters and viewers + # cannot see any default values. + if include_default_row_values: + if field_options_check_result: + # Builder or admin: expose all default values. + pass + elif check_results[permission_checks[f"read_default_values{view.id}"]]: + # Editor: expose default values for visible fields only. + if hidden_field_ids: + if "view_default_values" not in view._prefetched_objects_cache: + view._prefetched_objects_cache["view_default_values"] = ( + list(view.view_default_values.all()) + ) + view._prefetched_objects_cache["view_default_values"] = [ + default_value + for default_value in view._prefetched_objects_cache[ + "view_default_values" + ] + if default_value.field_id not in hidden_field_ids + ] + else: + # Commenter or viewer: no default values. + view._prefetched_objects_cache["view_default_values"] = [] return views diff --git a/enterprise/backend/src/baserow_enterprise/ws/restricted_view/rows/view_realtime_rows.py b/enterprise/backend/src/baserow_enterprise/ws/restricted_view/rows/view_realtime_rows.py index 5acf7125c1..94162d3d0d 100644 --- a/enterprise/backend/src/baserow_enterprise/ws/restricted_view/rows/view_realtime_rows.py +++ b/enterprise/backend/src/baserow_enterprise/ws/restricted_view/rows/view_realtime_rows.py @@ -11,9 +11,10 @@ class RestrictedViewRealtimeRowsType(ViewRealtimeRowsType): def get_views_filter(self) -> Q: return Q(ownership_type=RestrictedViewOwnershipType.type) - def broadcast(self, view, payload): + def broadcast(self, view, payload, user=None): view_page_type = page_registry.get("restricted_view") view_page_type.broadcast( payload, + ignore_web_socket_id=getattr(user, "web_socket_id", None), restricted_view_id=view.id, ) diff --git a/enterprise/backend/src/baserow_enterprise/ws/restricted_view/views/signals.py b/enterprise/backend/src/baserow_enterprise/ws/restricted_view/views/signals.py index a6e1b1bdbe..4366c02f69 100644 --- a/enterprise/backend/src/baserow_enterprise/ws/restricted_view/views/signals.py +++ b/enterprise/backend/src/baserow_enterprise/ws/restricted_view/views/signals.py @@ -26,6 +26,28 @@ def _send_force_rows_refresh_if_view_restricted(view): ) +@receiver(view_signals.view_updated) +def view_updated(sender, view, old_view, user, **kwargs): + view_page_type = page_registry.get("restricted_view") + if view.ownership_type == RestrictedViewOwnershipType.type: + transaction.on_commit( + lambda: view_page_type.broadcast( + # Broadcast the `force_view_refresh_and_default_values` event + # because that will force the view and default values to be + # refreshed. Unfortunately, the client has to fetch the default + # values again because we don't know what permissions the user has. + # Viewer should not receive default, but editor only the visible + # fields, for example. + { + "type": "force_view_refresh_and_default_values", + "view_id": view.id, + }, + None, + restricted_view_id=view.id, + ) + ) + + @receiver(view_signals.view_filter_created) def restricted_view_filter_created(sender, view_filter, user, **kwargs): _send_force_rows_refresh_if_view_restricted(view_filter.view) diff --git a/enterprise/backend/tests/baserow_enterprise_tests/api/role/test_other_views_with_rbac.py b/enterprise/backend/tests/baserow_enterprise_tests/api/role/test_other_views_with_rbac.py index b288da0cf0..13789a5f0e 100644 --- a/enterprise/backend/tests/baserow_enterprise_tests/api/role/test_other_views_with_rbac.py +++ b/enterprise/backend/tests/baserow_enterprise_tests/api/role/test_other_views_with_rbac.py @@ -350,6 +350,11 @@ def test_list_views_doesnt_include_personal_views_the_user_used_to_have(data_fix collab_view.id, } + # Restore the global default_roles dict so subsequent tests are not affected. + default_roles[role_that_looses_personal_views].append( + CreateAndUsePersonalViewOperationType + ) + VIEW_FILTER_RBAC_TESTS_PRAMS = [ ("VIEWER", OWNERSHIP_TYPE_PERSONAL, HTTP_200_OK), @@ -465,3 +470,73 @@ def test_builders_and_up_can_change_views_ownership_type( else initial_ownership_type ) assert view.ownership_type == expected_ownership_type + + +@pytest.mark.django_db(transaction=True) +@pytest.mark.view_ownership +def test_editor_personal_view_default_values_applied_to_new_row( + api_client, data_fixture, synced_roles +): + """ + An editor is normally not allowed to update default values on a collaborative + view, but they should be able to do so on their own personal view. This is + because the ViewOwnershipPermissionManagerType grants the + UpdateViewDefaultValuesOperationType on personal views owned by the user. + """ + + user, token = data_fixture.create_user_and_token( + email="test@test.nl", password="password", first_name="Test1" + ) + table = data_fixture.create_database_table(user) + text_field = data_fixture.create_text_field(table=table) + + editor_role = RoleAssignmentHandler().get_role_by_uid("EDITOR") + RoleAssignmentHandler().assign_role( + user, table.database.workspace, role=editor_role, scope=table + ) + + # Verify the editor cannot set default values on a collaborative view. + collaborative_view = data_fixture.create_grid_view(table=table) + response = api_client.patch( + reverse( + "api:database:views:default_values", + kwargs={"view_id": collaborative_view.id}, + ), + [{"field": text_field.id, "enabled": True, "value": "should fail"}], + format="json", + HTTP_AUTHORIZATION=f"JWT {token}", + ) + assert response.status_code == HTTP_401_UNAUTHORIZED + + # Editor creates their own personal view. + create_view_response = api_client.post( + reverse("api:database:views:list", kwargs={"table_id": table.id}), + {"name": "Editor personal", "type": "grid", "ownership_type": "personal"}, + format="json", + HTTP_AUTHORIZATION=f"JWT {token}", + ) + assert create_view_response.status_code == HTTP_200_OK + personal_view_id = create_view_response.json()["id"] + + # Editor sets default values on their own personal view. + patch_response = api_client.patch( + reverse( + "api:database:views:default_values", + kwargs={"view_id": personal_view_id}, + ), + [{"field": text_field.id, "enabled": True, "value": "editor default"}], + format="json", + HTTP_AUTHORIZATION=f"JWT {token}", + ) + assert patch_response.status_code == HTTP_200_OK + + # Editor creates a row using their personal view — defaults should apply. + create_row_response = api_client.post( + reverse("api:database:rows:list", kwargs={"table_id": table.id}) + + f"?view={personal_view_id}", + {}, + format="json", + HTTP_AUTHORIZATION=f"JWT {token}", + ) + assert create_row_response.status_code == HTTP_200_OK + assert create_row_response.json()[f"field_{text_field.id}"] == "editor default" diff --git a/enterprise/backend/tests/baserow_enterprise_tests/api/views/test_enterprise_view_views.py b/enterprise/backend/tests/baserow_enterprise_tests/api/views/test_enterprise_view_views.py index 080f10caaa..b1d34d7ebd 100644 --- a/enterprise/backend/tests/baserow_enterprise_tests/api/views/test_enterprise_view_views.py +++ b/enterprise/backend/tests/baserow_enterprise_tests/api/views/test_enterprise_view_views.py @@ -9,6 +9,7 @@ HTTP_402_PAYMENT_REQUIRED, ) +from baserow.contrib.database.views.handler import ViewHandler from baserow.contrib.database.views.models import View from baserow.core.subjects import UserSubjectType from baserow_enterprise.role.handler import RoleAssignmentHandler @@ -1014,3 +1015,59 @@ def test_cannot_update_rows_in_table_using_unrelated_view( HTTP_AUTHORIZATION=f"JWT {token2}", ) assert response.status_code == HTTP_401_UNAUTHORIZED + + +@pytest.mark.django_db +@override_settings(DEBUG=True) +def test_default_values_collaborative_view_viewer_sees_none( + enterprise_data_fixture, api_client +): + """ + A viewer on a collaborative view does not see default row values because + they cannot create rows. + """ + + enterprise_data_fixture.enable_enterprise() + + admin, admin_token = enterprise_data_fixture.create_user_and_token() + viewer_user, viewer_token = enterprise_data_fixture.create_user_and_token() + workspace = enterprise_data_fixture.create_workspace( + user=admin, members=[viewer_user] + ) + database = enterprise_data_fixture.create_database_application(workspace=workspace) + table = enterprise_data_fixture.create_database_table(database=database) + text_field = enterprise_data_fixture.create_text_field(table=table) + view = enterprise_data_fixture.create_grid_view(table=table) + + ViewHandler().update_view_default_values( + user=admin, + view=view, + items=[{"field": text_field.id, "enabled": True, "value": "test"}], + ) + + viewer_role = Role.objects.get(uid="VIEWER") + RoleAssignmentHandler().assign_role( + viewer_user, workspace, role=viewer_role, scope=workspace + ) + + # List views: viewer should not get default_row_values. + response = api_client.get( + reverse("api:database:views:list", kwargs={"table_id": table.id}) + + "?include=default_row_values", + HTTP_AUTHORIZATION=f"JWT {viewer_token}", + ) + assert response.status_code == HTTP_200_OK + data = response.json() + view_data = next(v for v in data if v["id"] == view.id) + assert view_data["default_row_values"] == [] + + # Admin (builder+) should see default_row_values. + response = api_client.get( + reverse("api:database:views:list", kwargs={"table_id": table.id}) + + "?include=default_row_values", + HTTP_AUTHORIZATION=f"JWT {admin_token}", + ) + assert response.status_code == HTTP_200_OK + data = response.json() + view_data = next(v for v in data if v["id"] == view.id) + assert len(view_data["default_row_values"]) == 1 diff --git a/enterprise/backend/tests/baserow_enterprise_tests/views/test_restricted_view.py b/enterprise/backend/tests/baserow_enterprise_tests/views/test_restricted_view.py index 9c0e8355fd..e5f2f27a03 100644 --- a/enterprise/backend/tests/baserow_enterprise_tests/views/test_restricted_view.py +++ b/enterprise/backend/tests/baserow_enterprise_tests/views/test_restricted_view.py @@ -1,7 +1,8 @@ from datetime import datetime from unittest.mock import ANY, call, patch -from django.test.utils import override_settings +from django.db import connection +from django.test.utils import CaptureQueriesContext, override_settings from django.urls import reverse import pytest @@ -10,6 +11,7 @@ from baserow.contrib.database.api.constants import PUBLIC_PLACEHOLDER_ENTITY_ID from baserow.contrib.database.fields.models import DateField from baserow.contrib.database.rows.handler import RowHandler +from baserow.contrib.database.views.handler import ViewHandler from baserow.contrib.database.views.models import ( GalleryViewFieldOptions, GridViewFieldOptions, @@ -2102,3 +2104,297 @@ def test_editor_adjacent_row_requires_view_and_excludes_hidden_fields( response_json = response.json() assert f"field_{visible_field.id}" in response_json assert f"field_{hidden_field.id}" in response_json + + +@pytest.mark.django_db(transaction=True) +@patch("baserow.ws.registries.broadcast_to_channel_group") +def test_when_restricted_view_updated_force_view_refresh_is_broadcasted( + mock_broadcast_to_channel_group, + enterprise_data_fixture, +): + enterprise_data_fixture.enable_enterprise() + + user = enterprise_data_fixture.create_user() + table = enterprise_data_fixture.create_database_table(user=user) + restricted_view = enterprise_data_fixture.create_grid_view( + table=table, + ownership_type=RestrictedViewOwnershipType.type, + ) + + mock_broadcast_to_channel_group.delay.reset_mock() + + ViewHandler().update_view(user=user, view=restricted_view, name="Updated name") + + restricted_channel = f"restricted-view-{restricted_view.id}" + restricted_call = None + for c in mock_broadcast_to_channel_group.delay.call_args_list: + if c[0][0] == restricted_channel: + restricted_call = c + break + assert restricted_call is not None, f"No broadcast to {restricted_channel} found" + + payload = restricted_call[0][1] + assert payload["type"] == "force_view_refresh_and_default_values" + assert payload["view_id"] == restricted_view.id + + +def _setup_default_values_test(enterprise_data_fixture): + """ + Helper that creates a workspace with an admin (builder) and a second user, + a table with a visible and a hidden field, a restricted view with hidden + field configuration, and a default value on each field. Returns a dict with + all the objects needed by the tests. + """ + + enterprise_data_fixture.enable_enterprise() + + admin, admin_token = enterprise_data_fixture.create_user_and_token() + other_user, other_token = enterprise_data_fixture.create_user_and_token() + workspace = enterprise_data_fixture.create_workspace( + user=admin, members=[other_user] + ) + database = enterprise_data_fixture.create_database_application(workspace=workspace) + table = enterprise_data_fixture.create_database_table(database=database) + visible_field = enterprise_data_fixture.create_text_field(table=table, primary=True) + hidden_field = enterprise_data_fixture.create_text_field(table=table) + view = enterprise_data_fixture.create_grid_view( + table=table, ownership_type=RestrictedViewOwnershipType.type + ) + + _set_field_hidden(view, hidden_field, visible_fields=[visible_field]) + + ViewHandler().update_view_default_values( + user=admin, + view=view, + items=[ + { + "field": visible_field.id, + "enabled": True, + "value": "visible default", + }, + { + "field": hidden_field.id, + "enabled": True, + "value": "hidden default", + }, + ], + ) + + return { + "admin": admin, + "admin_token": admin_token, + "other_user": other_user, + "other_token": other_token, + "workspace": workspace, + "table": table, + "visible_field": visible_field, + "hidden_field": hidden_field, + "view": view, + } + + +@pytest.mark.django_db +@override_settings(DEBUG=True) +def test_default_values_list_views_builder_sees_all( + enterprise_data_fixture, api_client +): + ctx = _setup_default_values_test(enterprise_data_fixture) + + response = api_client.get( + reverse("api:database:views:list", kwargs={"table_id": ctx["table"].id}) + + "?include=default_row_values", + HTTP_AUTHORIZATION=f"JWT {ctx['admin_token']}", + ) + assert response.status_code == HTTP_200_OK + data = response.json() + view_data = next(v for v in data if v["id"] == ctx["view"].id) + default_values = view_data["default_row_values"] + field_ids = {dv["field"] for dv in default_values} + assert ctx["visible_field"].id in field_ids + assert ctx["hidden_field"].id in field_ids + + +@pytest.mark.django_db +@override_settings(DEBUG=True) +def test_default_values_list_views_editor_sees_visible_only( + enterprise_data_fixture, api_client +): + ctx = _setup_default_values_test(enterprise_data_fixture) + + no_access_role = Role.objects.get(uid="NO_ACCESS") + editor_role = Role.objects.get(uid="EDITOR") + RoleAssignmentHandler().assign_role( + ctx["other_user"], + ctx["workspace"], + role=no_access_role, + scope=ctx["workspace"], + ) + RoleAssignmentHandler().assign_role( + ctx["other_user"], + ctx["workspace"], + role=editor_role, + scope=View.objects.get(id=ctx["view"].id), + ) + + response = api_client.get( + reverse("api:database:views:list", kwargs={"table_id": ctx["table"].id}) + + "?include=default_row_values", + HTTP_AUTHORIZATION=f"JWT {ctx['other_token']}", + ) + assert response.status_code == HTTP_200_OK + data = response.json() + view_data = next(v for v in data if v["id"] == ctx["view"].id) + default_values = view_data["default_row_values"] + field_ids = {dv["field"] for dv in default_values} + assert ctx["visible_field"].id in field_ids + assert ctx["hidden_field"].id not in field_ids + + +@pytest.mark.django_db +@override_settings(DEBUG=True) +def test_default_values_list_views_viewer_sees_none( + enterprise_data_fixture, api_client +): + ctx = _setup_default_values_test(enterprise_data_fixture) + + no_access_role = Role.objects.get(uid="NO_ACCESS") + viewer_role = Role.objects.get(uid="VIEWER") + RoleAssignmentHandler().assign_role( + ctx["other_user"], + ctx["workspace"], + role=no_access_role, + scope=ctx["workspace"], + ) + RoleAssignmentHandler().assign_role( + ctx["other_user"], + ctx["workspace"], + role=viewer_role, + scope=View.objects.get(id=ctx["view"].id), + ) + + response = api_client.get( + reverse("api:database:views:list", kwargs={"table_id": ctx["table"].id}) + + "?include=default_row_values", + HTTP_AUTHORIZATION=f"JWT {ctx['other_token']}", + ) + assert response.status_code == HTTP_200_OK + data = response.json() + view_data = next(v for v in data if v["id"] == ctx["view"].id) + default_values = view_data["default_row_values"] + assert default_values == [] + + +@pytest.mark.django_db +@override_settings(DEBUG=True) +def test_default_values_list_views_no_n_plus_one_queries( + enterprise_data_fixture, api_client +): + enterprise_data_fixture.enable_enterprise() + + admin, admin_token = enterprise_data_fixture.create_user_and_token() + editor_user, editor_token = enterprise_data_fixture.create_user_and_token() + workspace = enterprise_data_fixture.create_workspace( + user=admin, members=[editor_user] + ) + database = enterprise_data_fixture.create_database_application(workspace=workspace) + table = enterprise_data_fixture.create_database_table(database=database) + visible_field = enterprise_data_fixture.create_text_field(table=table, primary=True) + hidden_field = enterprise_data_fixture.create_text_field(table=table) + + no_access_role = Role.objects.get(uid="NO_ACCESS") + editor_role = Role.objects.get(uid="EDITOR") + RoleAssignmentHandler().assign_role( + editor_user, workspace, role=no_access_role, scope=workspace + ) + + def _create_restricted_view_with_defaults(): + view = enterprise_data_fixture.create_grid_view( + table=table, ownership_type=RestrictedViewOwnershipType.type + ) + _set_field_hidden(view, hidden_field, visible_fields=[visible_field]) + ViewHandler().update_view_default_values( + user=admin, + view=view, + items=[ + {"field": visible_field.id, "enabled": True, "value": "vis"}, + {"field": hidden_field.id, "enabled": True, "value": "hid"}, + ], + ) + RoleAssignmentHandler().assign_role( + editor_user, + workspace, + role=editor_role, + scope=View.objects.get(id=view.id), + ) + return view + + # Create one view and measure the query count. + _create_restricted_view_with_defaults() + + url = ( + reverse("api:database:views:list", kwargs={"table_id": table.id}) + + "?include=default_row_values" + ) + + response = api_client.get(url, HTTP_AUTHORIZATION=f"JWT {editor_token}") + assert response.status_code == HTTP_200_OK + # Warm up caches (content types, etc.) by making the first request above. + + with CaptureQueriesContext(connection) as context_one_view: + response = api_client.get(url, HTTP_AUTHORIZATION=f"JWT {editor_token}") + assert response.status_code == HTTP_200_OK + baseline_query_count = len(context_one_view) + + # Create two more views. + _create_restricted_view_with_defaults() + _create_restricted_view_with_defaults() + + with CaptureQueriesContext(connection) as context_three_views: + response = api_client.get(url, HTTP_AUTHORIZATION=f"JWT {editor_token}") + assert response.status_code == HTTP_200_OK + three_views_query_count = len(context_three_views) + + # Verify all three views have filtered default values (only visible field). + data = response.json() + for view_data in data: + default_values = view_data["default_row_values"] + assert len(default_values) == 1 + assert default_values[0]["field"] == visible_field.id + + # The query count should be the same regardless of view count. + assert three_views_query_count == baseline_query_count + + +@pytest.mark.django_db +@override_settings(DEBUG=True) +def test_default_values_get_view_editor_sees_visible_only( + enterprise_data_fixture, api_client +): + ctx = _setup_default_values_test(enterprise_data_fixture) + + no_access_role = Role.objects.get(uid="NO_ACCESS") + editor_role = Role.objects.get(uid="EDITOR") + RoleAssignmentHandler().assign_role( + ctx["other_user"], + ctx["workspace"], + role=no_access_role, + scope=ctx["workspace"], + ) + RoleAssignmentHandler().assign_role( + ctx["other_user"], + ctx["workspace"], + role=editor_role, + scope=View.objects.get(id=ctx["view"].id), + ) + + response = api_client.get( + reverse("api:database:views:item", kwargs={"view_id": ctx["view"].id}) + + "?include=default_row_values", + HTTP_AUTHORIZATION=f"JWT {ctx['other_token']}", + ) + assert response.status_code == HTTP_200_OK + data = response.json() + default_values = data["default_row_values"] + field_ids = {dv["field"] for dv in default_values} + assert ctx["visible_field"].id in field_ids + assert ctx["hidden_field"].id not in field_ids diff --git a/enterprise/web-frontend/modules/baserow_enterprise/components/dataSync/LocalBaserowTableDataSync.vue b/enterprise/web-frontend/modules/baserow_enterprise/components/dataSync/LocalBaserowTableDataSync.vue index ddd07a07b4..ea822a0d00 100644 --- a/enterprise/web-frontend/modules/baserow_enterprise/components/dataSync/LocalBaserowTableDataSync.vue +++ b/enterprise/web-frontend/modules/baserow_enterprise/components/dataSync/LocalBaserowTableDataSync.vue @@ -262,6 +262,7 @@ export default { false, false, false, + false, false ) this.views = data diff --git a/premium/backend/src/baserow_premium/permission_manager.py b/premium/backend/src/baserow_premium/permission_manager.py index caa45266ed..75e1fc2082 100644 --- a/premium/backend/src/baserow_premium/permission_manager.py +++ b/premium/backend/src/baserow_premium/permission_manager.py @@ -32,6 +32,7 @@ ReadAdjacentViewRowOperationType, ReadAggregationsViewOperationType, ReadViewDecorationOperationType, + ReadViewDefaultValuesOperationType, ReadViewFieldOptionsOperationType, ReadViewFilterGroupOperationType, ReadViewFilterOperationType, @@ -41,6 +42,7 @@ ReadViewSortOperationType, RestoreViewOperationType, UpdateViewDecorationOperationType, + UpdateViewDefaultValuesOperationType, UpdateViewFieldOptionsOperationType, UpdateViewFilterGroupOperationType, UpdateViewFilterOperationType, @@ -96,6 +98,8 @@ def __init__(self): ReadViewSortOperationType.type, UpdateViewSortOperationType.type, UpdateViewFieldOptionsOperationType.type, + ReadViewDefaultValuesOperationType.type, + UpdateViewDefaultValuesOperationType.type, DeleteViewSortOperationType.type, ReadViewOperationType.type, UpdateViewOperationType.type, diff --git a/premium/backend/tests/baserow_premium_tests/api/views/views/test_premium_views.py b/premium/backend/tests/baserow_premium_tests/api/views/views/test_premium_views.py index 9107d2b0f3..ccf3439614 100644 --- a/premium/backend/tests/baserow_premium_tests/api/views/views/test_premium_views.py +++ b/premium/backend/tests/baserow_premium_tests/api/views/views/test_premium_views.py @@ -294,3 +294,51 @@ def test_create_personal_grid_view_with_license(api_client, premium_data_fixture ) assert response.status_code == HTTP_200_OK assert response.json()["ownership_type"] == "personal" + + +@pytest.mark.django_db +@override_settings(DEBUG=True) +def test_personal_view_default_values_applied_to_new_row( + api_client, premium_data_fixture +): + user, token = premium_data_fixture.create_user_and_token( + has_active_premium_license=True + ) + table = premium_data_fixture.create_database_table(user=user) + text_field = premium_data_fixture.create_text_field(table=table) + number_field = premium_data_fixture.create_number_field(table=table) + + # Create a personal view via the API. + create_view_response = api_client.post( + reverse("api:database:views:list", kwargs={"table_id": table.id}), + {"name": "My personal view", "type": "grid", "ownership_type": "personal"}, + format="json", + HTTP_AUTHORIZATION=f"JWT {token}", + ) + assert create_view_response.status_code == HTTP_200_OK + view_id = create_view_response.json()["id"] + + # Set default values on the personal view. + patch_response = api_client.patch( + reverse("api:database:views:default_values", kwargs={"view_id": view_id}), + [ + {"field": text_field.id, "enabled": True, "value": "personal default"}, + {"field": number_field.id, "enabled": True, "value": "42"}, + ], + format="json", + HTTP_AUTHORIZATION=f"JWT {token}", + ) + assert patch_response.status_code == HTTP_200_OK + + # Create a row without providing any values, using the personal view. + create_row_response = api_client.post( + reverse("api:database:rows:list", kwargs={"table_id": table.id}) + + f"?view={view_id}", + {}, + format="json", + HTTP_AUTHORIZATION=f"JWT {token}", + ) + assert create_row_response.status_code == HTTP_200_OK + row_data = create_row_response.json() + assert row_data[f"field_{text_field.id}"] == "personal default" + assert row_data[f"field_{number_field.id}"] == "42" diff --git a/premium/backend/tests/baserow_premium_tests/views/test_premium_ws_view_signals.py b/premium/backend/tests/baserow_premium_tests/views/test_premium_ws_view_signals.py index d2326336a2..cd765b17a0 100644 --- a/premium/backend/tests/baserow_premium_tests/views/test_premium_ws_view_signals.py +++ b/premium/backend/tests/baserow_premium_tests/views/test_premium_ws_view_signals.py @@ -214,6 +214,7 @@ def test_view_updated_to_personal_signals( sortings=False, decorations=False, group_bys=False, + default_row_values=True, ).data ) @@ -257,6 +258,7 @@ def test_view_updated_to_collaborative_signals( sortings=True, decorations=True, group_bys=True, + default_row_values=True, ).data ) assert call_args_to_users[0][1] == user.web_socket_id @@ -275,6 +277,7 @@ def test_view_updated_to_collaborative_signals( sortings=False, decorations=False, group_bys=False, + default_row_values=True, ).data ) @@ -326,6 +329,7 @@ def test_broadcast_to_users_ownership_changed( sortings=False, decorations=False, group_bys=False, + default_row_values=True, ).data, } diff --git a/premium/web-frontend/modules/baserow_premium/fieldTypes.js b/premium/web-frontend/modules/baserow_premium/fieldTypes.js index 9ae9ebe1b5..aa2d12d8a0 100644 --- a/premium/web-frontend/modules/baserow_premium/fieldTypes.js +++ b/premium/web-frontend/modules/baserow_premium/fieldTypes.js @@ -36,6 +36,10 @@ export class AIFieldType extends FieldType { return false } + canBeDefaultValue() { + return false + } + getGridViewFieldComponent() { return GridViewFieldAI } diff --git a/premium/web-frontend/modules/baserow_premium/permissionManagerTypes.js b/premium/web-frontend/modules/baserow_premium/permissionManagerTypes.js index 4e577fb31a..024e74d65a 100644 --- a/premium/web-frontend/modules/baserow_premium/permissionManagerTypes.js +++ b/premium/web-frontend/modules/baserow_premium/permissionManagerTypes.js @@ -21,6 +21,7 @@ export class ViewOwnershipPermissionManagerType extends PermissionManagerType { 'database.table.view.update_field_options', 'database.table.view.decoration.update', 'database.table.view.decoration.delete', + 'database.table.view.update_default_values', ] const { $store } = this.app const userId = $store.getters['auth/getUserId'] diff --git a/web-frontend/locales/en.json b/web-frontend/locales/en.json index 63cd341a5e..b6f9ea7d34 100644 --- a/web-frontend/locales/en.json +++ b/web-frontend/locales/en.json @@ -169,7 +169,8 @@ "formViewEditRowShareWarning": "Anyone with the shared link can edit rows via the {formNames} form through the publicly visible edit row link fields.|Anyone with the shared link can edit rows via the {formNames} forms through the publicly visible edit row link field.", "ai": "AI prompt", "multipleCollaboratorsDropdown": "Dropdown", - "multipleCollaboratorsCheckboxes": "Checkboxes" + "multipleCollaboratorsCheckboxes": "Checkboxes", + "defaultValueFunctionNow": "Current date" }, "fieldErrors": { "invalidNumber": "Invalid number", @@ -180,6 +181,7 @@ "invalidPhoneNumber": "Invalid Phone Number", "invalidDuration": "Invalid format ({durationFormat}).", "overflowDuration": "Value is out of bounds.", + "higherThan": "Value is higher than {max}.", "maxChars": "Max {max} chars.", "minChars": "Min {min} chars." }, diff --git a/web-frontend/modules/database/components/field/FieldFormViewEditRowSubForm.vue b/web-frontend/modules/database/components/field/FieldFormViewEditRowSubForm.vue index 7c16ee3b9f..360cfb33f7 100644 --- a/web-frontend/modules/database/components/field/FieldFormViewEditRowSubForm.vue +++ b/web-frontend/modules/database/components/field/FieldFormViewEditRowSubForm.vue @@ -98,6 +98,7 @@ export default { false, false, false, + false, false ) views = data diff --git a/web-frontend/modules/database/components/field/FieldLinkRowSubForm.vue b/web-frontend/modules/database/components/field/FieldLinkRowSubForm.vue index 5d7bcd5d5c..c2d0bdf862 100644 --- a/web-frontend/modules/database/components/field/FieldLinkRowSubForm.vue +++ b/web-frontend/modules/database/components/field/FieldLinkRowSubForm.vue @@ -224,6 +224,7 @@ export default { false, false, false, + false, false ) // Because the field types are accessible for everyone, we only want to list diff --git a/web-frontend/modules/database/components/row/RowCreateModal.vue b/web-frontend/modules/database/components/row/RowCreateModal.vue index e09927e213..14cbff06e8 100644 --- a/web-frontend/modules/database/components/row/RowCreateModal.vue +++ b/web-frontend/modules/database/components/row/RowCreateModal.vue @@ -171,12 +171,38 @@ export default { methods: { show(defaults = {}, ...args) { const row = {} + const defaultItems = this.view?.default_row_values || [] + const defaultsByFieldId = {} + for (const item of defaultItems) { + if (item.enabled && (item.value != null || item.function)) { + defaultsByFieldId[item.field] = item + } + } this.allFields.forEach((field) => { const name = `field_${field.id}` + const fieldType = this.$registry.get('field', field._.type.type) + const dvItem = defaultsByFieldId[field.id] + const supportedFunctions = fieldType + .getSupportedDefaultValueFunctions() + .map((f) => f.name) if (this.presets[name] !== undefined) { row[name] = this.presets[name] + } else if ( + dvItem && + dvItem.function && + supportedFunctions.includes(dvItem.function) + ) { + row[name] = fieldType.resolveDefaultValueFunction( + dvItem.function, + field + ) + } else if ( + dvItem && + dvItem.value != null && + (!dvItem.field_type || dvItem.field_type === field._.type.type) + ) { + row[name] = fieldType.parseDefaultRowValue(field, dvItem.value) } else { - const fieldType = this.$registry.get('field', field._.type.type) row[name] = fieldType.getNewRowValue(field) } }) diff --git a/web-frontend/modules/database/components/row/RowEditFieldLinkRow.vue b/web-frontend/modules/database/components/row/RowEditFieldLinkRow.vue index ef98e244c9..447e4d3268 100644 --- a/web-frontend/modules/database/components/row/RowEditFieldLinkRow.vue +++ b/web-frontend/modules/database/components/row/RowEditFieldLinkRow.vue @@ -7,7 +7,11 @@ class="field-link-row__item" > @@ -37,7 +41,7 @@ @@ -51,7 +55,7 @@ {{ error }}
@@ -68,6 +69,7 @@ :view="view" :table="table" :views="views" + :store-prefix="storePrefix" @enable-rename="$refs.rename.edit()" > diff --git a/web-frontend/modules/database/components/table/TableTemplate.vue b/web-frontend/modules/database/components/table/TableTemplate.vue index 02cdb98566..3a7cf4427a 100644 --- a/web-frontend/modules/database/components/table/TableTemplate.vue +++ b/web-frontend/modules/database/components/table/TableTemplate.vue @@ -94,6 +94,7 @@ export default { true, true, true, + true, true ) viewsData.forEach((part, index, d) => { diff --git a/web-frontend/modules/database/components/view/DefaultValuesModal.vue b/web-frontend/modules/database/components/view/DefaultValuesModal.vue new file mode 100644 index 0000000000..ac1323c1f9 --- /dev/null +++ b/web-frontend/modules/database/components/view/DefaultValuesModal.vue @@ -0,0 +1,298 @@ + + + diff --git a/web-frontend/modules/database/components/view/ViewContext.vue b/web-frontend/modules/database/components/view/ViewContext.vue index e33e048f71..a8c61129fa 100644 --- a/web-frontend/modules/database/components/view/ViewContext.vue +++ b/web-frontend/modules/database/components/view/ViewContext.vue @@ -89,6 +89,22 @@ {{ $t('viewContext.webhooks') }} +
  • + + + {{ $t('viewContext.defaultRowValues') }} + +
  • + @@ -148,6 +171,7 @@ import ImportFileModal from '@baserow/modules/database/components/table/ImportFi import { notifyIf } from '@baserow/modules/core/utils/error' import ExportTableModal from '@baserow/modules/database/components/export/ExportTableModal' import WebhookModal from '@baserow/modules/database/components/webhook/WebhookModal.vue' +import DefaultValuesModal from '@baserow/modules/database/components/view/DefaultValuesModal.vue' export default { name: 'ViewContext', @@ -155,6 +179,7 @@ export default { ExportTableModal, WebhookModal, ImportFileModal, + DefaultValuesModal, }, mixins: [context], props: { @@ -170,6 +195,11 @@ export default { type: Object, required: true, }, + storePrefix: { + type: String, + required: false, + default: '', + }, }, emits: ['enable-rename'], data() { @@ -182,6 +212,10 @@ export default { hasValidExporter() { return viewTypeHasExporterTypes(this.view.type, this.$registry) }, + canSetDefaultValues() { + const viewType = this.$registry.get('view', this.view.type) + return viewType.canSetDefaultValues + }, ...mapGetters({ fields: 'field/getAll', }), @@ -263,6 +297,10 @@ export default { this.$refs.context.hide() this.$refs.webhookModal.show() }, + openDefaultValuesModal() { + this.$refs.context.hide() + this.$refs.defaultValuesModal.show() + }, }, } diff --git a/web-frontend/modules/database/components/view/ViewsContext.vue b/web-frontend/modules/database/components/view/ViewsContext.vue index b5b4abd742..9878e685fc 100644 --- a/web-frontend/modules/database/components/view/ViewsContext.vue +++ b/web-frontend/modules/database/components/view/ViewsContext.vue @@ -54,6 +54,7 @@ :view="view" :table="table" :read-only="readOnly" + :store-prefix="storePrefix" @selected="selectedView" > @@ -115,6 +116,10 @@ export default { required: false, default: true, }, + storePrefix: { + type: String, + required: true, + }, }, emits: ['selected-view'], data() { diff --git a/web-frontend/modules/database/components/view/ViewsContextItem.vue b/web-frontend/modules/database/components/view/ViewsContextItem.vue index 4a0f652066..cc48432382 100644 --- a/web-frontend/modules/database/components/view/ViewsContextItem.vue +++ b/web-frontend/modules/database/components/view/ViewsContextItem.vue @@ -51,6 +51,7 @@ :database="database" :table="table" :view="view" + :store-prefix="storePrefix" @enable-rename="enableRename" > @@ -84,6 +85,10 @@ export default { required: false, default: true, }, + storePrefix: { + type: String, + required: true, + }, }, emits: ['selected'], computed: { diff --git a/web-frontend/modules/database/components/view/grid/fields/GridViewFieldLinkRow.vue b/web-frontend/modules/database/components/view/grid/fields/GridViewFieldLinkRow.vue index 2059dc2f1a..d1a4649e0b 100644 --- a/web-frontend/modules/database/components/view/grid/fields/GridViewFieldLinkRow.vue +++ b/web-frontend/modules/database/components/view/grid/fields/GridViewFieldLinkRow.vue @@ -113,39 +113,6 @@ export default { } }, computed: { - // Return the reactive object that can be updated in runtime. - workspace() { - return this.$store.getters['workspace/get'](this.workspaceId) - }, - canAccessLinkedTable() { - const linkedTable = this.allTables.find( - ({ id }) => id === this.field.link_row_table_id - ) - - if (!linkedTable) { - return false - } - - return ( - this.$hasPermission( - 'database.table.read', - linkedTable, - this.workspace.id - ) && !this.readOnly - ) - }, - allTables() { - const databaseType = DatabaseApplicationType.getType() - return this.$store.getters['application/getAll'].reduce( - (tables, application) => { - if (application.type === databaseType) { - return tables.concat(application.tables || []) - } - return tables - }, - [] - ) - }, publicGrid() { return this.$store.getters['page/view/public/getIsPublic'] }, diff --git a/web-frontend/modules/database/fieldTypes.js b/web-frontend/modules/database/fieldTypes.js index c0aa93635b..393e238944 100644 --- a/web-frontend/modules/database/fieldTypes.js +++ b/web-frontend/modules/database/fieldTypes.js @@ -338,6 +338,48 @@ export class FieldType extends Registerable { return this.getCardComponent(field).height || 0 } + /** + * Indicates whether this field type is compatible with the default values + * feature. By default all writable field types are compatible. Override and + * return `false` for field types whose row-edit component or write behaviour + * is incompatible with default value setting (e.g. the AI field). + */ + canBeDefaultValue() { + return true + } + + /** + * Returns a list of supported default value functions for this field type. + * Each item is an object with `name` and `label` properties. + * Override in field types that support dynamic defaults (e.g. date fields). + */ + getSupportedDefaultValueFunctions() { + return [] + } + + /** + * Resolves a default value function to an actual value for optimistic display. + * Override in field types that support functions. + */ + resolveDefaultValueFunction(functionName, field) { + return null + } + + /** + * Converts a raw default value (stored in API request format) into the + * frontend's internal row representation so that it can be displayed and + * later passed through `prepareValueForUpdate` correctly. + * + * By default returns the value as-is. Override in field types where the + * request format differs from the frontend representation (e.g. + * single_select stores an ID but the frontend expects an option object, + * multiple_select stores [id, ...] but the frontend expects [{id, value, + * color}, ...]). + */ + parseDefaultRowValue(field, value) { + return value + } + /** * Should return the empty value for the field type. */ @@ -2079,6 +2121,29 @@ export class RatingFieldType extends FieldType { return valueParsed } + prepareValueForUpdate(field, value) { + if (value > field.max_value) { + return field.max_value + } + return value + } + + getValidationError(field, value) { + const valueParsed = parseInt(value, 10) + + if (isNaN(valueParsed) || valueParsed < 0) { + return this.app.$i18n.t('fieldErrors.invalidNumber') + } + + if (valueParsed > field.max_value) { + return this.app.$i18n.t('fieldErrors.higherThan', { + max: field.max_value, + }) + } + + return null + } + getCanImport() { return true } @@ -2500,6 +2565,22 @@ export class DateFieldType extends BaseDateFieldType { return i18n.t('fieldType.date') } + getSupportedDefaultValueFunctions() { + const { $i18n: i18n } = this.app + return [{ name: 'now', label: i18n.t('fieldType.defaultValueFunctionNow') }] + } + + resolveDefaultValueFunction(functionName, field) { + if (functionName === 'now') { + const now = new Date() + if (field.date_include_time) { + return now.toISOString() + } + return now.toISOString().split('T')[0] + } + return null + } + getGridViewFieldComponent() { return GridViewFieldDate } @@ -3610,6 +3691,17 @@ export class SingleSelectFieldType extends SelectOptionBaseFieldType { return value ? { value } : null } + parseDefaultRowValue(field, value) { + if (value === null || value === undefined) { + return null + } + // Raw value is an option ID; resolve to the full option object. + if (typeof value !== 'object') { + return field.select_options.find((opt) => opt.id === value) || null + } + return value + } + prepareValueForUpdate(field, value) { if (value === undefined || value === null) { return null @@ -3861,6 +3953,21 @@ export class MultipleSelectFieldType extends SelectOptionBaseFieldType { } } + parseDefaultRowValue(field, value) { + if (!Array.isArray(value)) { + return [] + } + // Raw value is an array of option IDs; resolve to full option objects. + return value + .map((item) => { + if (typeof item === 'object' && item !== null) { + return item + } + return field.select_options.find((opt) => opt.id === item) || null + }) + .filter(Boolean) + } + prepareValueForUpdate(field, value) { if (value === undefined || value === null) { return [] @@ -4749,6 +4856,10 @@ export class MultipleCollaboratorsFieldType extends FieldType { return _.isEqual(value1Ids, value2Ids) } + + getEmptyValue(field) { + return [] + } } export class UUIDFieldType extends FieldType { diff --git a/web-frontend/modules/database/locales/en.json b/web-frontend/modules/database/locales/en.json index e321308965..4e27ba1964 100644 --- a/web-frontend/modules/database/locales/en.json +++ b/web-frontend/modules/database/locales/en.json @@ -635,6 +635,7 @@ "viewContext": { "exportView": "Export view", "duplicateView": "Duplicate view", + "defaultRowValues": "Default row values", "renameView": "Rename view", "toPersonal": "To personal", "toCollaborative": "To collaborative", @@ -642,6 +643,12 @@ "importFile": "Import file", "deleteView": "Delete view" }, + "defaultValuesModal": { + "title": "Default values for {name}", + "setDefaultValue": "Set default value", + "removeDefaultValue": "Remove default value", + "staticValue": "Static value" + }, "deleteViewModal": { "title": "Delete {name}", "description": "Are you sure you want to delete the view {name}? The table data will be preserved, but the filters, sortings and field widths related to the view will be deleted.", diff --git a/web-frontend/modules/database/mixins/linkRowField.js b/web-frontend/modules/database/mixins/linkRowField.js index 7b24fd67ba..2a44c0a9d4 100644 --- a/web-frontend/modules/database/mixins/linkRowField.js +++ b/web-frontend/modules/database/mixins/linkRowField.js @@ -1,5 +1,6 @@ import { getPrimaryOrFirstField } from '@baserow/modules/database/utils/field' import BigNumber from 'bignumber.js' +import { DatabaseApplicationType } from '@baserow/modules/database/applicationTypes' export default { emits: ['update'], @@ -14,6 +15,39 @@ export default { } }, computed: { + // Return the reactive object that can be updated in runtime. + workspace() { + return this.$store.getters['workspace/get'](this.workspaceId) + }, + allTables() { + const databaseType = DatabaseApplicationType.getType() + return this.$store.getters['application/getAll'].reduce( + (tables, application) => { + if (application.type === databaseType) { + return tables.concat(application.tables || []) + } + return tables + }, + [] + ) + }, + canAccessLinkedTable() { + const linkedTable = this.allTables.find( + ({ id }) => id === this.field.link_row_table_id + ) + + if (!linkedTable) { + return false + } + + return ( + this.$hasPermission( + 'database.table.read', + linkedTable, + this.workspace.id + ) && !this.readOnly + ) + }, /** * Returns the value of the field that can be used when creating a new row * in the linked table starting from the current row. diff --git a/web-frontend/modules/database/realtime.js b/web-frontend/modules/database/realtime.js index 987a31a410..473c0c435d 100644 --- a/web-frontend/modules/database/realtime.js +++ b/web-frontend/modules/database/realtime.js @@ -349,6 +349,16 @@ export const registerRealtimeEvents = (realtime) => { } }) + realtime.registerEvent( + 'force_view_refresh_and_default_values', + async ({ store }, data) => { + const view = store.getters['view/get'](data.view_id) + if (view !== undefined) { + await store.dispatch('view/refreshViewAndDefaultValues', { view }) + } + } + ) + realtime.registerEvent('view_filter_created', ({ store, app }, data) => { const view = store.getters['view/get'](data.view_filter.view) if (view !== undefined) { diff --git a/web-frontend/modules/database/services/view.js b/web-frontend/modules/database/services/view.js index 9419c272fe..9c18827d05 100644 --- a/web-frontend/modules/database/services/view.js +++ b/web-frontend/modules/database/services/view.js @@ -10,6 +10,7 @@ export default (client) => { includeSortings = false, includeGroupBys = false, includeDecorations = false, + includeDefaultRowValues = false, limit = null, type = null ) { @@ -34,6 +35,10 @@ export default (client) => { include.push('decorations') } + if (includeDefaultRowValues) { + include.push('default_row_values') + } + if (include.length > 0) { config.params.include = include.join(',') } @@ -60,7 +65,8 @@ export default (client) => { includeFilters = false, includeSortings = false, includeDecorations = false, - includeGroupBys = false + includeGroupBys = false, + includeDefaultRowValues = false ) { const config = { params: {}, @@ -82,6 +88,10 @@ export default (client) => { include.push('group_bys') } + if (includeDefaultRowValues) { + include.push('default_row_values') + } + if (include.length > 0) { config.params.include = include.join(',') } @@ -168,5 +178,8 @@ export default (client) => { } return client.get(`/database/views/${viewSlug}/row/${rowId}/`, config) }, + updateDefaultValues(viewId, items) { + return client.patch(`/database/views/${viewId}/default-values/`, items) + }, } } diff --git a/web-frontend/modules/database/store/view.js b/web-frontend/modules/database/store/view.js index 35f630b8b8..82847fef82 100644 --- a/web-frontend/modules/database/store/view.js +++ b/web-frontend/modules/database/store/view.js @@ -103,6 +103,10 @@ export function populateView(view, registry) { view.decorations = [] } + if (!Object.prototype.hasOwnProperty.call(view, 'default_row_values')) { + view.default_row_values = [] + } + return type.populate(view) } @@ -348,6 +352,7 @@ export const actions = { true, true, true, + true, true ) data.forEach((part, index, d) => { @@ -514,6 +519,33 @@ export const actions = { registry: registry || (repopulate ? this.$registry : null), }) }, + /** + * Fetches the view from the server (without filters, sortings, decorations, or + * group_bys, but with default_row_values) and updates only the view properties + * and default values in the store without touching the existing filters, sorts, etc. + */ + async refreshViewAndDefaultValues({ commit }, { view }) { + const { $client } = this + const { data } = await ViewService($client).get( + view.id, + false, + false, + false, + false, + true + ) + + // Only update the view properties and default_row_values. We don't want to + // overwrite filters, sortings, decorations, or group_bys that are already + // in the store. + const { filters, sortings, decorations, group_bys, ...viewValues } = data + commit('UPDATE_ITEM', { + id: view.id, + view, + values: viewValues, + repopulate: false, + }) + }, /** * Duplicates an existing view. */ diff --git a/web-frontend/modules/database/store/view/grid.js b/web-frontend/modules/database/store/view/grid.js index 6a54c0a813..f70b1308b5 100644 --- a/web-frontend/modules/database/store/view/grid.js +++ b/web-frontend/modules/database/store/view/grid.js @@ -2074,12 +2074,45 @@ export const actions = { `table_${table.id}` ) const taskId = taskQueue.add(async () => { - // Create an object of default field values that can be used to fill the row with - // missing default values + // Create an object of default field values that can be used to fill the row. If + // the view has default row values configured, those take precedence over the + // field type's default value. + const defaultItems = view.default_row_values + const defaultsByFieldId = {} + for (const item of defaultItems) { + if (item.enabled && (item.value != null || item.function)) { + defaultsByFieldId[item.field] = item + } + } const fieldNewRowValueMap = fields.reduce((map, field) => { const name = `field_${field.id}` const fieldType = $registry.get('field', field._.type.type) - map[name] = fieldType.getNewRowValue(field) + const defaultViewItem = defaultsByFieldId[field.id] + const supportedFunctions = fieldType + .getSupportedDefaultValueFunctions() + .map((f) => f.name) + if ( + defaultViewItem && + defaultViewItem.function && + supportedFunctions.includes(defaultViewItem.function) + ) { + map[name] = fieldType.resolveDefaultValueFunction( + defaultViewItem.function, + field + ) + } else if ( + defaultViewItem && + defaultViewItem.value != null && + (!defaultViewItem.field_type || + defaultViewItem.field_type === field._.type.type) + ) { + map[name] = fieldType.parseDefaultRowValue( + field, + defaultViewItem.value + ) + } else { + map[name] = fieldType.getNewRowValue(field) + } return map }, {}) diff --git a/web-frontend/modules/database/viewTypes.js b/web-frontend/modules/database/viewTypes.js index 28c187eeb2..3d1e37a450 100644 --- a/web-frontend/modules/database/viewTypes.js +++ b/web-frontend/modules/database/viewTypes.js @@ -83,6 +83,13 @@ export class ViewType extends Registerable { return false } + /** + * Indicates whether it is possible to set default row values for this view. + */ + canSetDefaultValues() { + return true + } + constructor(...args) { super(...args) this.type = this.getType() @@ -92,6 +99,7 @@ export class ViewType extends Registerable { this.canSort = this.canSort() this.canGroupBy = this.canGroupBy() this.canShare = this.canShare() + this.canSetDefaultValues = this.canSetDefaultValues() if (this.type === null) { throw new Error('The type name of a view type must be set.') @@ -1261,6 +1269,10 @@ export class FormViewType extends ViewType { return true } + canSetDefaultValues() { + return false + } + getPublicRoute() { return 'database-table-form' }