diff --git a/experimental/reporting-ui/src/main/react/reporting-ui/client/reporting/testing/BUILD.bazel b/experimental/reporting-ui/src/main/react/reporting-ui/client/reporting/testing/BUILD.bazel
index 4c0cbfc5670..c216f270c68 100644
--- a/experimental/reporting-ui/src/main/react/reporting-ui/client/reporting/testing/BUILD.bazel
+++ b/experimental/reporting-ui/src/main/react/reporting-ui/client/reporting/testing/BUILD.bazel
@@ -16,6 +16,7 @@ js_library(
"//:node_modules/react-dom",
"//experimental/reporting-ui/src/main/react/reporting-ui/client",
"//experimental/reporting-ui/src/main/react/reporting-ui/model/reporting",
+ "//experimental/reporting-ui/src/main/react/reporting-ui/public/asset/font",
],
)
diff --git a/experimental/reporting-ui/src/main/react/reporting-ui/client/reporting/testing/webpack.config.js b/experimental/reporting-ui/src/main/react/reporting-ui/client/reporting/testing/webpack.config.js
index 7febef2c85e..80934f87a77 100644
--- a/experimental/reporting-ui/src/main/react/reporting-ui/client/reporting/testing/webpack.config.js
+++ b/experimental/reporting-ui/src/main/react/reporting-ui/client/reporting/testing/webpack.config.js
@@ -46,5 +46,6 @@ module.exports = {
plugins: [new MiniCssExtractPlugin()],
devServer: {
static: path.resolve(__dirname, '../../../public'),
+ historyApiFallback: true,
},
};
diff --git a/experimental/reporting-ui/src/main/react/reporting-ui/component/card_wrapper/BUILD.bazel b/experimental/reporting-ui/src/main/react/reporting-ui/component/card_wrapper/BUILD.bazel
new file mode 100644
index 00000000000..4aafc257b41
--- /dev/null
+++ b/experimental/reporting-ui/src/main/react/reporting-ui/component/card_wrapper/BUILD.bazel
@@ -0,0 +1,14 @@
+load("@aspect_rules_js//js:defs.bzl", "js_library")
+
+package(
+ default_visibility = [
+ "//experimental/reporting-ui/src/main/react/reporting-ui:__subpackages__",
+ ],
+)
+
+js_library(
+ name = "card_wrapper",
+ srcs = [
+ "card_wrapper.tsx",
+ ],
+)
diff --git a/experimental/reporting-ui/src/main/react/reporting-ui/component/card_wrapper/card_wrapper.tsx b/experimental/reporting-ui/src/main/react/reporting-ui/component/card_wrapper/card_wrapper.tsx
new file mode 100644
index 00000000000..3dbbc6de334
--- /dev/null
+++ b/experimental/reporting-ui/src/main/react/reporting-ui/component/card_wrapper/card_wrapper.tsx
@@ -0,0 +1,38 @@
+// Copyright 2023 The Cross-Media Measurement Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import React from 'react';
+import Card from 'react-bootstrap/Card';
+
+type props = {
+ cardId: string,
+ title: string,
+ content: string,
+};
+
+const COMPONENT_STYLE = Object.freeze({
+ borderRadius: '12px',
+ boxShadow: '0px 2px 6px 2px rgba(0, 0, 0, 0.15), 0px 1px 2px 0px rgba(0, 0, 0, 0.30)',
+});
+
+export function CardWrapper({cardId, title, content}: props) {
+ return (
+
+
+ {title}
+ {content}
+
+
+ )
+}
diff --git a/experimental/reporting-ui/src/main/react/reporting-ui/index.css b/experimental/reporting-ui/src/main/react/reporting-ui/index.css
index fb454cb5344..4538eafc34e 100644
--- a/experimental/reporting-ui/src/main/react/reporting-ui/index.css
+++ b/experimental/reporting-ui/src/main/react/reporting-ui/index.css
@@ -12,6 +12,11 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */
+@font-face {
+ font-family: open-sans-light;
+ src: url(./public/asset/font/open-sans-light.ttf);
+}
+
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
diff --git a/experimental/reporting-ui/src/main/react/reporting-ui/index.tsx b/experimental/reporting-ui/src/main/react/reporting-ui/index.tsx
index 986db3f9a4c..da1224d2311 100644
--- a/experimental/reporting-ui/src/main/react/reporting-ui/index.tsx
+++ b/experimental/reporting-ui/src/main/react/reporting-ui/index.tsx
@@ -14,12 +14,12 @@
import React from 'react';
import ReactDOM from 'react-dom/client';
-import './index.css';
import {routes} from './route';
import reportWebVitals from './report_web_vitals';
import AppConfig from './client/initialize';
import { ReportingClientImpl } from './client/reporting/client_impl';
import {createBrowserRouter, RouterProvider} from 'react-router-dom';
+import './index.css';
import 'bootstrap/dist/css/bootstrap.min.css';
const configProps = {
diff --git a/experimental/reporting-ui/src/main/react/reporting-ui/public/asset/font/BUILD.bazel b/experimental/reporting-ui/src/main/react/reporting-ui/public/asset/font/BUILD.bazel
index 29e42e22783..39cf9145210 100644
--- a/experimental/reporting-ui/src/main/react/reporting-ui/public/asset/font/BUILD.bazel
+++ b/experimental/reporting-ui/src/main/react/reporting-ui/public/asset/font/BUILD.bazel
@@ -10,7 +10,7 @@ js_library(
name = "font",
srcs = glob(
include = [
- "open-san-light.ttf",
+ "open-sans-light.ttf",
],
),
)
diff --git a/experimental/reporting-ui/src/main/react/reporting-ui/public/index.html b/experimental/reporting-ui/src/main/react/reporting-ui/public/index.html
index a2db49b35b1..e6508600b46 100644
--- a/experimental/reporting-ui/src/main/react/reporting-ui/public/index.html
+++ b/experimental/reporting-ui/src/main/react/reporting-ui/public/index.html
@@ -15,6 +15,7 @@
+
diff --git a/experimental/reporting-ui/src/main/react/reporting-ui/util/BUILD.bazel b/experimental/reporting-ui/src/main/react/reporting-ui/util/BUILD.bazel
new file mode 100644
index 00000000000..7120cf169e9
--- /dev/null
+++ b/experimental/reporting-ui/src/main/react/reporting-ui/util/BUILD.bazel
@@ -0,0 +1,14 @@
+load("@aspect_rules_js//js:defs.bzl", "js_library")
+
+package(
+ default_visibility = [
+ "//experimental/reporting-ui/src/main/react/reporting-ui:__subpackages__",
+ ],
+)
+
+js_library(
+ name = "formatting",
+ srcs = [
+ "formatting.ts",
+ ],
+)
diff --git a/experimental/reporting-ui/src/main/react/reporting-ui/util/formatting.ts b/experimental/reporting-ui/src/main/react/reporting-ui/util/formatting.ts
new file mode 100644
index 00000000000..805d68d895f
--- /dev/null
+++ b/experimental/reporting-ui/src/main/react/reporting-ui/util/formatting.ts
@@ -0,0 +1,44 @@
+// Copyright 2023 The Cross-Media Measurement Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// In powers of 10
+const MAGNITUDES = Object.freeze({
+ 3: 'K',
+ 6: 'M',
+ 9: 'B',
+ 12: 'T',
+});
+
+export const formatNumberWithMagnitude = (
+ num: number,
+ decimals: number,
+ trailingZeros: boolean = false,
+) => {
+ let power = 0;
+ let newNumber = num;
+ while (newNumber >= 1000) {
+ newNumber = newNumber / 1000;
+ power += 3;
+ }
+
+ if (power === 0) {
+ return num.toString();
+ } else {
+ const value = (newNumber.toFixed(decimals));
+
+ return trailingZeros ?
+ value.toString() + MAGNITUDES[power]
+ : value.toString().replace(/\.0+$/, '') + MAGNITUDES[power]
+ }
+}
diff --git a/experimental/reporting-ui/src/main/react/reporting-ui/view/report/BUILD.bazel b/experimental/reporting-ui/src/main/react/reporting-ui/view/report/BUILD.bazel
index 1952ca5fb9b..25d5a691413 100644
--- a/experimental/reporting-ui/src/main/react/reporting-ui/view/report/BUILD.bazel
+++ b/experimental/reporting-ui/src/main/react/reporting-ui/view/report/BUILD.bazel
@@ -12,6 +12,7 @@ js_library(
"report_view.tsx",
],
deps = [
+ "//experimental/reporting-ui/src/main/react/reporting-ui/view/report/component:terminal_report",
"//experimental/reporting-ui/src/main/react/reporting-ui/view_model/report",
],
)
diff --git a/experimental/reporting-ui/src/main/react/reporting-ui/view/report/component/BUILD.bazel b/experimental/reporting-ui/src/main/react/reporting-ui/view/report/component/BUILD.bazel
new file mode 100644
index 00000000000..93650fd66d9
--- /dev/null
+++ b/experimental/reporting-ui/src/main/react/reporting-ui/view/report/component/BUILD.bazel
@@ -0,0 +1,28 @@
+load("@aspect_rules_js//js:defs.bzl", "js_library")
+
+package(
+ default_visibility = [
+ "//experimental/reporting-ui/src/main/react/reporting-ui/view/report:__subpackages__",
+ ],
+)
+
+js_library(
+ name = "terminal_report",
+ srcs = [
+ "header.css",
+ "header.tsx",
+ "overview.css",
+ "overview.tsx",
+ "overview_card.tsx",
+ "publisher_cell.tsx",
+ "summary_table.css",
+ "summary_table.tsx",
+ "summary_table_row.tsx",
+ "terminal_report.tsx",
+ ],
+ deps = [
+ "//experimental/reporting-ui/src/main/react/reporting-ui/component/card_wrapper",
+ "//experimental/reporting-ui/src/main/react/reporting-ui/public/asset/icon",
+ "//experimental/reporting-ui/src/main/react/reporting-ui/util:formatting",
+ ],
+)
diff --git a/experimental/reporting-ui/src/main/react/reporting-ui/view/report/component/header.css b/experimental/reporting-ui/src/main/react/reporting-ui/view/report/component/header.css
new file mode 100644
index 00000000000..3b533ff77a8
--- /dev/null
+++ b/experimental/reporting-ui/src/main/react/reporting-ui/view/report/component/header.css
@@ -0,0 +1,30 @@
+ /* Copyright 2023 The Cross-Media Measurement Authors
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License. */
+
+#header-title {
+ color: #000000;
+ font-family: open-sans-light;
+ font-size: 22px;
+ font-style: normal;
+ font-weight: 400;
+ line-height: 28px;
+}
+
+#get-report-header-menu {
+ margin: 0px 8px 0px 32px;
+}
+
+#header-collapse > svg {
+ margin-right: 8px;
+}
diff --git a/experimental/reporting-ui/src/main/react/reporting-ui/view/report/component/header.tsx b/experimental/reporting-ui/src/main/react/reporting-ui/view/report/component/header.tsx
new file mode 100644
index 00000000000..9cc8d8a5037
--- /dev/null
+++ b/experimental/reporting-ui/src/main/react/reporting-ui/view/report/component/header.tsx
@@ -0,0 +1,48 @@
+// Copyright 2023 The Cross-Media Measurement Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import React from 'react';
+import Navbar from 'react-bootstrap/Navbar';
+import {
+ AddIcon,
+ DownloadIcon,
+ FilterIcon,
+ MenuIcon,
+ TrailingIcon,
+} from '../../../public/asset/icon';
+import './header.css';
+
+type HeaderProps = {
+ reportName: string;
+};
+
+export function Header({reportName}: HeaderProps) {
+ return (
+
+
+
+ );
+}
diff --git a/experimental/reporting-ui/src/main/react/reporting-ui/view/report/component/overview.css b/experimental/reporting-ui/src/main/react/reporting-ui/view/report/component/overview.css
new file mode 100644
index 00000000000..66235a01d94
--- /dev/null
+++ b/experimental/reporting-ui/src/main/react/reporting-ui/view/report/component/overview.css
@@ -0,0 +1,40 @@
+ /* Copyright 2023 The Cross-Media Measurement Authors
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License. */
+
+#report-overview {
+ margin: 32px 16px 0px 16px;
+
+ .col {
+ margin: 0px 16px 0px 16px;
+ padding: 0px;
+ }
+}
+
+#report-overview .card-title {
+ color: #1F1F1F;
+ font-family: open-sans-light;
+ font-size: 16px;
+ font-style: normal;
+ font-weight: 500;
+ line-height: 24px;
+}
+
+#report-overview .card-text {
+ color: #1F1F1F;
+ font-family: open-sans-light;
+ font-size: 45px;
+ font-style: normal;
+ font-weight: 400;
+ line-height: 52px;
+}
diff --git a/experimental/reporting-ui/src/main/react/reporting-ui/view/report/component/overview.tsx b/experimental/reporting-ui/src/main/react/reporting-ui/view/report/component/overview.tsx
new file mode 100644
index 00000000000..6b69931c911
--- /dev/null
+++ b/experimental/reporting-ui/src/main/react/reporting-ui/view/report/component/overview.tsx
@@ -0,0 +1,43 @@
+// Copyright 2023 The Cross-Media Measurement Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import React from 'react';
+import Row from 'react-bootstrap/Row';
+import Col from 'react-bootstrap/Col';
+import './overview.css';
+import { ReportOverviewCard } from './overview_card';
+import { Overview } from '../../../model/reporting';
+
+type ReportTotalsProps = {
+ reportOverview: Overview;
+};
+
+export function ReportOverviewStats({reportOverview}: ReportTotalsProps) {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/experimental/reporting-ui/src/main/react/reporting-ui/view/report/component/overview_card.tsx b/experimental/reporting-ui/src/main/react/reporting-ui/view/report/component/overview_card.tsx
new file mode 100644
index 00000000000..94049d82191
--- /dev/null
+++ b/experimental/reporting-ui/src/main/react/reporting-ui/view/report/component/overview_card.tsx
@@ -0,0 +1,29 @@
+// Copyright 2023 The Cross-Media Measurement Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import React from 'react';
+import { CardWrapper as Card } from '../../../component/card_wrapper/card_wrapper';
+import { formatNumberWithMagnitude } from '../../../util/formatting';
+
+export type ReportOverviewProps = {
+ id: string,
+ title: string,
+ value: number,
+}
+
+export function ReportOverviewCard({id, title, value}: ReportOverviewProps) {
+ return (
+
+ )
+}
diff --git a/experimental/reporting-ui/src/main/react/reporting-ui/view/report/component/publisher_cell.tsx b/experimental/reporting-ui/src/main/react/reporting-ui/view/report/component/publisher_cell.tsx
new file mode 100644
index 00000000000..665ee4a5642
--- /dev/null
+++ b/experimental/reporting-ui/src/main/react/reporting-ui/view/report/component/publisher_cell.tsx
@@ -0,0 +1,34 @@
+// Copyright 2023 The Cross-Media Measurement Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import React from 'react';
+import Stack from 'react-bootstrap/Stack';
+import { SquareIcon } from '../../../public/asset/icon';
+
+type ReportSummaryProps = {
+ publisherName: string,
+ publisherColor: string,
+};
+
+export function PublisherCell({
+ publisherName,
+ publisherColor,
+}: ReportSummaryProps) {
+ return (
+
+
+ {publisherName}
+
+ )
+}
diff --git a/experimental/reporting-ui/src/main/react/reporting-ui/view/report/component/summary_table.css b/experimental/reporting-ui/src/main/react/reporting-ui/view/report/component/summary_table.css
new file mode 100644
index 00000000000..86d7a096e67
--- /dev/null
+++ b/experimental/reporting-ui/src/main/react/reporting-ui/view/report/component/summary_table.css
@@ -0,0 +1,70 @@
+ /* Copyright 2023 The Cross-Media Measurement Authors
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License. */
+
+.SummaryCard {
+ overflow: hidden;
+ border-radius: 12px;
+ margin: 32px 32px 0px 32px;
+ box-shadow: 0px 2px 6px 2px rgba(0, 0, 0, 0.15), 0px 1px 2px 0px rgba(0, 0, 0, 0.30);
+
+ > .card-body {
+ padding: 0px;
+ }
+}
+
+.SummaryCard table {
+ margin: 0!important;
+}
+
+.SummaryCard table thead td {
+ color: #000000;
+ font-family: open-sans-light;
+ font-size: 12px;
+ font-style: normal;
+ font-weight: 600;
+ line-height: 16px;
+ letter-spacing: 0.1px;
+ padding: 16px;
+}
+
+.SummaryCard table tbody td {
+ color: #000000;
+ font-family: open-sans-light;
+ font-size: 12px;
+ font-style: normal;
+ font-weight: 400;
+ line-height: 16px;
+ letter-spacing: 0.1px;
+ padding: 16px;
+}
+
+.SummaryCard table thead > tr > th:first-child {
+ padding-left: 32px;
+}
+
+.SummaryCard table thead > tr > th:last-child {
+ padding-right: 32px;
+}
+
+.SummaryCard table tbody > tr > td:first-child {
+ padding-left: 32px;
+}
+
+.SummaryCard table tbody > tr > td:last-child {
+ padding-right: 32px;
+}
+
+.SummaryCard table tbody > tr:last-child > td {
+ border-bottom: 0;
+}
diff --git a/experimental/reporting-ui/src/main/react/reporting-ui/view/report/component/summary_table.tsx b/experimental/reporting-ui/src/main/react/reporting-ui/view/report/component/summary_table.tsx
new file mode 100644
index 00000000000..d6de308b216
--- /dev/null
+++ b/experimental/reporting-ui/src/main/react/reporting-ui/view/report/component/summary_table.tsx
@@ -0,0 +1,58 @@
+// Copyright 2023 The Cross-Media Measurement Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import React from 'react';
+import Table from 'react-bootstrap/Table';
+import Card from 'react-bootstrap/Card';
+import {SummaryPublisherData} from '../../../model/reporting';
+import { SummaryTableRow } from './summary_table_row';
+import './summary_table.css';
+
+type PublisherConfig = {[id: string]: string};
+
+type SummaryTableProps = {
+ reportSummaries: SummaryPublisherData[];
+ publisherColors: PublisherConfig;
+};
+
+export function SummaryTable({
+ reportSummaries,
+ publisherColors,
+}: SummaryTableProps) {
+ const summaries = reportSummaries.map((pubData: SummaryPublisherData) => {
+ return(
+
+ )
+ });
+
+ return (
+
+
+
+
+
+ Publisher |
+ Impressions |
+ Reach |
+ On target reach |
+ Unique reach |
+ Average frequency |
+
+
+ {summaries}
+
+
+
+ );
+}
diff --git a/experimental/reporting-ui/src/main/react/reporting-ui/view/report/component/summary_table_row.tsx b/experimental/reporting-ui/src/main/react/reporting-ui/view/report/component/summary_table_row.tsx
new file mode 100644
index 00000000000..db2025ef3b2
--- /dev/null
+++ b/experimental/reporting-ui/src/main/react/reporting-ui/view/report/component/summary_table_row.tsx
@@ -0,0 +1,44 @@
+// Copyright 2023 The Cross-Media Measurement Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import React from 'react';
+import { SummaryPublisherData } from '../../../model/reporting';
+import { PublisherCell } from './publisher_cell';
+import { formatNumberWithMagnitude } from '../../../util/formatting';
+
+type ReportSummaryProps = {
+ pubData: SummaryPublisherData,
+ color: string,
+};
+
+export function SummaryTableRow({
+ pubData,
+ color,
+}: ReportSummaryProps) {
+ return (
+
+
+
+ |
+ {formatNumberWithMagnitude(pubData.impressions, 1)} |
+ {formatNumberWithMagnitude(pubData.reach, 1)} |
+ {formatNumberWithMagnitude(pubData.onTargetReach, 1)} |
+ {formatNumberWithMagnitude(pubData.uniqueReach, 1)} |
+ {formatNumberWithMagnitude(pubData.averageFrequency, 1)} |
+
+ )
+}
diff --git a/experimental/reporting-ui/src/main/react/reporting-ui/view/report/component/terminal_report.tsx b/experimental/reporting-ui/src/main/react/reporting-ui/view/report/component/terminal_report.tsx
new file mode 100644
index 00000000000..6335e677c06
--- /dev/null
+++ b/experimental/reporting-ui/src/main/react/reporting-ui/view/report/component/terminal_report.tsx
@@ -0,0 +1,48 @@
+// Copyright 2023 The Cross-Media Measurement Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import React from 'react';
+import { Header } from './header';
+import { ReportOverviewStats } from './overview';
+import { SummaryTable } from './summary_table';
+import { Overview, SummaryPublisherData } from '../../../model/reporting';
+
+const COLORS = Object.freeze([
+ '#FFA300',
+ '#EA5F94',
+ '#9D02D7',
+ '#5E5E5E',
+]);
+
+type TerminalReportProps = {
+ name: string;
+ overview: Overview,
+ summaries: SummaryPublisherData[],
+}
+
+export const TerminalReport = ({name, overview, summaries}: TerminalReportProps) => {
+ // Assign a color to each publisher
+ const pubIds = summaries.map(x => x.id);
+ const pubColors = {};
+ pubIds.forEach((pub_id, index) => pubColors[pub_id] = COLORS[index]);
+
+ return (
+
+
+
+
+ {/* TODO: Add the charts */}
+
+ )
+};
diff --git a/experimental/reporting-ui/src/main/react/reporting-ui/view/report/report_view.tsx b/experimental/reporting-ui/src/main/react/reporting-ui/view/report/report_view.tsx
index 60ade29c826..8582b35795e 100644
--- a/experimental/reporting-ui/src/main/react/reporting-ui/view/report/report_view.tsx
+++ b/experimental/reporting-ui/src/main/react/reporting-ui/view/report/report_view.tsx
@@ -18,6 +18,7 @@ import { ReportViewModel } from '../../view_model/report/report_view_model';
import { Loader } from '../../component/loader/loader';
import { Error } from '../../component/error/error';
import { TERMINAL_STATES } from '../../model/reporting';
+import { TerminalReport } from './component/terminal_report';
export const ReportView = () => {
const { errors, report, load, loading } = ReportViewModel();
@@ -40,7 +41,7 @@ export const ReportView = () => {
}
if (TERMINAL_STATES.includes(report.status)) {
- return {report.name}
+ return
}
return(
diff --git a/experimental/reporting-ui/src/main/react/reporting-ui/view_model/report/report_view_model.ts b/experimental/reporting-ui/src/main/react/reporting-ui/view_model/report/report_view_model.ts
index 4a2c8be6b93..ca89c4f88b1 100644
--- a/experimental/reporting-ui/src/main/react/reporting-ui/view_model/report/report_view_model.ts
+++ b/experimental/reporting-ui/src/main/react/reporting-ui/view_model/report/report_view_model.ts
@@ -13,13 +13,15 @@
// limitations under the License.
import {useState} from 'react';
-import { Report, ReportState } from '../../model/reporting';
+import { Overview, Report, ReportState, SummaryPublisherData } from '../../model/reporting';
import { ReportRepository } from '../../model/report/report_repository';
type UiReport = {
id: string,
name: string,
status: ReportState,
+ overview: Overview,
+ summary: SummaryPublisherData[],
}
const handleUiReport = (report: Report|undefined) => {
@@ -31,6 +33,8 @@ const handleUiReport = (report: Report|undefined) => {
id: report.id,
name: report.name,
status: report.status,
+ overview: report.overview,
+ summary: report.summary,
};
};