Skip to content

Commit

Permalink
Merge pull request #2959 from the-deep/feature/tags-analysis-module
Browse files Browse the repository at this point in the history
Contextual data for auto cluster and summarization
  • Loading branch information
AdityaKhatri authored Jun 13, 2024
2 parents 49df55c + a3af782 commit dc4f20b
Show file tree
Hide file tree
Showing 9 changed files with 789 additions and 83 deletions.
212 changes: 212 additions & 0 deletions app/components/TagInput/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
import React, { useState, useCallback } from 'react';
import { _cs } from '@togglecorp/fujs';
import {
IoClose,
IoCheckmarkSharp,
IoAdd,
} from 'react-icons/io5';
import {
Button,
RawInput,
List,
Tag,
TagProps as PropsFromTag,
useBooleanState,
} from '@the-deep/deep-ui';

import styles from './styles.css';

type TagVariant = PropsFromTag['variant'];

interface TagProps extends PropsFromTag {
label: string;
onRemove: (key: string) => void;
variant?: TagVariant;
disabled?: boolean;
readOnly?: boolean;
className?: string;
}

function ModifiedTag(props: TagProps) {
const {
className,
onRemove,
label,
variant,
disabled,
readOnly,
...otherProps
} = props;

return (
<Tag
className={_cs(className, styles.tag)}
actions={!readOnly && (
<Button
name={label}
onClick={onRemove}
className={styles.tagButton}
childrenContainerClassName={styles.children}
disabled={disabled}
icons={(
<IoClose />
)}
/>
)}
variant={variant}
{...otherProps}
>
{label}
</Tag>
);
}

const keySelector = (d: string) => d;
const emptyValue: string[] = [];

interface Props<N extends string> extends PropsFromTag{
className?: string;
tagClassName?: string;
value?: string[];
label: string;
name: N;
variant?: TagVariant;
onChange?: (newVal: string[], name: N) => void;
disabled?: boolean;
readOnly?: boolean;
}

function TagInput<N extends string>(props: Props<N>) {
const {
className,
value = emptyValue,
onChange,
name,
label,
variant,
disabled,
readOnly,
tagClassName,
...otherProps
} = props;

const [newTagValue, setNewTagValue] = useState<string | undefined>();
const [newTagAddShown, showNewTagAdd, hideNewTagAdd] = useBooleanState(false);

const handleTagAdd = useCallback(() => {
if (!newTagValue) {
setNewTagValue(undefined);
hideNewTagAdd();
return;
}

const indexToRemove = value.indexOf(newTagValue);
if (indexToRemove === -1) {
const newValues = [...value];
newValues.push(newTagValue);
if (onChange) {
onChange(newValues, name);
}
}
setNewTagValue(undefined);
hideNewTagAdd();
}, [onChange, value, name, hideNewTagAdd, newTagValue]);

const handleTagRemove = useCallback((tagToRemove: string) => {
const indexToRemove = value.indexOf(tagToRemove);
if (indexToRemove !== -1) {
const newValues = [...value];
newValues.splice(indexToRemove, 1);
if (onChange) {
onChange(newValues, name);
}
}
}, [onChange, value, name]);

const tagRendererParams = useCallback(
(d: string) => ({
label: d,
onRemove: handleTagRemove,
variant,
disabled,
readOnly,
className: tagClassName,
...otherProps,
}),
[handleTagRemove, variant, readOnly, disabled, tagClassName, otherProps],
);

const handleNewTagAddCancel = useCallback(() => {
setNewTagValue(undefined);
hideNewTagAdd();
}, [hideNewTagAdd]);

return (
<div className={_cs(styles.tagInput, className)}>
<div className={styles.label}>
{label}
</div>
<div className={styles.tags}>
<List
data={value}
rendererParams={tagRendererParams}
renderer={ModifiedTag}
keySelector={keySelector}
/>
{!readOnly && (
<Tag
className={styles.tag}
actionsContainerClassName={styles.tagActions}
actions={newTagAddShown ? (
<>
<Button
name="done"
onClick={handleTagAdd}
className={_cs(styles.tagButton, styles.checkButton)}
childrenContainerClassName={styles.children}
disabled={disabled}
icons={(
<IoCheckmarkSharp />
)}
/>
<Button
name="remove"
onClick={handleNewTagAddCancel}
className={_cs(styles.tagButton, styles.cancelButton)}
childrenContainerClassName={styles.children}
disabled={disabled}
icons={(
<IoClose />
)}
/>
</>
) : (
<Button
name="add"
onClick={showNewTagAdd}
className={styles.tagButton}
childrenContainerClassName={styles.children}
disabled={disabled}
icons={(
<IoAdd />
)}
/>
)}
>
{newTagAddShown ? (
<RawInput
name="newTag"
value={newTagValue}
onChange={setNewTagValue}
autoFocus
disabled={disabled}
/>
) : ''}
</Tag>
)}
</div>
</div>
);
}

export default TagInput;
45 changes: 45 additions & 0 deletions app/components/TagInput/styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
.tag-input {
.tag-button {
--padding: var(--dui-spacing-extra-small);
border: none;
border-radius: calc(1em + var(--padding) / 2);
background-color: transparent;
padding: var(--padding);
width: calc(1em + 2 * var(--padding));
height: calc(1em + 2 * var(--padding));
color: inherit;

.children {
padding: 0;
}

&.check-button {
color: var(--dui-color-success);
}

&.cancel-button {
color: var(--dui-color-danger);
}
}

.label {
padding: var(--dui-spacing-small) var(--dui-spacing-medium);
color: var(--dui-color-text-label);
font-size: var(--dui-font-size-small);
font-weight: var(--dui-font-weight-bold);
}

.tags {
display: flex;
flex-wrap: wrap;

.tag {
margin: var(--dui-spacing-extra-small);
}

.tag-actions {
display: flex;
align-items: center;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import React from 'react';

import {
Modal,
Button,
} from '@the-deep/deep-ui';

import TagInput from '#components/TagInput';

interface Props {
widgetTags: string[];
setWidgetTags: React.Dispatch<React.SetStateAction<string[] | undefined>>;
handleSubmitButtonClick: () => void;
onCloseButtonClick: () => void;
}

function SummaryTagsModal(props: Props) {
const {
widgetTags,
setWidgetTags,
handleSubmitButtonClick,
onCloseButtonClick,
} = props;

return (
<Modal
heading="Automatic Summary"
onCloseButtonClick={onCloseButtonClick}
footerActions={(
<Button
name={undefined}
onClick={handleSubmitButtonClick}
>
Submit tags
</Button>
)}
>
Please select/add relevant tags to get better summary.

<TagInput
name="tags"
label="Tags"
value={widgetTags}
onChange={setWidgetTags}
/>
</Modal>
);
}

export default SummaryTagsModal;
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,31 @@ import React, {
} from 'react';
import {
Button,
CollapsibleContainer,
Container,
ListView,
useConfirmation,
Modal,
QuickActionButton,
CollapsibleContainer,
SegmentInput,
Tab,
TabList,
TabPanel,
Tabs,
TextInput,
Tooltip,
useConfirmation,
} from '@the-deep/deep-ui';
import { isDefined, encodeDate, _cs, unique, listToGroupList } from '@togglecorp/fujs';
import {
isDefined,
encodeDate,
_cs,
unique,
listToGroupList,
} from '@togglecorp/fujs';
import {
IoChevronForward,
IoChevronBackOutline,
IoInformation,
} from 'react-icons/io5';
import { VscServerProcess } from 'react-icons/vsc';

Expand Down Expand Up @@ -385,6 +393,16 @@ function StoryAnalysisModal(props: Props) {
>
Automatic Summary
</Tab>
{project?.isPrivate && (
<div className={styles.info}>
<IoInformation />
<Tooltip>
Auto summary is not available
for private projects to
maintain document privacy.
</Tooltip>
</div>
)}
</TabList>
)}
contentClassName={styles.tabPanelContainer}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,18 @@
font-size: var(--dui-font-size-large);
font-weight: var(--dui-font-weight-regular);
}
.info {
display: flex;
align-self: center;
border: var(--dui-width-separator-thin) solid var(--dui-color-separator);
border-radius: 50%;
padding: var(--dui-spacing-extra-small);
font-size: var(--dui-font-size-medium);
}

.brain-icon {
align-self: center;
}

.tab-panel-container {
display: flex;
Expand Down
Loading

0 comments on commit dc4f20b

Please sign in to comment.