kpfadnis commited on
Commit
599f646
·
1 Parent(s): 8777b6a

chore: Initial commit.

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .dockerignore +9 -0
  2. .eslintrc.json +6 -0
  3. .gitignore +23 -0
  4. .prettierignore +9 -0
  5. .prettierrc +5 -0
  6. CHANGELOG.md +28 -0
  7. Dockerfile +71 -0
  8. README.md +36 -1
  9. VERSION +1 -0
  10. data/clapNQ.json +0 -0
  11. next-env.d.ts +5 -0
  12. next.config.js +83 -0
  13. package.json +60 -0
  14. public/app.LICENSE.txt +17 -0
  15. public/favicon.ico +0 -0
  16. public/robot.txt +2 -0
  17. scripts/license.js +53 -0
  18. src/app/cookbooks/page.tsx +23 -0
  19. src/app/documentation/page.tsx +23 -0
  20. src/app/examples/[example_id]/layout.tsx +27 -0
  21. src/app/examples/[example_id]/loading.tsx +23 -0
  22. src/app/examples/[example_id]/page.tsx +33 -0
  23. src/app/examples/page.tsx +30 -0
  24. src/app/global.scss +44 -0
  25. src/app/layout.tsx +49 -0
  26. src/app/loading.tsx +21 -0
  27. src/app/page.tsx +77 -0
  28. src/app/visualize/layout.tsx +27 -0
  29. src/app/visualize/loading.tsx +23 -0
  30. src/app/visualize/page.tsx +23 -0
  31. src/components/comments/AddCommentModal.module.scss +44 -0
  32. src/components/comments/AddCommentModal.tsx +128 -0
  33. src/components/comments/CommentViewer.module.scss +92 -0
  34. src/components/comments/CommentsViewer.tsx +145 -0
  35. src/components/disabled/DisabledTab.module.scss +43 -0
  36. src/components/disabled/DisabledTab.tsx +39 -0
  37. src/components/example-tile/ExampleTile.module.scss +116 -0
  38. src/components/example-tile/ExampleTile.tsx +201 -0
  39. src/components/example-tile/SkeletonExampleTile.tsx +126 -0
  40. src/components/filters/Filters.module.scss +72 -0
  41. src/components/filters/Filters.tsx +137 -0
  42. src/components/filters/SkeletonFilters.tsx +71 -0
  43. src/components/header/Header.jsx +114 -0
  44. src/components/header/Header.module.scss +34 -0
  45. src/components/notification/Notification.module.scss +24 -0
  46. src/components/notification/Notification.tsx +91 -0
  47. src/components/selectors/AggregatorSelector.tsx +80 -0
  48. src/components/selectors/MetricSelector.tsx +135 -0
  49. src/components/selectors/ModelSelector.tsx +75 -0
  50. src/components/task-tile/SkeletonTaskTile.tsx +124 -0
.dockerignore ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ # Deployment
2
+ yaml
3
+
4
+ # Development
5
+ .prettierignore
6
+ .prettierrc
7
+
8
+ # Documentation
9
+ README.md
.eslintrc.json ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ {
2
+ "extends": ["next/core-web-vitals", "prettier"],
3
+ "rules": {
4
+ "react/no-unescaped-entities": "off"
5
+ }
6
+ }
.gitignore ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # MacOS
2
+ .DS_Store
3
+
4
+ # Visual Studio code
5
+ .vscode
6
+
7
+ # IDE
8
+ .idea/
9
+
10
+ # NPM
11
+ node_modules
12
+
13
+ # NPM lock files
14
+ package-lock.json
15
+
16
+ # Next files
17
+ .next
18
+
19
+ # Husky files
20
+ .husky
21
+
22
+ # Dist files
23
+ dist
.prettierignore ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ node_modules/
2
+ .vscode/
3
+ .next/
4
+ .yarn/
5
+ public/
6
+ yarn.lock
7
+ package-lock.json
8
+ .pnp.*
9
+ *.md
.prettierrc ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ {
2
+ "arrowParens": "always",
3
+ "singleQuote": true,
4
+ "trailingComma": "all"
5
+ }
CHANGELOG.md ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Change Log
2
+
3
+ ## v1.0 (2024-04-26)
4
+
5
+
6
+ ### 🚀 Release Highlight
7
+
8
+ - InspectorRAGet has gone open source! https://github.com/IBM/InspectorRAGet
9
+
10
+ ### 💅 Features
11
+
12
+
13
+ - Functionality - Supported Evaluations: InspectorRAGet supports any human and automatic evaluations in a unified interface, from numerical metrics such as F1 and Rouge-L, to LLM-as-a-judge metrics such as faithfulness or answer relevance, to any human evaluation metrics, whether numerical or categorical.
14
+ - Integration - Experiment Runner: Python notebook demonstrating how to run experiments using Hugging Face assets (datasets, models, and metric evaluators) and output the results in the JSON format expected by InspectorRAGet
15
+ - Functionality - Input Validator: Validate input file on load and return informative error messages if any data is missing or incorrectly formatted
16
+ - Views - Data Characteristics: New view! Displays several informative visualizations of the input data
17
+ - Views - Predictions: New view! Sortable list of the input text and all corresponding model responses, filterable on all available data enrichments
18
+ - Views - Performance Overview: Aggregate values show mean, std and agreement levels, for all human and automatic metrics
19
+ - Functionality - Aggregate: Aggregator function can be specified for each metric independently
20
+ - Views - Model Behavior: Filter evaluations on any available enrichments and analyze per-metric performance across all models; display a sortable and filtered table of all tasks, with access to ever tasks Detail view
21
+ - Views - Task Detail: Examine all detailed task information including the context(s), input text, all model outputs, and all evaluation metric values
22
+ - Functionality - Sympathetic Highlighting: In the Task Detail view, click to highlight the common text between the response and the context(s)
23
+ - Functionality - Annotate: In the Task Detail view, flag a task instance, or add comments to individual components, which will persist for the rest of the session
24
+ - Functionality - Copy to Clipboard: In the Task Detail view, instantly copy all individual task detail information in text, JSON or LaTeX format
25
+ - Views - Model Comparator: Calculate statistical similarity between the distributions of two models on a given metric; display a table of all tasks with different model aggregate scores, with access to every task's Detail view
26
+ - Views - Metric Behavior: Show correlations of any selected metrics, optionally for a subset of all models, to provide insights on metric definitions and relationships
27
+ - Functionality - Export: Export the evaluation file, including all new annotations of comments and flag, to save your enriched file for future analysis
28
+ - Functionality - Dark Mode: Switch the entire UI to dark mode!
Dockerfile ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM --platform=linux/amd64 node:20-alpine AS base
2
+
3
+ # ----------------------------------------------------------
4
+ # DEPENDENCY MANAGEMENT
5
+ # ----------------------------------------------------------
6
+ # Install dependencies only when needed
7
+ FROM base AS deps
8
+ # Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
9
+ RUN apk add --no-cache libc6-compat
10
+ WORKDIR /app
11
+
12
+ # Install dependencies based on the preferred package manager
13
+ COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./
14
+ RUN \
15
+ if [ -f yarn.lock ]; then yarn --frozen-lockfile; \
16
+ elif [ -f package-lock.json ]; then npm ci --legacy-peer-deps; \
17
+ elif [ -f pnpm-lock.yaml ]; then yarn global add pnpm && pnpm i --frozen-lockfile; \
18
+ else echo "Lockfile not found." && exit 1; \
19
+ fi
20
+
21
+ # ----------------------------------------------------------
22
+ # BUILD
23
+ # ----------------------------------------------------------
24
+ # Rebuild the source code only when needed
25
+ FROM base AS builder
26
+ WORKDIR /app
27
+ COPY --from=deps /app/node_modules ./node_modules
28
+ COPY . .
29
+
30
+ # Next.js collects completely anonymous telemetry data about general usage.
31
+ # Learn more here: https://nextjs.org/telemetry
32
+ # Uncomment the following line in case you want to disable telemetry during the build.
33
+ ENV NEXT_TELEMETRY_DISABLED 1
34
+
35
+ RUN yarn build
36
+
37
+ # ----------------------------------------------------------
38
+ # PRODUCTION
39
+ # ----------------------------------------------------------
40
+ # Production image, copy all the files and run next
41
+ FROM base AS runner
42
+
43
+ # Set up environment
44
+ ENV PORT 3000
45
+ ENV NODE_ENV production
46
+
47
+ # Users configuration
48
+ RUN addgroup --system --gid 1001 nodejs
49
+ RUN adduser --system --uid 1001 nextjs
50
+
51
+ # Disable telemetry during runtime.
52
+ ENV NEXT_TELEMETRY_DISABLED 1
53
+
54
+ # Configure application directory
55
+ WORKDIR /app
56
+ COPY --from=builder /app/public ./public
57
+
58
+ # Automatically leverage output traces to reduce image size
59
+ # https://nextjs.org/docs/advanced-features/output-file-tracing
60
+ COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
61
+ COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
62
+
63
+ # Adjust permissions for next cache
64
+ RUN mkdir -p /app/.next/cache/fetch-cache && chmod -R 755 /app/.next/cache/fetch-cache
65
+
66
+ # Switch user
67
+ USER nextjs
68
+
69
+ # Runtime
70
+ EXPOSE ${PORT}
71
+ CMD ["node", "server.js"]
README.md CHANGED
@@ -1,2 +1,37 @@
1
  # InspectorRAGet
2
- The repository contains generative AI analytics platform application code.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  # InspectorRAGet
2
+
3
+ InspectorRAGet, an introspection platform for RAG evaluation. InspectorRAGet allows the user to analyze aggregate and instance-level performance of RAG systems, using both human and algorithmic metrics as well as annotator quality.
4
+
5
+ ## 🎥 Demo
6
+ [![InspectorRAGet on the case!](https://img.youtube.com/vi/MJhe8QIXcEc/0.jpg)](https://www.youtube.com/watch?v=MJhe8QIXcEc)
7
+
8
+ InspectorRAGet is a a [React](https://react.dev/) web application built with [NextJS 14](https://nextjs.org/) framework. We extensively use the [Carbon Design System](https://carbondesignsystem.com/), an open-source design system with a wide range of assets including react and web components, styling guidelines,
9
+ custom icons, and others
10
+
11
+ ## 🏗️ Build & Deploy
12
+ ### Installation
13
+ We use yarn as a default package manager.
14
+
15
+ ```shell
16
+ yarn install
17
+ ```
18
+ ⚠️ node version must be `20.12.0` or higher.
19
+
20
+ ### Development server
21
+ To start InspectorRAGet in development mode, please run the following command.
22
+
23
+ ```shell
24
+ yarn dev
25
+ ```
26
+
27
+ ### Build
28
+ To build a static production bundle, please run the following command.
29
+ ```shell
30
+ yarn dev
31
+ ```
32
+
33
+ ### Production server
34
+ To start InspectorRAGet in production mode, please run the following command.
35
+ ```shell
36
+ yarn start
37
+ ```
VERSION ADDED
@@ -0,0 +1 @@
 
 
1
+ 0.0.1-alpha
data/clapNQ.json ADDED
The diff for this file is too large to render. See raw diff
 
next-env.d.ts ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ /// <reference types="next" />
2
+ /// <reference types="next/image-types/global" />
3
+
4
+ // NOTE: This file should not be edited
5
+ // see https://nextjs.org/docs/basic-features/typescript for more information.
next.config.js ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ *
3
+ * Copyright 2023-2024 InspectorRAGet Team
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ *
17
+ **/
18
+
19
+ const path = require('path');
20
+
21
+ const cspMap = {
22
+ 'base-uri': ["'none'"],
23
+ 'font-src': ["'self'", 'data:', "'unsafe-inline'"],
24
+ 'form-action': ["'self'"],
25
+ 'frame-ancestors': ["'none'"],
26
+ 'frame-src': ["'self'"],
27
+ 'img-src': ["'self'", 'data:', 'blob:', 'www.ibm.com/'],
28
+ 'media-src': ["'self'", 'blob:', 'www.ibm.com/'],
29
+ 'object-src': ["'none'"],
30
+ 'style-src': ["'self'", "'unsafe-inline'", 'www.ibm.com/common/'],
31
+ };
32
+
33
+ const getCSPString = (cspMap) =>
34
+ Object.entries(cspMap)
35
+ .map(([key, values]) => `${key} ${values.join(' ')}`)
36
+ .join('; ');
37
+
38
+ const headers = [
39
+ {
40
+ key: 'Content-Security-Policy',
41
+ value: getCSPString(cspMap),
42
+ },
43
+ {
44
+ key: 'X-Content-Type-Options',
45
+ value: 'nosniff',
46
+ },
47
+ {
48
+ key: 'X-XSS-Protection',
49
+ value: '1',
50
+ },
51
+ {
52
+ key: 'Strict-Transport-Security',
53
+ value: 'max-age=63072000; includeSubDomains; preload',
54
+ },
55
+ {
56
+ key: 'X-Frame-Options',
57
+ value: 'DENY',
58
+ },
59
+ {
60
+ key: 'Referrer-Policy',
61
+ value: 'strict-origin-when-cross-origin',
62
+ },
63
+ ];
64
+
65
+ const nextConfig = {
66
+ reactStrictMode: true,
67
+ swcMinify: true,
68
+
69
+ output: 'standalone',
70
+ sassOptions: {
71
+ includePaths: [path.join(__dirname, 'styles')],
72
+ },
73
+
74
+ async headers() {
75
+ return [
76
+ // Default headers for all pages.
77
+ { source: '/', headers },
78
+ { source: '/:path*', headers },
79
+ ];
80
+ },
81
+ };
82
+
83
+ module.exports = nextConfig;
package.json ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "InspectorRAGet",
3
+ "version": "1.0.0-beta",
4
+ "private": true,
5
+ "description": "An Introspection Platform for RAG Evaluation",
6
+ "author": "[email protected]",
7
+ "license": "ISC",
8
+ "scripts": {
9
+ "postinstall": "husky install",
10
+ "dev": "next dev",
11
+ "build": "next build && node ./scripts/license",
12
+ "start": "next start",
13
+ "lint": "next lint && stylelint \"**/*.{css,scss}\"",
14
+ "format": "prettier --write ."
15
+ },
16
+ "husky": {
17
+ "hooks": {
18
+ "pre-commit": "yarn build"
19
+ }
20
+ },
21
+ "devDependencies": {
22
+ "@next/eslint-plugin-next": "^13.4.2",
23
+ "@types/node": "18.16.3",
24
+ "cross-env": "^7.0.3",
25
+ "eslint": "^8.23.0",
26
+ "eslint-config-next": "^13.1.6",
27
+ "eslint-config-prettier": "^8.8.0",
28
+ "husky": "^8.0.3",
29
+ "prepend-file": "^2.0.1",
30
+ "prettier": "^3.0.3",
31
+ "sass": "^1.54.3",
32
+ "typescript": "^5.0.4",
33
+ "stylelint": "16.2.1",
34
+ "stylelint-config-standard-scss": "13.0.0"
35
+ },
36
+ "dependencies": {
37
+ "@carbon/colors": "^11.4.0",
38
+ "@carbon/themes": "^11.8.0",
39
+ "@carbon/icons-react": "^11.34.1",
40
+ "@carbon/pictograms-react": "^11.49.0",
41
+ "@carbon/charts": "^1.7.4",
42
+ "@carbon/charts-react": "^1.7.4",
43
+ "@carbon/react": "^1.17.0",
44
+ "d3": "^7.8.4",
45
+ "date-fns": "^2.30.0",
46
+ "dompurify": "3.0.8",
47
+ "html-react-parser": "^5.1.1",
48
+ "lodash": "^4.17.4",
49
+ "next": "^14.1.1",
50
+ "prop-types": "^15.7.2",
51
+ "react": "^18.2.0",
52
+ "react-dom": "^18.2.0",
53
+ "react-intl": "^6.1.0",
54
+ "react-markdown": "^8.0.7",
55
+ "rehype-raw": "^7.0.0",
56
+ "remark-gfm": "^3.0.1",
57
+ "statistics.js": "^1.0.0",
58
+ "uuid": "^9.0.1"
59
+ }
60
+ }
public/app.LICENSE.txt ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+ *
3
+ * Copyright 2023-2024 InspectorRAGet Team
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ *
17
+ **/
public/favicon.ico ADDED
public/robot.txt ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ User-agent: *
2
+ Disallow: /
scripts/license.js ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ *
3
+ * Copyright 2023-2024 InspectorRAGet Team
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ *
17
+ **/
18
+
19
+ const fs = require('fs');
20
+ const path = require('path');
21
+ const prependFile = require('prepend-file');
22
+
23
+ const license = `/*! For license information please see app.LICENSE.txt */
24
+ `;
25
+
26
+ const chunksPath = path.join(__dirname, '../.next/static/chunks/');
27
+ const cssPath = path.join(__dirname, '../.next/static/css');
28
+
29
+ function applyLicence(filePath) {
30
+ prependFile(filePath, license);
31
+ }
32
+
33
+ function findAllFiles(dirPath) {
34
+ const files = [];
35
+ const searchFiles = (directoryPath) =>
36
+ fs.readdirSync(directoryPath).forEach((file) => {
37
+ const filePath = path.join(directoryPath, file);
38
+ if (fs.statSync(filePath).isDirectory()) {
39
+ searchFiles(filePath);
40
+ } else {
41
+ files.push(filePath);
42
+ }
43
+ });
44
+
45
+ searchFiles(dirPath);
46
+
47
+ return files;
48
+ }
49
+
50
+ [chunksPath, cssPath].forEach((folder) => {
51
+ const files = findAllFiles(folder);
52
+ files.forEach((file) => applyLicence(file));
53
+ });
src/app/cookbooks/page.tsx ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ *
3
+ * Copyright 2023-2024 InspectorRAGet Team
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ *
17
+ **/
18
+
19
+ import CookBooksView from '@/src/views/cookbooks/CookBooks';
20
+
21
+ export default function Page() {
22
+ return <CookBooksView />;
23
+ }
src/app/documentation/page.tsx ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ *
3
+ * Copyright 2023-2024 InspectorRAGet Team
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ *
17
+ **/
18
+
19
+ import DocumentationView from '@/src/views/documentation/Documentation';
20
+
21
+ export default function Page() {
22
+ return <DocumentationView />;
23
+ }
src/app/examples/[example_id]/layout.tsx ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ *
3
+ * Copyright 2023-2024 InspectorRAGet Team
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ *
17
+ **/
18
+ import { Suspense } from 'react';
19
+ import Loading from '@/src/app/examples/[example_id]/loading';
20
+
21
+ export default function ExampleLayout({
22
+ children,
23
+ }: {
24
+ children: React.ReactNode;
25
+ }) {
26
+ return <Suspense fallback={<Loading />}>{children}</Suspense>;
27
+ }
src/app/examples/[example_id]/loading.tsx ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ *
3
+ * Copyright 2022-2023 InspectorRAGet Team
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ *
17
+ **/
18
+
19
+ import SkeletonExample from '@/src/views/example/SkeletonExample';
20
+
21
+ export default async function Loading() {
22
+ return <SkeletonExample />;
23
+ }
src/app/examples/[example_id]/page.tsx ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ *
3
+ * Copyright 2023-2024 InspectorRAGet Team
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ *
17
+ **/
18
+
19
+ import { Data } from '@/src/types';
20
+ import { load } from '@/src/dataloader';
21
+ import Example from '@/src/views/example/Example';
22
+
23
+ export default async function Page({
24
+ params,
25
+ }: {
26
+ params: { example_id: string };
27
+ }) {
28
+ const example: Data | undefined = (await load()).find(
29
+ (entry) => entry.exampleId === params.example_id,
30
+ );
31
+
32
+ return <>{example ? <Example data={example} /> : null}</>;
33
+ }
src/app/examples/page.tsx ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ *
3
+ * Copyright 2023-2024 InspectorRAGet Team
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ *
17
+ **/
18
+
19
+ /* NextJS 14 Hack to avoid fetching data during build */
20
+ export const dynamic = 'force-dynamic';
21
+
22
+ import { TileData } from '@/src/types';
23
+ import { load } from '@/src/dataloader';
24
+ import ExamplesView from '@/src/views/examples/Examples';
25
+
26
+ export default async function Page() {
27
+ const examples: TileData[] = await load();
28
+
29
+ return <ExamplesView examples={examples} />;
30
+ }
src/app/global.scss ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ *
3
+ * Copyright 2023-2024 InspectorRAGet Team
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ *
17
+ **/
18
+
19
+ @use '@carbon/react' as *;
20
+
21
+ body {
22
+ width: 100vw;
23
+ height: 100vh;
24
+ }
25
+
26
+ .root {
27
+ height: 100vh;
28
+ width: 100%;
29
+ padding-top: $spacing-09;
30
+ display: flex;
31
+ }
32
+
33
+ .copiedText {
34
+ background-color: #f1c21b;
35
+ mix-blend-mode: hard-light;
36
+ }
37
+
38
+ .highlightClickable {
39
+ cursor: pointer;
40
+ }
41
+
42
+ .cds--tabs--contained ~ .cds--tab-content {
43
+ background: var(--cds-background) !important;
44
+ }
src/app/layout.tsx ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ *
3
+ * Copyright 2023-2024 InspectorRAGet Team
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ *
17
+ **/
18
+
19
+ import { Suspense } from 'react';
20
+ import HeaderView from '@/src/components/header/Header';
21
+ import Loading from '@/src/app/loading';
22
+ import { ThemeProvider } from '@/src/theme';
23
+ import { DataStoreProvider } from '@/src/store';
24
+ import { NotificationProvider } from '@/src/components/notification/Notification';
25
+
26
+ import '@/src/app/global.scss';
27
+
28
+ export default function RootLayout({
29
+ children,
30
+ }: {
31
+ children: React.ReactNode;
32
+ }) {
33
+ return (
34
+ <html lang="en">
35
+ <body>
36
+ <ThemeProvider>
37
+ <NotificationProvider>
38
+ <DataStoreProvider>
39
+ <HeaderView />
40
+ <Suspense fallback={<Loading />}>
41
+ <main className="root">{children}</main>
42
+ </Suspense>
43
+ </DataStoreProvider>
44
+ </NotificationProvider>
45
+ </ThemeProvider>
46
+ </body>
47
+ </html>
48
+ );
49
+ }
src/app/loading.tsx ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ *
3
+ * Copyright 2023-2024 InspectorRAGet Team
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ *
17
+ **/
18
+
19
+ export default async function Loading() {
20
+ return <> </>;
21
+ }
src/app/page.tsx ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ *
3
+ * Copyright 2023-2024 InspectorRAGet Team
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ *
17
+ **/
18
+
19
+ import Home from '@/src/views/home/Home';
20
+
21
+ export default async function Page() {
22
+ return (
23
+ <Home
24
+ page={{
25
+ greeting: 'Hi,',
26
+ title: 'Welcome to InspectorRAGet',
27
+ subtitle:
28
+ 'An introspection Platform for RAG Evaluation enabling performance benchmarking, a combined aggregate and in stance level analysis, a holistic view of results via a mix of metrics, annotator qualification, and dataset characterization. Our goal is to help accelerate the transition from idea to product.',
29
+ subtitleLink: {
30
+ content: 'Learn more',
31
+ href: 'https://github.com/IBM/InspectorRAGet',
32
+ openInNewTab: true,
33
+ },
34
+ cards: [
35
+ {
36
+ title: 'Visualize',
37
+ text: 'Experience analytics capabilities.',
38
+ href: '/visualize',
39
+ actionText: 'Try it out',
40
+ tag: null,
41
+ icon: 'CHART_MULTITYPE',
42
+ openInNewTab: false,
43
+ },
44
+ {
45
+ title: 'Examples',
46
+ text: 'See how analytics platform can help you identify issues with the model faster.',
47
+ href: '/examples',
48
+ actionText: 'Explore',
49
+ tag: null,
50
+ icon: 'MICROSCOPE',
51
+ openInNewTab: false,
52
+ },
53
+ {
54
+ title: 'Data collection cookbooks',
55
+ text: 'A guide for collecting human & algorithmic evaluations.',
56
+ href: '/cookbooks',
57
+ actionText: 'Start cooking',
58
+ tag: 'coming soon',
59
+ icon: 'NOODLE_BOWL',
60
+ openInNewTab: false,
61
+ disabled: true,
62
+ },
63
+ {
64
+ title: 'Documentation',
65
+ text: 'Access developer resources',
66
+ href: '/documentation',
67
+ actionText: 'Read the docs',
68
+ tag: 'coming soon',
69
+ icon: 'BOOK',
70
+ openInNewTab: false,
71
+ disabled: true,
72
+ },
73
+ ],
74
+ }}
75
+ />
76
+ );
77
+ }
src/app/visualize/layout.tsx ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ *
3
+ * Copyright 2023-2024 InspectorRAGet Team
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ *
17
+ **/
18
+ import { Suspense } from 'react';
19
+ import Loading from '@/src/app/visualize/loading';
20
+
21
+ export default function ExperimentLayout({
22
+ children,
23
+ }: {
24
+ children: React.ReactNode;
25
+ }) {
26
+ return <Suspense fallback={<Loading />}>{children}</Suspense>;
27
+ }
src/app/visualize/loading.tsx ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ *
3
+ * Copyright 2023-2024 InspectorRAGet Team
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ *
17
+ **/
18
+
19
+ import SkeletonVisualizationView from '@/src/views/visualization/SkeletonVisualization';
20
+
21
+ export default async function Loading() {
22
+ return <SkeletonVisualizationView />;
23
+ }
src/app/visualize/page.tsx ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ *
3
+ * Copyright 2023-2024 InspectorRAGet Team
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ *
17
+ **/
18
+
19
+ import VisualizationView from '@/src/views/visualization/Visualization';
20
+
21
+ export default function Page() {
22
+ return <VisualizationView />;
23
+ }
src/components/comments/AddCommentModal.module.scss ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ *
3
+ * Copyright 2023-2024 InspectorRAGet Team
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ *
17
+ **/
18
+
19
+ @use '@carbon/react/scss/spacing' as *;
20
+
21
+ .commentProvenance {
22
+ display: flex;
23
+ flex-direction: column;
24
+ row-gap: $spacing-02;
25
+ }
26
+
27
+ .commentProvenanceTag {
28
+ max-width: 8rem;
29
+ }
30
+
31
+ .commentBox {
32
+ padding-bottom: $spacing-03;
33
+ }
34
+
35
+ .reference {
36
+ padding-bottom: $spacing-03;
37
+ }
38
+
39
+ .label {
40
+ font-size: 0.75rem;
41
+ font-weight: 400;
42
+ line-height: 1rem;
43
+ letter-spacing: 0.32px;
44
+ }
src/components/comments/AddCommentModal.tsx ADDED
@@ -0,0 +1,128 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ *
3
+ * Copyright 2023-2024 InspectorRAGet Team
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ *
17
+ **/
18
+
19
+ 'use client';
20
+
21
+ import { useState, useMemo } from 'react';
22
+ import { Modal, TextArea, TextInput, Tag } from '@carbon/react';
23
+
24
+ import { TaskCommentProvenance, Model } from '@/src/types';
25
+ import classes from './AddCommentModal.module.scss';
26
+
27
+ interface Props {
28
+ onSubmit: Function;
29
+ onClose: Function;
30
+ open: boolean;
31
+ selectedText?: string;
32
+ provenance: TaskCommentProvenance | undefined;
33
+ models: Map<string, Model> | undefined;
34
+ }
35
+
36
+ export default function AddCommentModal({
37
+ selectedText,
38
+ onSubmit,
39
+ onClose,
40
+ open = false,
41
+ provenance,
42
+ models,
43
+ }: Props) {
44
+ const [comment, setComment] = useState<string>('');
45
+ const [author, setAuthor] = useState<string>('');
46
+ const [tag, tagType] = useMemo(() => {
47
+ if (provenance) {
48
+ if (provenance.component.includes('input')) {
49
+ return ['Input', 'purple'];
50
+ } else if (provenance.component.includes('document_')) {
51
+ return ['Contexts', 'cyan'];
52
+ } else if (provenance.component.includes('::evaluation::response')) {
53
+ const modelId = provenance.component.split('::')[0];
54
+ return [`${models?.get(modelId)?.name || modelId}`, 'green'];
55
+ } else {
56
+ return ['Generic', 'gray'];
57
+ }
58
+ } else {
59
+ return ['Generic', 'gray'];
60
+ }
61
+ }, [provenance, models]);
62
+
63
+ return (
64
+ <Modal
65
+ open={open}
66
+ modalHeading="Add a comment"
67
+ modalLabel="Comments"
68
+ primaryButtonText="Add"
69
+ secondaryButtonText="Cancel"
70
+ onRequestSubmit={() => {
71
+ //Step 1: Clear comment & update default value for author
72
+ setComment('');
73
+
74
+ // Step 2: Register comment and close modal
75
+ onSubmit(comment, author);
76
+ }}
77
+ onRequestClose={() => {
78
+ //Step 1: Clear comment
79
+ setComment('');
80
+
81
+ // Step 2: Close modal
82
+ onClose();
83
+ }}
84
+ primaryButtonDisabled={comment === '' || author === ''}
85
+ >
86
+ <div className={classes.commentProvenance}>
87
+ <span className={classes.label}>Provenance</span>
88
+ <Tag className={classes.commentProvenanceTag} type={tagType}>
89
+ {tag}
90
+ </Tag>
91
+ </div>
92
+
93
+ <TextArea
94
+ className={classes.commentBox}
95
+ labelText="Comment"
96
+ rows={4}
97
+ id="comment-area"
98
+ value={comment}
99
+ invalid={comment === ''}
100
+ invalidText={'comment cannot be empty'}
101
+ onChange={(event) => {
102
+ setComment(event.target.value);
103
+ }}
104
+ />
105
+
106
+ {tag !== 'Generic' && (
107
+ <div className={classes.reference}>
108
+ <div>
109
+ <span className={'cds--label'}>Reference</span>
110
+ </div>
111
+ <p>{selectedText}</p>
112
+ </div>
113
+ )}
114
+
115
+ <TextInput
116
+ id="author-input"
117
+ type="text"
118
+ labelText="Author"
119
+ defaultValue={author}
120
+ invalid={author === ''}
121
+ invalidText={'author cannot be empty'}
122
+ onChange={(event) => {
123
+ setAuthor(event.target.value);
124
+ }}
125
+ />
126
+ </Modal>
127
+ );
128
+ }
src/components/comments/CommentViewer.module.scss ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ *
3
+ * Copyright 2023-2024 InspectorRAGet Team
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ *
17
+ **/
18
+
19
+ @use '@carbon/react/scss/spacing' as *;
20
+ @use '@carbon/colors' as *;
21
+
22
+ .viewer {
23
+ display: flex;
24
+ flex-direction: column;
25
+ row-gap: $spacing-05;
26
+ }
27
+
28
+ .comment {
29
+ display: flex;
30
+ flex-direction: column;
31
+ row-gap: $spacing-04;
32
+ border-bottom: solid 1px var(--cds-border-strong-01);
33
+ }
34
+
35
+ .commentHeader {
36
+ display: flex;
37
+ font-size: 14px;
38
+ font-weight: 300;
39
+ justify-content: space-between;
40
+ }
41
+
42
+ .commentHeaderAuthor {
43
+ display: flex;
44
+ flex-direction: column;
45
+ row-gap: $spacing-02;
46
+ align-items: center;
47
+ }
48
+
49
+ .commentHeaderProvenance {
50
+ display: flex;
51
+ flex-direction: column;
52
+ align-items: center;
53
+ }
54
+
55
+ .commentTag {
56
+ max-width: 8rem;
57
+ }
58
+
59
+ .commentHeaderTimestamp {
60
+ display: flex;
61
+ flex-direction: column;
62
+ row-gap: $spacing-02;
63
+ align-items: center;
64
+ }
65
+
66
+ .label {
67
+ font-size: 0.75rem;
68
+ font-weight: 400;
69
+ line-height: 1rem;
70
+ letter-spacing: 0.32px;
71
+ }
72
+
73
+ .commentBody {
74
+ display: flex;
75
+ flex-direction: column;
76
+ row-gap: $spacing-02;
77
+ }
78
+
79
+ .commentBodyHeader {
80
+ font-size: 14px;
81
+ font-weight: 300;
82
+ }
83
+
84
+ .commentActions {
85
+ display: flex;
86
+ justify-content: space-around;
87
+ }
88
+
89
+ .commentBtn {
90
+ display: flex;
91
+ column-gap: $spacing-03;
92
+ }
src/components/comments/CommentsViewer.tsx ADDED
@@ -0,0 +1,145 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ *
3
+ * Copyright 2023-2024 InspectorRAGet Team
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ *
17
+ **/
18
+
19
+ 'use client';
20
+
21
+ import { useState, memo, useMemo } from 'react';
22
+ import { Button, Tag } from '@carbon/react';
23
+ import { Edit, TrashCan } from '@carbon/icons-react';
24
+
25
+ import { TaskComment, Model } from '@/src/types';
26
+
27
+ import classes from './CommentViewer.module.scss';
28
+
29
+ function Comment({
30
+ id,
31
+ comment,
32
+ onEdit,
33
+ onDelete,
34
+ models,
35
+ }: {
36
+ id: string;
37
+ comment: TaskComment;
38
+ onEdit: Function;
39
+ onDelete: Function;
40
+ models: Map<string, Model> | undefined;
41
+ }) {
42
+ const [editing, setEditing] = useState<boolean>(false);
43
+ const [editedCommentText, setEditedCommentText] = useState<string>('');
44
+ const [author, setAuthor] = useState<string>('');
45
+
46
+ const [tag, tagType]: [string, string] = useMemo(() => {
47
+ if (comment.provenance) {
48
+ if (comment.provenance.component.includes('input')) {
49
+ return ['Input', 'purple'];
50
+ } else if (comment.provenance.component.includes('document_')) {
51
+ return ['Contexts', 'cyan'];
52
+ } else if (
53
+ comment.provenance.component.includes('::evaluation::response')
54
+ ) {
55
+ const modelId = comment.provenance.component.split('::')[0];
56
+ return [`${models?.get(modelId)?.name || modelId}`, 'green'];
57
+ } else {
58
+ return ['Generic', 'gray'];
59
+ }
60
+ } else {
61
+ return ['Generic', 'gray'];
62
+ }
63
+ }, [comment.provenance, models]);
64
+
65
+ return (
66
+ <div className={classes.comment}>
67
+ <div className={classes.commentHeader}>
68
+ <div className={classes.commentHeaderAuthor}>
69
+ <span className={classes.label}>Author</span>
70
+ <span>{comment.author}</span>
71
+ </div>
72
+ <div className={classes.commentHeaderProvenance}>
73
+ <span className={classes.label}>Provenance</span>
74
+ <Tag className={classes.commentTag} type={tagType}>
75
+ {tag}
76
+ </Tag>
77
+ </div>
78
+
79
+ <span className={classes.commentHeaderTimestamp}>
80
+ <span className={classes.label}>Last updated</span>
81
+ <span>{new Date(comment.updated).toLocaleDateString()}</span>
82
+ </span>
83
+ </div>
84
+
85
+ <div className={classes.commentBody}>{comment.comment}</div>
86
+ <div className={classes.commentActions}>
87
+ <Button
88
+ id={`${id}-editBtn`}
89
+ className={classes.commentBtn}
90
+ kind={'ghost'}
91
+ onClick={() => {
92
+ setEditing(true);
93
+ }}
94
+ disabled={true}
95
+ >
96
+ <span>Edit</span>
97
+ <Edit />
98
+ </Button>
99
+ <Button
100
+ id={`${id}-deleteBtn`}
101
+ className={classes.commentBtn}
102
+ kind={'ghost'}
103
+ onClick={onDelete}
104
+ disabled={true}
105
+ >
106
+ <span>Delete</span>
107
+ <TrashCan />
108
+ </Button>
109
+ </div>
110
+ </div>
111
+ );
112
+ }
113
+
114
+ interface Props {
115
+ comments: TaskComment[];
116
+ onSelect: Function;
117
+ onEdit: Function;
118
+ onDelete: Function;
119
+ models: Map<string, Model> | undefined;
120
+ }
121
+ export default memo(function ViewComments({
122
+ comments,
123
+ onSelect,
124
+ onEdit,
125
+ onDelete,
126
+ models,
127
+ }: Props) {
128
+ return (
129
+ <div className={classes.viewer}>
130
+ <h4>Comments</h4>
131
+ {comments.map((comment, commentIdx) => {
132
+ return (
133
+ <Comment
134
+ key={`comment-${commentIdx}`}
135
+ id={`comment-${commentIdx}`}
136
+ comment={comment}
137
+ onEdit={onEdit}
138
+ onDelete={onDelete}
139
+ models={models}
140
+ />
141
+ );
142
+ })}
143
+ </div>
144
+ );
145
+ });
src/components/disabled/DisabledTab.module.scss ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ *
3
+ * Copyright 2023-2024 InspectorRAGet Team
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ *
17
+ **/
18
+
19
+ @use '@carbon/react/scss/spacing' as *;
20
+ @use '@carbon/colors' as *;
21
+
22
+ .page {
23
+ display: flex;
24
+ flex-direction: column;
25
+ }
26
+
27
+ .warningContainer {
28
+ margin: $spacing-09 0;
29
+ display: flex;
30
+ column-gap: $spacing-03;
31
+ justify-content: center;
32
+ align-items: flex-end;
33
+ }
34
+
35
+ .warningContainerIcon {
36
+ color: $gray-40;
37
+ }
38
+
39
+ .warningContainerText {
40
+ font-size: 24px;
41
+ line-height: 28px;
42
+ color: $gray-40;
43
+ }
src/components/disabled/DisabledTab.tsx ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ *
3
+ * Copyright 2023-2024 InspectorRAGet Team
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ *
17
+ **/
18
+
19
+ import { WarningAlt } from '@carbon/icons-react';
20
+ import classes from './DisabledTab.module.scss';
21
+
22
+ interface Props {
23
+ message: string;
24
+ }
25
+
26
+ export default function DisabledTab({ message }: Props) {
27
+ return (
28
+ <div className={classes.page}>
29
+ <div className={classes.warningContainer}>
30
+ <WarningAlt
31
+ height={'32px'}
32
+ width={'32px'}
33
+ className={classes.warningContainerIcon}
34
+ />
35
+ <span className={classes.warningContainerText}>{message}</span>
36
+ </div>
37
+ </div>
38
+ );
39
+ }
src/components/example-tile/ExampleTile.module.scss ADDED
@@ -0,0 +1,116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ *
3
+ * Copyright 2023-2024 InspectorRAGet Team
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ *
17
+ **/
18
+
19
+ @use '@carbon/react/scss/spacing' as *;
20
+ @use '@carbon/colors' as *;
21
+
22
+ .tile {
23
+ display: flex;
24
+ flex-direction: column;
25
+ }
26
+
27
+ .skeletonTitle {
28
+ width: 50%;
29
+ }
30
+
31
+ .heading {
32
+ display: flex;
33
+ column-gap: $spacing-03;
34
+ }
35
+
36
+ .icon {
37
+ width: 16px;
38
+ height: 16px;
39
+ }
40
+
41
+ .title {
42
+ font-weight: 400;
43
+ font-size: 16px;
44
+ line-height: 20px;
45
+ }
46
+
47
+ .block {
48
+ display: flex;
49
+ margin-top: $spacing-03;
50
+ }
51
+
52
+ .divider {
53
+ border-right: 1px solid #d8d8d8;
54
+ flex: 0 0 1px;
55
+ margin: 0 1rem;
56
+ }
57
+
58
+ .information {
59
+ display: flex;
60
+ flex: 1 0 70%;
61
+ min-width: 40%;
62
+ column-gap: $spacing-12;
63
+ align-items: baseline;
64
+ }
65
+
66
+ .actions {
67
+ display: flex;
68
+ flex: 1 1 30%;
69
+ align-items: baseline;
70
+ justify-content: space-evenly;
71
+ }
72
+
73
+ .artifactEvaluations {
74
+ flex-direction: column;
75
+ }
76
+
77
+ .artifactAnnotators {
78
+ flex-direction: column;
79
+ }
80
+
81
+ .artifactMetrics {
82
+ display: flex;
83
+ flex-direction: column;
84
+ }
85
+
86
+ .artifactModels {
87
+ display: flex;
88
+ flex-direction: column;
89
+ }
90
+
91
+ .artifactDuration {
92
+ display: flex;
93
+ flex-direction: column;
94
+ }
95
+
96
+ .artifactHeader {
97
+ display: flex;
98
+ column-gap: $spacing-02;
99
+ align-items: center;
100
+ }
101
+
102
+ .artifactTitle {
103
+ font-size: 14px;
104
+ line-height: 16px;
105
+ color: var(--cds-text-helper);
106
+ }
107
+
108
+ .artifactValue {
109
+ font-size: 14px;
110
+ line-height: 16px;
111
+ margin-top: $spacing-02;
112
+ }
113
+
114
+ .listItem {
115
+ color: var(--cds-background) !important;
116
+ }
src/components/example-tile/ExampleTile.tsx ADDED
@@ -0,0 +1,201 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ *
3
+ * Copyright 2023-2024 InspectorRAGet Team
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ *
17
+ **/
18
+
19
+ 'use client';
20
+
21
+ import Link from 'next/link';
22
+ import {
23
+ ExpandableTile,
24
+ TileAboveTheFoldContent,
25
+ TileBelowTheFoldContent,
26
+ Tag,
27
+ Button,
28
+ DefinitionTooltip,
29
+ Toggletip,
30
+ ToggletipButton,
31
+ ToggletipContent,
32
+ ToggletipActions,
33
+ UnorderedList,
34
+ ListItem,
35
+ } from '@carbon/react';
36
+ import { Microscope, Download, Information } from '@carbon/icons-react';
37
+
38
+ import { TileData } from '@/src/types';
39
+ import {
40
+ MetricDefinitions,
41
+ extractMetricDisplayName,
42
+ } from '@/src/utilities/metrics';
43
+ import { calculateDuration } from '@/src/utilities/time';
44
+
45
+ import styles from './ExampleTile.module.scss';
46
+
47
+ export default function ExperimentTile({
48
+ data,
49
+ disableNavigation = false,
50
+ disableActions = false,
51
+ expanded = true,
52
+ }: {
53
+ data: TileData;
54
+ disableNavigation?: boolean;
55
+ disableActions?: boolean;
56
+ expanded?: boolean;
57
+ }) {
58
+ const [
59
+ durationInDays,
60
+ durationInHours,
61
+ durationInMinutes,
62
+ durationInSeconds,
63
+ ] = calculateDuration(data.endTimestamp, data.startTimestamp);
64
+
65
+ return (
66
+ <ExpandableTile expanded={expanded}>
67
+ <TileAboveTheFoldContent>
68
+ <div className={styles.heading}>
69
+ <Microscope className={styles.icon} />
70
+ {disableNavigation ? (
71
+ <span className={styles.title}>{data.name}</span>
72
+ ) : (
73
+ <Link href={`/examples/${data.exampleId}`}>
74
+ <span className={styles.title}>{data.name}</span>
75
+ </Link>
76
+ )}
77
+ </div>
78
+ </TileAboveTheFoldContent>
79
+ <TileBelowTheFoldContent>
80
+ <div className={styles.block}>
81
+ <div className={styles.information}>
82
+ <div className={styles.artifactEvaluations}>
83
+ <div className={styles.artifactTitle}>
84
+ <span># of tasks</span>
85
+ </div>
86
+ <div className={styles.artifactValue}>
87
+ <span>{data.numTasks}</span>
88
+ </div>
89
+ </div>
90
+ <div className={styles.artifactAnnotators}>
91
+ <div className={styles.artifactTitle}>
92
+ <span># of annotators</span>
93
+ </div>
94
+ <div className={styles.artifactValue}>
95
+ <span>{data.annotators.length}</span>
96
+ </div>
97
+ </div>
98
+ <div className={styles.artifactMetrics}>
99
+ <div className={styles.artifactHeader}>
100
+ <div className={styles.artifactTitle}>
101
+ <span>Metrics</span>
102
+ </div>
103
+ <Toggletip>
104
+ <ToggletipButton label="Additional information">
105
+ <Information />
106
+ </ToggletipButton>
107
+ <ToggletipContent>
108
+ <p>Analytics platform supports three kind of metrics</p>
109
+ <UnorderedList>
110
+ <ListItem className={styles.listItem}>
111
+ Go vs No-Go Rubric
112
+ </ListItem>
113
+ <ListItem className={styles.listItem}>
114
+ Intuitive Rubric
115
+ </ListItem>
116
+ <ListItem className={styles.listItem}>
117
+ Detailed Rubric
118
+ </ListItem>
119
+ </UnorderedList>
120
+ <ToggletipActions>
121
+ <Link target="_blank" rel="noopener noreferrer" href="">
122
+ Reference
123
+ </Link>
124
+ </ToggletipActions>
125
+ </ToggletipContent>
126
+ </Toggletip>
127
+ </div>
128
+ <div className={styles.artifactValue}>
129
+ {[...data.metrics].map((metric) => {
130
+ return (
131
+ <Tag type={'cool-gray'} key={'metric-' + metric.name}>
132
+ <DefinitionTooltip
133
+ definition={
134
+ metric.description || MetricDefinitions[metric.name]
135
+ }
136
+ align={'bottom'}
137
+ openOnHover={true}
138
+ >
139
+ {extractMetricDisplayName(metric)}
140
+ </DefinitionTooltip>
141
+ </Tag>
142
+ );
143
+ })}
144
+ </div>
145
+ </div>
146
+ <div className={styles.artifactModels}>
147
+ <div className={styles.artifactTitle}>
148
+ <span>Models</span>
149
+ </div>
150
+ <div className={styles.artifactValue}>
151
+ {[...data.models].map((model) => {
152
+ return (
153
+ <Tag type={'cool-gray'} key={'model-' + model.modelId}>
154
+ {model.name}
155
+ </Tag>
156
+ );
157
+ })}
158
+ </div>
159
+ </div>
160
+ {durationInDays ||
161
+ durationInHours ||
162
+ durationInMinutes ||
163
+ durationInSeconds ? (
164
+ <div className={styles.artifactDuration}>
165
+ <div className={styles.artifactTitle}>
166
+ <span>Duration</span>
167
+ </div>
168
+ <div className={styles.artifactValue}>
169
+ <span>
170
+ {durationInDays ? durationInDays + ' days ' : ''}
171
+ {durationInHours ? durationInHours + ' hours ' : ''}
172
+ {durationInMinutes ? durationInMinutes + ' mins ' : ''}
173
+ {durationInSeconds} sec
174
+ </span>
175
+ </div>
176
+ </div>
177
+ ) : null}
178
+ </div>
179
+ {!disableActions && (
180
+ <>
181
+ <div className={styles.divider}></div>
182
+ <div className={styles.actions}>
183
+ <Button
184
+ id="download-evaluations"
185
+ renderIcon={Download}
186
+ kind={'ghost'}
187
+ iconDescription={'Download evaluations'}
188
+ tooltipAlignment={'end'}
189
+ tooltipPosition={'bottom'}
190
+ disabled
191
+ >
192
+ Download evaluations
193
+ </Button>
194
+ </div>
195
+ </>
196
+ )}
197
+ </div>
198
+ </TileBelowTheFoldContent>
199
+ </ExpandableTile>
200
+ );
201
+ }
src/components/example-tile/SkeletonExampleTile.tsx ADDED
@@ -0,0 +1,126 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ *
3
+ * Copyright 2023-2024 InspectorRAGet Team
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ *
17
+ **/
18
+
19
+ 'use client';
20
+
21
+ import Link from 'next/link';
22
+ import { Tile, Tag, Button, SkeletonText } from '@carbon/react';
23
+ import { Microscope, Download } from '@carbon/icons-react';
24
+
25
+ import styles from './ExampleTile.module.scss';
26
+
27
+ export default function SkeletonExampleTile({
28
+ disableNavigation = false,
29
+ disableActions = false,
30
+ }: {
31
+ disableNavigation?: boolean;
32
+ disableActions?: boolean;
33
+ }) {
34
+ return (
35
+ <Tile className={styles.tile}>
36
+ <div className={styles.heading}>
37
+ <Microscope className={styles.icon} />
38
+ {disableNavigation ? (
39
+ <span className={styles.title}>
40
+ <SkeletonText />
41
+ </span>
42
+ ) : (
43
+ <Link href={`#`}>
44
+ <span className={styles.title}>
45
+ <SkeletonText />
46
+ </span>
47
+ </Link>
48
+ )}
49
+ </div>
50
+ <div className={styles.block}>
51
+ <div className={styles.information}>
52
+ <div className={styles.artifactEvaluations}>
53
+ <div className={styles.artifactTitle}>
54
+ <span># of evaluations</span>
55
+ </div>
56
+ <div className={styles.artifactValue}>
57
+ <SkeletonText />
58
+ </div>
59
+ </div>
60
+ <div className={styles.artifactAnnotators}>
61
+ <div className={styles.artifactTitle}>
62
+ <span># of annotators</span>
63
+ </div>
64
+ <div className={styles.artifactValue}>
65
+ <SkeletonText />
66
+ </div>
67
+ </div>
68
+ <div className={styles.artifactMetrics}>
69
+ <div className={styles.artifactTitle}>
70
+ <span>Metrics</span>
71
+ </div>
72
+ <div className={styles.artifactValue}>
73
+ {['Metric A', 'Metric B', 'Metric C'].map((metric) => {
74
+ return (
75
+ <Tag type="cool-gray" key={'metric-' + metric}>
76
+ {metric}
77
+ </Tag>
78
+ );
79
+ })}
80
+ </div>
81
+ </div>
82
+ <div className={styles.artifactModels}>
83
+ <div className={styles.artifactTitle}>
84
+ <span>Models</span>
85
+ </div>
86
+ <div className={styles.artifactValue}>
87
+ {['Model A', 'Model B'].map((model) => {
88
+ return (
89
+ <Tag type="cool-gray" key={'model-' + model}>
90
+ {model}
91
+ </Tag>
92
+ );
93
+ })}
94
+ </div>
95
+ </div>
96
+ <div className={styles.artifactDuration}>
97
+ <div className={styles.artifactTitle}>
98
+ <span>Duration</span>
99
+ </div>
100
+ <div className={styles.artifactValue}>
101
+ <SkeletonText />
102
+ </div>
103
+ </div>
104
+ </div>
105
+ {!disableActions && (
106
+ <>
107
+ <div className={styles.divider}></div>
108
+ <div className={styles.actions}>
109
+ <Button
110
+ id="download-evaluations"
111
+ renderIcon={Download}
112
+ kind={'ghost'}
113
+ iconDescription={'Download evaluations'}
114
+ tooltipAlignment={'end'}
115
+ tooltipPosition={'bottom'}
116
+ disabled
117
+ >
118
+ Download evaluations
119
+ </Button>
120
+ </div>
121
+ </>
122
+ )}
123
+ </div>
124
+ </Tile>
125
+ );
126
+ }
src/components/filters/Filters.module.scss ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ *
3
+ * Copyright 2023-2024 InspectorRAGet Team
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ *
17
+ **/
18
+
19
+ @use '@carbon/react/scss/spacing' as *;
20
+ @use '@carbon/colors' as *;
21
+
22
+ .filtersBtnTooltip {
23
+ align-self: center;
24
+ margin-bottom: $spacing-03;
25
+ }
26
+
27
+ .filtersBtn {
28
+ display: flex;
29
+ column-gap: $spacing-04;
30
+ padding: $spacing-03;
31
+ color: inherit !important;
32
+ }
33
+
34
+ .filtersBtnElements {
35
+ display: flex;
36
+ column-gap: $spacing-04;
37
+ align-items: center;
38
+ }
39
+
40
+ .filtersBtnCaptionElements {
41
+ display: flex;
42
+ column-gap: $spacing-02;
43
+ align-items: center;
44
+ }
45
+
46
+ .filters {
47
+ margin: 0 0 $spacing-03 $spacing-05;
48
+ padding: $spacing-05;
49
+ display: none;
50
+ align-items: baseline;
51
+ column-gap: $spacing-09;
52
+ box-shadow: 0 0 5px 2px $gray-40;
53
+ }
54
+
55
+ .visible {
56
+ display: flex;
57
+ animation: fade-in 0.5s;
58
+ }
59
+
60
+ @keyframes fade-in {
61
+ from {
62
+ opacity: 0;
63
+ }
64
+
65
+ to {
66
+ opacity: 1;
67
+ }
68
+ }
69
+
70
+ .filterSelector {
71
+ max-width: 25%;
72
+ }
src/components/filters/Filters.tsx ADDED
@@ -0,0 +1,137 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ *
3
+ * Copyright 2023-2024 InspectorRAGet Team
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ *
17
+ **/
18
+
19
+ 'use client';
20
+
21
+ import { isEmpty, omit } from 'lodash';
22
+ import cx from 'classnames';
23
+ import { useState, useEffect } from 'react';
24
+
25
+ import { FilterableMultiSelect, Tag, Tooltip, Button } from '@carbon/react';
26
+ import { ChevronUp, ChevronDown, Filter } from '@carbon/icons-react';
27
+
28
+ import classes from './Filters.module.scss';
29
+ // ===================================================================================
30
+ // TYPES
31
+ // ===================================================================================
32
+ interface Props {
33
+ keyPrefix: string;
34
+ filters: { [key: string]: string[] };
35
+ selectedFilters: { [key: string]: string[] };
36
+ setSelectedFilters: Function;
37
+ }
38
+
39
+ // ===================================================================================
40
+ // MAIN FUNCTION
41
+ // ===================================================================================
42
+ export default function Filters({
43
+ keyPrefix,
44
+ filters,
45
+ selectedFilters,
46
+ setSelectedFilters,
47
+ }: Props) {
48
+ // Step 1: Initialize state and necessary variables
49
+ const [showFilters, setShowFilters] = useState<boolean>(true);
50
+
51
+ // Step 2: Run effects
52
+ // Step 2.a: If no filters are found, set show filters to false
53
+ useEffect(() => {
54
+ if (filters === undefined) {
55
+ setShowFilters(false);
56
+ }
57
+ }, [filters]);
58
+
59
+ // Step 3: Render
60
+ return (
61
+ <>
62
+ {filters && (
63
+ <Tooltip
64
+ label={'Click to toggel filters'}
65
+ align={'right'}
66
+ className={classes.filtersBtnTooltip}
67
+ >
68
+ <Button
69
+ id={`${keyPrefix}-filters`}
70
+ className={classes.filtersBtn}
71
+ kind={'ghost'}
72
+ size={'sm'}
73
+ onClick={() => {
74
+ setShowFilters(!showFilters);
75
+ }}
76
+ disabled={!filters}
77
+ >
78
+ <div className={classes.filtersBtnElements}>
79
+ {showFilters ? (
80
+ <ChevronUp size={24} />
81
+ ) : (
82
+ <ChevronDown size={24} />
83
+ )}
84
+ <div className={classes.filtersBtnCaptionElements}>
85
+ <h5>Additional Filters</h5>
86
+ <Filter />
87
+ </div>
88
+ </div>
89
+ </Button>
90
+ </Tooltip>
91
+ )}
92
+ <div className={cx(classes.filters, showFilters && classes.visible)}>
93
+ {showFilters &&
94
+ filters &&
95
+ Object.entries(filters).map(([filterType, values]) => {
96
+ return (
97
+ <div
98
+ key={`${keyPrefix}-filter` + filterType + '-selector'}
99
+ className={classes.filterSelector}
100
+ >
101
+ <FilterableMultiSelect
102
+ id={`${keyPrefix}-filter` + filterType + '-selector'}
103
+ titleText={filterType}
104
+ items={values}
105
+ itemToString={(item) => String(item)}
106
+ onChange={(event) => {
107
+ setSelectedFilters((prevState) =>
108
+ isEmpty(event.selectedItems)
109
+ ? omit(prevState, filterType)
110
+ : {
111
+ ...prevState,
112
+ [filterType]: event.selectedItems,
113
+ },
114
+ );
115
+ }}
116
+ ></FilterableMultiSelect>
117
+ {Object.keys(selectedFilters).includes(filterType) ? (
118
+ <div>
119
+ {selectedFilters[filterType].map((value) => {
120
+ return (
121
+ <Tag
122
+ type={'cool-gray'}
123
+ key={`${keyPrefix}-filter-value` + value}
124
+ >
125
+ {value}
126
+ </Tag>
127
+ );
128
+ })}
129
+ </div>
130
+ ) : null}
131
+ </div>
132
+ );
133
+ })}
134
+ </div>
135
+ </>
136
+ );
137
+ }
src/components/filters/SkeletonFilters.tsx ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ *
3
+ * Copyright 2023-2024 InspectorRAGet Team
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ *
17
+ **/
18
+
19
+ 'use client';
20
+
21
+ import cx from 'classnames';
22
+
23
+ import { SelectSkeleton, TagSkeleton, Tooltip, Button } from '@carbon/react';
24
+ import { ChevronUp, Filter } from '@carbon/icons-react';
25
+
26
+ import classes from './Filters.module.scss';
27
+
28
+ // ===================================================================================
29
+ // MAIN FUNCTION
30
+ // ===================================================================================
31
+ export default function SkeletonFilters() {
32
+ return (
33
+ <>
34
+ <Tooltip
35
+ label={'Click to toggel filters'}
36
+ align={'right'}
37
+ className={classes.filtersBtnTooltip}
38
+ >
39
+ <Button
40
+ id={`skeleton-filters`}
41
+ className={classes.filtersBtn}
42
+ kind={'ghost'}
43
+ size={'sm'}
44
+ >
45
+ <div className={classes.filtersBtnElements}>
46
+ <ChevronUp size={24} />
47
+ <div className={classes.filtersBtnCaptionElements}>
48
+ <h5>Additional Filters</h5>
49
+ <Filter />
50
+ </div>
51
+ </div>
52
+ </Button>
53
+ </Tooltip>
54
+
55
+ <div className={cx(classes.filters, classes.visible)}>
56
+ {['1', '2', '3'].map((filter) => {
57
+ return (
58
+ <div
59
+ key={`$filter-` + filter + '-selector'}
60
+ className={classes.filterSelector}
61
+ style={{ width: '15%' }}
62
+ >
63
+ <SelectSkeleton />
64
+ <TagSkeleton />
65
+ </div>
66
+ );
67
+ })}
68
+ </div>
69
+ </>
70
+ );
71
+ }
src/components/header/Header.jsx ADDED
@@ -0,0 +1,114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ *
3
+ * Copyright 2023-2024 InspectorRAGet Team
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ *
17
+ **/
18
+
19
+ 'use client';
20
+
21
+ import Link from 'next/link';
22
+ import { React, memo } from 'react';
23
+ import {
24
+ Header,
25
+ HeaderName,
26
+ HeaderGlobalBar,
27
+ HeaderGlobalAction,
28
+ Theme,
29
+ } from '@carbon/react';
30
+
31
+ import {
32
+ Home,
33
+ DocumentExport,
34
+ Debug,
35
+ LogoGithub,
36
+ Awake,
37
+ Asleep,
38
+ } from '@carbon/icons-react';
39
+
40
+ import { useTheme } from '@/src/theme';
41
+ import { useDataStore } from '@/src/store';
42
+ import { useNotification } from '@/src/components/notification/Notification';
43
+ import { exportData } from '@/src/processor';
44
+
45
+ import classes from './Header.module.scss';
46
+
47
+ export default memo(function HeaderView() {
48
+ const { theme, set } = useTheme();
49
+ const { item, taskMap } = useDataStore();
50
+ const { createNotification } = useNotification();
51
+
52
+ return (
53
+ <Header aria-label="InspectorRAGet">
54
+ <Link className={classes.homeBtn} href="/">
55
+ <Home height={'16px'} width={'16px'} />
56
+ </Link>
57
+ <HeaderName prefix="">InspectorRAGet</HeaderName>
58
+ <HeaderGlobalBar>
59
+ <HeaderGlobalAction
60
+ aria-label={
61
+ theme === 'white' ? 'Switch to dark mode' : 'Switch to light mode'
62
+ }
63
+ onClick={() => {
64
+ theme === 'white' ? set('g100') : set('white');
65
+ }}
66
+ >
67
+ {theme === 'white' ? <Asleep size={20} /> : <Awake size={20} />}
68
+ </HeaderGlobalAction>
69
+ <HeaderGlobalAction
70
+ aria-label="Export"
71
+ onClick={() => {
72
+ const success = exportData(item, Array.from(taskMap.values()));
73
+ if (success) {
74
+ // Notify user about successfuly export
75
+ createNotification({
76
+ kind: 'success',
77
+ title: 'Export successful.',
78
+ subtitle: 'Please look into browser default save location.',
79
+ });
80
+ } else {
81
+ // Notify user about invalid request
82
+ createNotification({
83
+ kind: 'error',
84
+ title: 'Export unsuccessful.',
85
+ subtitle: 'No visualized analytics data available to export.',
86
+ });
87
+ }
88
+ }}
89
+ >
90
+ <DocumentExport size={20} />
91
+ </HeaderGlobalAction>
92
+ <HeaderGlobalAction
93
+ aria-label="Report bug"
94
+ onClick={() => {
95
+ window.open(
96
+ 'https://github.com/IBM/InspectorRAGet/issues/new?assignees=&labels=&template=bug_report.md&title=',
97
+ '_blank',
98
+ );
99
+ }}
100
+ >
101
+ <Debug size={20} />
102
+ </HeaderGlobalAction>
103
+ <HeaderGlobalAction
104
+ aria-label="Github"
105
+ onClick={() => {
106
+ window.open('https://github.com/IBM/InspectorRAGet', '_blank');
107
+ }}
108
+ >
109
+ <LogoGithub size={20} />
110
+ </HeaderGlobalAction>
111
+ </HeaderGlobalBar>
112
+ </Header>
113
+ );
114
+ });
src/components/header/Header.module.scss ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ *
3
+ * Copyright 2023-2024 InspectorRAGet Team
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ *
17
+ **/
18
+
19
+ @use '@carbon/react/scss/spacing' as *;
20
+ @use '@carbon/colors' as *;
21
+
22
+ .homeBtn {
23
+ width: $spacing-09;
24
+ height: $spacing-09;
25
+ padding: 0 $spacing-03;
26
+ color: inherit !important;
27
+ display: flex;
28
+ justify-content: center;
29
+ align-items: center;
30
+ }
31
+
32
+ .homeBtn:hover {
33
+ background-color: var(--cds-background-hover);
34
+ }
src/components/notification/Notification.module.scss ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ *
3
+ * Copyright 2023-2024 InspectorRAGet Team
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ *
17
+ **/
18
+
19
+ .notification {
20
+ position: fixed;
21
+ top: 4rem;
22
+ right: 1rem;
23
+ z-index: 20;
24
+ }
src/components/notification/Notification.tsx ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ *
3
+ * Copyright 2023-2024 InspectorRAGet Team
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ *
17
+ **/
18
+
19
+ 'use client';
20
+
21
+ import { createContext, useContext, useState, useRef } from 'react';
22
+ import { ToastNotification } from '@carbon/react';
23
+
24
+ import { Notification as NotificationType } from '@/src/types';
25
+
26
+ import styles from './Notification.module.scss';
27
+
28
+ type NotificationContextType = {
29
+ createNotification(notification: NotificationType, timeout?: number): void;
30
+ };
31
+
32
+ const NotificationContext = createContext<NotificationContextType | undefined>(
33
+ undefined,
34
+ );
35
+
36
+ const NotificationComponent = ({
37
+ title,
38
+ subtitle,
39
+ kind,
40
+ caption,
41
+ }: NotificationType) => (
42
+ <ToastNotification
43
+ hideCloseButton={true}
44
+ className={styles.notification}
45
+ closeOnEscape={false}
46
+ title={title}
47
+ kind={kind}
48
+ subtitle={subtitle}
49
+ caption={caption}
50
+ />
51
+ );
52
+
53
+ export const NotificationProvider = ({ children }: { children: any }) => {
54
+ const [notification, setNotification] = useState<
55
+ NotificationType | undefined
56
+ >();
57
+ const timeoutId = useRef<NodeJS.Timeout | undefined>();
58
+
59
+ const createNotification = (
60
+ notification: NotificationType,
61
+ timeout?: number,
62
+ ) => {
63
+ if (timeoutId.current) {
64
+ clearTimeout(timeoutId.current);
65
+ }
66
+ setNotification(notification);
67
+ timeoutId.current = setTimeout(
68
+ () => {
69
+ setNotification(undefined);
70
+ },
71
+ timeout ? timeout : 5000,
72
+ );
73
+ };
74
+
75
+ return (
76
+ <NotificationContext.Provider value={{ createNotification }}>
77
+ {children}
78
+ {notification && <NotificationComponent {...notification} />}
79
+ </NotificationContext.Provider>
80
+ );
81
+ };
82
+
83
+ export const useNotification = () => {
84
+ const context = useContext(NotificationContext);
85
+ if (context === undefined) {
86
+ throw new Error(
87
+ 'useNotification must be used within a NotificationProvider',
88
+ );
89
+ }
90
+ return context;
91
+ };
src/components/selectors/AggregatorSelector.tsx ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ *
3
+ * Copyright 2023-2024 InspectorRAGet Team
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ *
17
+ **/
18
+
19
+ 'use client';
20
+
21
+ import { memo } from 'react';
22
+ import { Select, SelectItem } from '@carbon/react';
23
+
24
+ import { Aggregator } from '@/src/types';
25
+
26
+ interface Props {
27
+ aggregators: Aggregator[];
28
+ onSelect: Function;
29
+ defaultValue: Aggregator;
30
+ warn: boolean;
31
+ warnText?: string;
32
+ disableDefaultValue?: boolean;
33
+ disabledAggregators?: Aggregator[];
34
+ disabled?: boolean;
35
+ }
36
+ export default memo(function AggregatorSelector({
37
+ aggregators: aggregators,
38
+ onSelect,
39
+ defaultValue,
40
+ warn = false,
41
+ warnText = 'You must select an aggregator to view results.',
42
+ disabledAggregators: disabledAggregators,
43
+ disabled = false,
44
+ }: Props) {
45
+ return (
46
+ <Select
47
+ id={'aggregator-selector'}
48
+ labelText="Choose aggregator"
49
+ defaultValue={defaultValue.name}
50
+ disabled={disabled}
51
+ warn={warn}
52
+ warnText={warnText}
53
+ onChange={(event) => {
54
+ onSelect(
55
+ aggregators.find(
56
+ (aggregator) => aggregator.name === event.target.value,
57
+ ),
58
+ );
59
+ }}
60
+ >
61
+ {aggregators.map((aggregator) => {
62
+ return (
63
+ <SelectItem
64
+ key={`${aggregator.name}-selector`}
65
+ value={aggregator.name}
66
+ text={
67
+ aggregator.displayName ? aggregator.displayName : aggregator.name
68
+ }
69
+ disabled={
70
+ disabledAggregators &&
71
+ disabledAggregators
72
+ .map((entry) => entry.name)
73
+ .includes(aggregator.name)
74
+ }
75
+ ></SelectItem>
76
+ );
77
+ })}
78
+ </Select>
79
+ );
80
+ });
src/components/selectors/MetricSelector.tsx ADDED
@@ -0,0 +1,135 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ *
3
+ * Copyright 2023-2024 InspectorRAGet Team
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ *
17
+ **/
18
+
19
+ 'use client';
20
+
21
+ import { memo } from 'react';
22
+ import { Select, SelectItem, SelectItemGroup } from '@carbon/react';
23
+
24
+ import { Metric } from '@/src/types';
25
+ import { extractMetricDisplayName } from '@/src/utilities/metrics';
26
+
27
+ interface Props {
28
+ metrics: Metric[];
29
+ onSelect: Function;
30
+ warn: boolean;
31
+ warnText?: string;
32
+ defaultValue?: string;
33
+ disableDefaultValue?: boolean;
34
+ disabledMetrics?: Metric[];
35
+ disabled?: boolean;
36
+ }
37
+ export default memo(function MetricSelector({
38
+ metrics,
39
+ onSelect,
40
+ warn = false,
41
+ warnText = 'You must select a single metric to view tasks.',
42
+ defaultValue = 'all',
43
+ disableDefaultValue = false,
44
+ disabledMetrics,
45
+ disabled = false,
46
+ }: Props) {
47
+ const metricTypes = new Set(metrics.map((metric) => metric.type));
48
+
49
+ return (
50
+ <Select
51
+ id={'metric-selector'}
52
+ labelText="Choose metric"
53
+ disabled={disabled}
54
+ defaultValue={defaultValue}
55
+ warn={warn}
56
+ warnText={warnText}
57
+ onChange={(event) => {
58
+ onSelect(
59
+ event.target.value !== defaultValue
60
+ ? metrics.find((metric) => metric.name === event.target.value)
61
+ : undefined,
62
+ );
63
+ }}
64
+ >
65
+ <SelectItem
66
+ key={'default-selector'}
67
+ text={
68
+ defaultValue.charAt(0).toUpperCase() +
69
+ defaultValue.slice(1).toLowerCase()
70
+ }
71
+ value={defaultValue}
72
+ disabled={disableDefaultValue}
73
+ />
74
+ {metricTypes.size > 1 ? (
75
+ <>
76
+ <SelectItemGroup key={'human-metric-selectors'} label={'Human'}>
77
+ {metrics
78
+ .filter((metric) => metric.author === 'human')
79
+ .map((metric) => {
80
+ return (
81
+ <SelectItem
82
+ key={`${metric.name}-selector`}
83
+ value={metric.name}
84
+ text={extractMetricDisplayName(metric)}
85
+ disabled={
86
+ disabledMetrics &&
87
+ disabledMetrics
88
+ .map((entry) => entry.name)
89
+ .includes(metric.name)
90
+ }
91
+ ></SelectItem>
92
+ );
93
+ })}
94
+ </SelectItemGroup>
95
+ <SelectItemGroup
96
+ key={'algorithmic-metric-selectors'}
97
+ label={'Algorithmic'}
98
+ >
99
+ {metrics
100
+ .filter((metric) => metric.author === 'algorithm')
101
+ .map((metric) => {
102
+ return (
103
+ <SelectItem
104
+ key={`${metric.name}-selector`}
105
+ value={metric.name}
106
+ text={extractMetricDisplayName(metric)}
107
+ disabled={
108
+ disabledMetrics &&
109
+ disabledMetrics
110
+ .map((entry) => entry.name)
111
+ .includes(metric.name)
112
+ }
113
+ ></SelectItem>
114
+ );
115
+ })}
116
+ </SelectItemGroup>
117
+ </>
118
+ ) : (
119
+ metrics.map((metric) => {
120
+ return (
121
+ <SelectItem
122
+ key={`${metric.name}-selector`}
123
+ value={metric.name}
124
+ text={extractMetricDisplayName(metric)}
125
+ disabled={
126
+ disabledMetrics &&
127
+ disabledMetrics.map((entry) => entry.name).includes(metric.name)
128
+ }
129
+ ></SelectItem>
130
+ );
131
+ })
132
+ )}
133
+ </Select>
134
+ );
135
+ });
src/components/selectors/ModelSelector.tsx ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ *
3
+ * Copyright 2023-2024 InspectorRAGet Team
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ *
17
+ **/
18
+
19
+ 'use client';
20
+
21
+ import { memo } from 'react';
22
+ import { Select, SelectItem } from '@carbon/react';
23
+
24
+ import { Model } from '@/src/types';
25
+
26
+ interface Props {
27
+ id: string;
28
+ models: Model[];
29
+ onSelect: Function;
30
+ defaultValue?: Model;
31
+ disabledModels?: Model[];
32
+ warn?: boolean;
33
+ warnText?: string;
34
+ disabled?: boolean;
35
+ }
36
+ export default memo(function ModelSelector({
37
+ id,
38
+ models,
39
+ onSelect,
40
+ defaultValue,
41
+ disabledModels,
42
+ warn = false,
43
+ warnText,
44
+ disabled = false,
45
+ }: Props) {
46
+ return (
47
+ <Select
48
+ id={id}
49
+ defaultValue={defaultValue?.modelId}
50
+ labelText="Choose a model"
51
+ disabled={disabled}
52
+ onChange={(event) => {
53
+ onSelect(event.target.value);
54
+ }}
55
+ warn={warn}
56
+ warnText={warnText}
57
+ >
58
+ {models.map((model) => {
59
+ return (
60
+ <SelectItem
61
+ key={`${model.modelId}-selector`}
62
+ disabled={
63
+ disabledModels &&
64
+ disabledModels
65
+ .map((entry) => entry.modelId)
66
+ .includes(model.modelId)
67
+ }
68
+ value={model.modelId}
69
+ text={model.name}
70
+ ></SelectItem>
71
+ );
72
+ })}
73
+ </Select>
74
+ );
75
+ });
src/components/task-tile/SkeletonTaskTile.tsx ADDED
@@ -0,0 +1,124 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ *
3
+ * Copyright 2023-2024 InspectorRAGet Team
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ *
17
+ **/
18
+
19
+ 'use client';
20
+
21
+ import Link from 'next/link';
22
+ import {
23
+ Tile,
24
+ Tag,
25
+ SkeletonText,
26
+ Toggletip,
27
+ ToggletipButton,
28
+ ToggletipContent,
29
+ ToggletipActions,
30
+ UnorderedList,
31
+ ListItem,
32
+ } from '@carbon/react';
33
+ import { Task as TaskIcon, Information } from '@carbon/icons-react';
34
+
35
+ import styles from './TaskTile.module.scss';
36
+
37
+ export default function SkeletonTaskTile() {
38
+ return (
39
+ <Tile className={styles.tile}>
40
+ <div className={styles.heading}>
41
+ <TaskIcon className={styles.icon} />
42
+ <span className={styles.title}>
43
+ <SkeletonText />
44
+ </span>
45
+ </div>
46
+ <div className={styles.block}>
47
+ <div className={styles.information}>
48
+ <div className={styles.artifactEvaluations}>
49
+ <div className={styles.artifactTitle}>
50
+ <span># of evaluations</span>
51
+ </div>
52
+ <div className={styles.artifactValue}>
53
+ <span>
54
+ <SkeletonText />
55
+ </span>
56
+ </div>
57
+ </div>
58
+ <div className={styles.artifactAnnotators}>
59
+ <div className={styles.artifactTitle}>
60
+ <span># of annotators</span>
61
+ </div>
62
+ <div className={styles.artifactValue}>
63
+ <span>
64
+ <SkeletonText />
65
+ </span>
66
+ </div>
67
+ </div>
68
+ <div className={styles.artifactMetrics}>
69
+ <div className={styles.artifactTitle}>
70
+ <span>Metrics</span>
71
+ <Toggletip>
72
+ <ToggletipButton label="Additional information">
73
+ <Information />
74
+ </ToggletipButton>
75
+ <ToggletipContent>
76
+ <p>Analytics platform supports three kind of metrics</p>
77
+ <UnorderedList>
78
+ <ListItem className={styles.listItem}>
79
+ Go vs No-Go Rubric
80
+ </ListItem>
81
+ <ListItem className={styles.listItem}>
82
+ Intuitive Rubric
83
+ </ListItem>
84
+ <ListItem className={styles.listItem}>
85
+ Detailed Rubric
86
+ </ListItem>
87
+ </UnorderedList>
88
+ <ToggletipActions>
89
+ <Link target="_blank" rel="noopener noreferrer" href="">
90
+ Reference
91
+ </Link>
92
+ </ToggletipActions>
93
+ </ToggletipContent>
94
+ </Toggletip>
95
+ </div>
96
+ <div className={styles.artifactValue}>
97
+ {['faithfulness'].map((metric, idx) => {
98
+ return (
99
+ <Tag type={'cool-gray'} key={'metric-' + idx}>
100
+ {metric}
101
+ </Tag>
102
+ );
103
+ })}
104
+ </div>
105
+ </div>
106
+ <div className={styles.artifactModels}>
107
+ <div className={styles.artifactTitle}>
108
+ <span>Models</span>
109
+ </div>
110
+ <div className={styles.artifactValue}>
111
+ {['Model A', 'Model B', 'Model C'].map((model, idx) => {
112
+ return (
113
+ <Tag type={'cool-gray'} key={'model-' + idx}>
114
+ {model}
115
+ </Tag>
116
+ );
117
+ })}
118
+ </div>
119
+ </div>
120
+ </div>
121
+ </div>
122
+ </Tile>
123
+ );
124
+ }