diff --git a/observations/templates/observations/timeseries.html b/observations/templates/observations/timeseries.html
index 215a66e926fe408a09bf07f4fe109fae91171081..8c9f923446b0dce3cf1adaf8884c8eb2d20cddd3 100644
--- a/observations/templates/observations/timeseries.html
+++ b/observations/templates/observations/timeseries.html
@@ -1 +1,149 @@
-<h1>TIMESERIES {{ observation_time_series_id }}</h1>
\ No newline at end of file
+{% extends "base.html" %}
+{% load i18n l10n static %}
+{% comment %}
+    #
+    # Copyright (c) 2024 NIBIO <http://www.nibio.no/>.
+    #
+    # This file is part of VIPSWeb.
+    # VIPSWeb is free software: you can redistribute it and/or modify
+    # it under the terms of the NIBIO Open Source License as published by
+    # NIBIO, either version 1 of the License, or (at your option) any
+    # later version.
+    #
+    # VIPSWeb is distributed in the hope that it will be useful,
+    # but WITHOUT ANY WARRANTY; without even the implied warranty of
+    # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    # NIBIO Open Source License for more details.
+    #
+    # You should have received a copy of the NIBIO Open Source License
+    # along with VIPSWeb.  If not, see <http://www.nibio.no/licenses/>.
+    #
+{% endcomment %}
+{% load i18n %}
+{% block title%}{% trans "Time series" %}{%endblock%}
+{% block content %}
+    <div class="singleBlockContainer">
+        <div class="row">
+            <div class="col-md-6">
+                <h1>{% trans "Time series" %}</h1>
+                <p><a href="/observations" class="btn btn-default back" role="button">{% trans "View all observations" %}</a></p>
+                <h4>{% trans "Organism" %}</h4>
+                <p id="organismName"></p>
+                <h4>{% trans "Crop" %}</h4>
+                <p id="cropOrganismName"></p>
+                <h2 id="timeSeriesName"></h2>
+                <p id="timeSeriesDescription"></p>
+            </div>
+            <div class="col-md-6">
+                <div id="observationViewMap" class="map" style="height: 400px;"></div>
+            </div>
+        </div>
+        <div class="row singleBlockContainer">
+            <div class="col-md-12">
+                <div id="observationTable" class="table-responsive"></div>
+            </div>
+        </div>
+        <div style="display: none;"><div id="poiMarker" title="Marker"><img src="{% static "observations/images/observation_marker.png" %}"/></div></div>
+    </div>
+{% endblock %}
+{% block customCSS %}
+    <link rel="stylesheet" href="{% static "css/3rdparty/ol.css" %}" type="text/css">
+{% endblock %}
+{% block customJS %}
+    <script type="text/javascript" src="{% url "javascript-catalog" %}"></script>
+    <script type="text/javascript" src="{% static "js/3rdparty/moment.min.js" %}"></script>
+    <script type="text/javascript" src="{% static "js/3rdparty/ol.js" %}"></script>
+    <script type="text/javascript" src="{% url "views.settings_js" %}"></script>
+    <script type="text/javascript" src="{% static "js/util.js" %}"></script>
+    <script type="text/javascript" src="{% static "observations/js/observationViewMap.js" %}"></script>
+    <script type="text/javascript">
+        $(document).ready(function() {
+            var uuidParam = settings.userUuid != null ? "?userUUID=" + settings.userUuid : "";
+            $.getJSON( "/vipslogicproxy/rest/observationtimeseries/{{observation_time_series_id}}/" + uuidParam , function( observationTimeSeries ) {
+                //console.log(observation);
+                document.getElementById("organismName").innerHTML = getLocalizedOrganismName(observationTimeSeries.organism) + " <i>(" + observationTimeSeries.organism.latinName + ")</i>";
+                document.getElementById("cropOrganismName").innerHTML = getLocalizedOrganismName(observationTimeSeries.cropOrganism) + " <i>(" + observationTimeSeries.cropOrganism.latinName + ")</i>";
+                document.getElementById("timeSeriesName").innerHTML = observationTimeSeries.name;
+                document.getElementById("timeSeriesDescription").innerHTML = observationTimeSeries.description;
+
+                console.info("observationTimeSeries", observationTimeSeries);
+
+                let observations = [];
+                $.getJSON( "/vipslogicproxy/rest/observation/list/filter/{{ organization_id }}?observationTimeSeriesId={{ observation_time_series_id }}", function( observations ) {
+                    initTable(observations);
+                });
+
+                if(!observationTimeSeries.locationIsPrivate)
+                {
+                    if(observationTimeSeries.locationPointOfInterestId > 0)
+                    {
+                        $.getJSON(settings.vipslogicProtocol + "://" + settings.vipslogicServerName + "/rest/poi/" + observationTimeSeries.locationPointOfInterestId , function( poi ) {
+                            initMap(null,poi,"observationViewMap","{{settings.MAP_ATTRIBUTION|safe}}")
+                        });
+                    }
+                    else
+                    {
+                        initMap(observationTimeSeries.geoinfo,null,"observationViewMap","{{settings.MAP_ATTRIBUTION|safe}}");
+                    }
+                }
+                else
+                {
+                    renderLocationIsHiddenMessage();
+                }
+            });
+        });
+
+        function initTable(observations) {
+            const parent = document.getElementById("observationTable").parentNode;
+            parent.innerHTML = "";
+
+            if (!observations) {
+                return;
+            }
+
+            const dataSchema = JSON.parse(observations[0].observationDataSchema["dataSchema"])
+            let dataVars = {}
+            Object.keys(dataSchema['properties']).forEach(function(key) {
+                dataVars[key] = dataSchema['properties'][key]['title']
+            });
+            console.info("dataSchema", dataSchema);
+
+            const table = document.createElement("table");
+            table.className = "table table-striped"
+
+            const header = table.createTHead();
+            const headerRow = header.insertRow(0);
+            const headers = Object.keys(observations[0]);
+
+            const dateCell = headerRow.insertCell();
+            dateCell.outerHTML = `<th>Observasjonsdag</th>`;
+
+            Object.keys(dataVars).forEach((key, index) => {
+                const dataCell = headerRow.insertCell();
+                dataCell.outerHTML = "<th>" + dataVars[key] + "</th>";
+            });
+
+            const tbody = table.createTBody();
+            observations.forEach((observation, rowIndex) => {
+                const row = tbody.insertRow(rowIndex);
+                const dateCell = row.insertCell();
+                dateCell.innerText = getStandardFormattedDate(observation.timeOfObservation);
+
+                Object.keys(dataVars).forEach((key, index) => {
+                    const dataCell = row.insertCell();
+                    if (observation.observationData) {
+                        dataCell.innerText = JSON.parse(observation.observationData)[key];
+                    } else {
+                        dataCell.innerText = "";
+                    }
+                });
+            });
+            parent.appendChild(table);
+        }
+
+        function renderLocationIsHiddenMessage(){
+            document.getElementById("observationViewMap").parentNode.innerHTML =
+                "<h2>{% trans "Map view not available" %}</h2>";
+        }
+    </script>
+{% endblock %}
\ No newline at end of file
diff --git a/observations/views.py b/observations/views.py
index 31b680e98379a16e239798dee38ccc232d1e20d3..3ff5543a581ad262e516746cfc161d6eb858fccd 100755
--- a/observations/views.py
+++ b/observations/views.py
@@ -75,7 +75,12 @@ def detail(request, observation_id):
     return render(request, 'observations/detail.html', context)
 
 def timeseries(request, observation_time_series_id):
+    if request.session.get("vips_logic_user", None) != None:
+        organization_id = request.session["vips_logic_user"]["organization_id"]
+    else:
+        organization_id = settings.VIPS_ORGANIZATION_ID
     context = {
+        "organization_id": organization_id,
         "observation_time_series_id" : observation_time_series_id,
     }
     return render(request, 'observations/timeseries.html', context)
\ No newline at end of file