Skip to content

Commit

Permalink
Added discussion post summary
Browse files Browse the repository at this point in the history
  • Loading branch information
ajturner committed Sep 6, 2024
1 parent dbc7c0a commit d642634
Show file tree
Hide file tree
Showing 7 changed files with 148 additions and 55 deletions.
16 changes: 16 additions & 0 deletions src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* It contains typing information for all components that exist in this project.
*/
import { HTMLStencilElement, JSXBase } from "@stencil/core/internal";
import { HubPostSummary } from "./util/search";
export namespace Components {
interface HubModerationAssistant {
/**
Expand All @@ -21,6 +22,9 @@ export namespace Components {
interface HubPostsResults {
"posts": any[];
}
interface HubPostsSummary {
"summary": HubPostSummary;
}
}
export interface HubModerationFiltersCustomEvent<T> extends CustomEvent<T> {
detail: T;
Expand Down Expand Up @@ -51,11 +55,18 @@ declare global {
prototype: HTMLHubPostsResultsElement;
new (): HTMLHubPostsResultsElement;
};
interface HTMLHubPostsSummaryElement extends Components.HubPostsSummary, HTMLStencilElement {
}
var HTMLHubPostsSummaryElement: {
prototype: HTMLHubPostsSummaryElement;
new (): HTMLHubPostsSummaryElement;
};
interface HTMLElementTagNameMap {
"hub-moderation-assistant": HTMLHubModerationAssistantElement;
"hub-moderation-filters": HTMLHubModerationFiltersElement;
"hub-post-card": HTMLHubPostCardElement;
"hub-posts-results": HTMLHubPostsResultsElement;
"hub-posts-summary": HTMLHubPostsSummaryElement;
}
}
declare namespace LocalJSX {
Expand All @@ -75,11 +86,15 @@ declare namespace LocalJSX {
interface HubPostsResults {
"posts"?: any[];
}
interface HubPostsSummary {
"summary"?: HubPostSummary;
}
interface IntrinsicElements {
"hub-moderation-assistant": HubModerationAssistant;
"hub-moderation-filters": HubModerationFilters;
"hub-post-card": HubPostCard;
"hub-posts-results": HubPostsResults;
"hub-posts-summary": HubPostsSummary;
}
}
export { LocalJSX as JSX };
Expand All @@ -90,6 +105,7 @@ declare module "@stencil/core" {
"hub-moderation-filters": LocalJSX.HubModerationFilters & JSXBase.HTMLAttributes<HTMLHubModerationFiltersElement>;
"hub-post-card": LocalJSX.HubPostCard & JSXBase.HTMLAttributes<HTMLHubPostCardElement>;
"hub-posts-results": LocalJSX.HubPostsResults & JSXBase.HTMLAttributes<HTMLHubPostsResultsElement>;
"hub-posts-summary": LocalJSX.HubPostsSummary & JSXBase.HTMLAttributes<HTMLHubPostsSummaryElement>;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
background-color: var(--calcite-color-background);
height: 100%;
display: flex;
margin: 4rem;
margin: 1rem;
/* align-items: center;
justify-content: center; */
font-size: var(--calcite-font-size-1);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Component, Host, Listen, Prop, State, h } from '@stencil/core';
import { setAssetPath } from '@esri/calcite-components/dist/components';
import { fetchPosts, PostFilters } from '../../util/search';
import { fetchPosts, fetchPostsSummary, PostFilters } from '../../util/search';

setAssetPath('https://js.arcgis.com/calcite-components/2.11/assets');

Expand All @@ -17,8 +17,19 @@ export class HubModerationAssistant {



/**
* Posts fetched from API
*/
@State() posts: any[] = [];

/**
*
*/
@State() summary: any = "";

/**
* Organization name
*/
@State() org: any = {
name: "CityX"
}
Expand All @@ -44,14 +55,18 @@ export class HubModerationAssistant {
...filters
}
const context = {
limit: 100,
// limit: 100,
channelId: this.channelId,
}
try {
// Fetch posts from API using search util
const data = await fetchPosts( params, context);

this.posts = data.features;

const summary = await fetchPostsSummary(params, context);
this.summary = summary.summary;

// Process the fetched data
// ...

Expand Down Expand Up @@ -118,6 +133,10 @@ export class HubModerationAssistant {
{/* Body */}
<calcite-panel slot="">
<div class="page">
<hub-posts-summary summary={this.summary}></hub-posts-summary>
</div>
<div class="page">

<hub-posts-results posts={this.posts}></hub-posts-results>
</div>
</calcite-panel>
Expand Down
7 changes: 7 additions & 0 deletions src/components/hub-posts-summary/hub-posts-summary.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
:host {
display: block;
background-color: white;
border-radius: 4px;
padding: 1rem;
border: 1px solid var(--calcite-color-border-1);
}
25 changes: 25 additions & 0 deletions src/components/hub-posts-summary/hub-posts-summary.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Component, Host, Prop, h } from '@stencil/core';
import { HubPostSummary } from '../../util/search';

@Component({
tag: 'hub-posts-summary',
styleUrl: 'hub-posts-summary.css',
shadow: true,
})
export class HubPostsSummary {

@Prop() summary: HubPostSummary = {};

render() {
return (
<Host>
<slot></slot>
<div class="summary">
<h3>Summary</h3>
<p>{this.summary.text}</p>
</div>
</Host>
);
}

}
82 changes: 41 additions & 41 deletions src/util/analysis.ts
Original file line number Diff line number Diff line change
@@ -1,50 +1,50 @@
export interface Analysis {
range: [number, number];
name: string;
icon: string;
selected: boolean;
}
range: [number, number];
name: string;
icon: string;
selected: boolean;
}

export const authenticityAnalysis: Analysis[] = [
{ range: [0.2, Infinity], name: 'Authentic', icon: 'check-circle-f', selected: true },
{ range: [-0.5, 0.2], name: 'Neutral Authenticity', icon: 'rings', selected: false },
{ range: [-Infinity, -0.5], name: 'Fake', icon: 'exclamation-mark-triangle-f', selected: false },
{ range: [-Infinity, Infinity], name: 'Unknown', icon: 'question', selected: false },
];
export const authenticityAnalysis: Analysis[] = [
{ range: [0.2, 1], name: 'Authentic', icon: 'check-circle-f', selected: true },
{ range: [-0.5, 0.2], name: 'Neutral Authenticity', icon: 'rings', selected: false },
{ range: [-1, -0.5], name: 'Fake', icon: 'exclamation-mark-triangle-f', selected: false },
{ range: [-1, 1], name: 'Unknown', icon: 'question', selected: false },
];

export const sentimentAnalysis: Analysis[] = [
{ range: [0.3, Infinity], name: 'Positive', icon: 'check-circle-f', selected: true },
{ range: [0, 0.3], name: 'Slightly Positive', icon: 'rings', selected: false },
{ range: [-0.5, 0], name: 'Slightly Negative', icon: 'rings', selected: false },
{ range: [-Infinity, -0.5], name: 'Negative', icon: 'exclamation-mark-triangle-f', selected: false },
{ range: [-Infinity, Infinity], name: 'Unknown', icon: 'question', selected: false },
];
export const sentimentAnalysis: Analysis[] = [
{ range: [0.3, 1], name: 'Positive', icon: 'check-circle-f', selected: true },
{ range: [0, 0.3], name: 'Slightly Positive', icon: 'rings', selected: false },
{ range: [-0.5, 0], name: 'Slightly Negative', icon: 'rings', selected: false },
{ range: [-1, -0.5], name: 'Negative', icon: 'exclamation-mark-triangle-f', selected: false },
{ range: [-1, 1], name: 'Unknown', icon: 'question', selected: false },
];

export const toxicityAnalysis: Analysis[] = [
{ range: [0.2, Infinity], name: 'OK', icon: 'check-circle-f', selected: false },
{ range: [-0.5, 0.2], name: 'Neutral', icon: 'rings', selected: true },
{ range: [-Infinity, -0.5], name: 'Toxic', icon: 'exclamation-mark-triangle-f', selected: false },
{ range: [-Infinity, Infinity], name: 'Unknown', icon: 'question', selected: false },
];
export const toxicityAnalysis: Analysis[] = [
{ range: [0.2, 1], name: 'OK', icon: 'check-circle-f', selected: false },
{ range: [-0.5, 0.2], name: 'Neutral', icon: 'rings', selected: true },
{ range: [-1, -0.5], name: 'Toxic', icon: 'exclamation-mark-triangle-f', selected: false },
{ range: [-1, 1], name: 'Unknown', icon: 'question', selected: false },
];


export function getAnalysisConfiguration(name: string): Analysis[] {
switch (name) {
case 'authenticity':
return authenticityAnalysis;
case 'sentiment':
return sentimentAnalysis;
case 'toxicity':
return toxicityAnalysis;
default:
return [];
}
export function getAnalysisConfiguration(name: string): Analysis[] {
switch (name) {
case 'authenticity':
return authenticityAnalysis;
case 'sentiment':
return sentimentAnalysis;
case 'toxicity':
return toxicityAnalysis;
default:
return [];
}
export function getAnalysisValue(value: number, analysis: Analysis[]): Analysis {
for (const item of analysis) {
if (value > item.range[0] && value <= item.range[1]) {
return item;
}
}
export function getAnalysisValue(value: number, analysis: Analysis[]): Analysis {
for (const item of analysis) {
if (value > item.range[0] && value <= item.range[1]) {
return item;
}
return analysis[analysis.length - 1];
}
return analysis[analysis.length - 1];
}
48 changes: 37 additions & 11 deletions src/util/search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,40 @@ export interface PostFilters {
channelId?: string;
}

export interface HubPostSummary {
numberConsidered?: number;
numberErrored?: number;
numberMatched?: number;
numberSummarized?: number;
text?: string;
}

export async function fetchPosts(filters: PostFilters = {}, context: any = {}): Promise<any> {
const baseUrl = `${HUB_API_BASE_URL}/search/v2/collections/discussion-post/items`;

const url = buildDiscussionAPIUrl(context, filters, baseUrl);

try {
const response = await axios.get(url);
return response.data;
} catch (error) {
console.error('Error fetching posts:', error);
throw error;
}
}

function buildDiscussionAPIUrl(context: any, filters: PostFilters, baseUrl: string) {
const contextQuery = Object.entries(context)
.filter(([_, value]) => value !== undefined)
.map(([key, value]) => {
if (Array.isArray(value)) {
const [min, max] = value;
return `filter=${key}%3E=${min}+and+${key}%3C=${max}`;
} else {
return `${key}=${value}`;
}
})
.join('&');
.filter(([_, value]) => value !== undefined)
.map(([key, value]) => {
if (Array.isArray(value)) {
const [min, max] = value;
return `filter=${key}%3E=${min}+and+${key}%3C=${max}`;
} else {
return `${key}=${value}`;
}
})
.join('&');


const filterQuery = Object.entries(filters)
Expand All @@ -43,12 +63,18 @@ export async function fetchPosts(filters: PostFilters = {}, context: any = {}):
.join('+and+');

const url = contextQuery ? `${baseUrl}?${contextQuery}&filter=${filterQuery}` : baseUrl;
return url;
}

export async function fetchPostsSummary(filters: PostFilters = {}, context: any = {}): Promise<any> {
const baseUrl = `${HUB_API_BASE_URL}/search/v2/collections/discussion-post/summarize`;

const url = buildDiscussionAPIUrl(context, filters, baseUrl);
try {
const response = await axios.get(url);
return response.data;
} catch (error) {
console.error('Error fetching posts:', error);
throw error;
}
}
}

0 comments on commit d642634

Please sign in to comment.