Skip to content

Add text list attribute for sharepoint integration tags #78

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 12 commits into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export default function ExecutionContainer(props: ExecutionContainerProps) {
setRequestedSomething(false);
props.setEnabledButton(false);
setRunOn10HasError(sampleRecordsFinal.calculatedAttributes.length > 0 ? false : true);
if (currentAttributesRef.current.dataType == DataTypeEnum.EMBEDDING_LIST) {
if (currentAttributesRef.current.dataType == DataTypeEnum.EMBEDDING_LIST || currentAttributesRef.current.dataType == DataTypeEnum.TEXT_LIST) {
sampleRecordsFinal.calculatedAttributesList = sampleRecordsFinal.calculatedAttributes.map((record: string) => JSON.parse(record));
sampleRecordsFinal.calculatedAttributesListDisplay = extendArrayElementsByUniqueId(sampleRecordsFinal.calculatedAttributesList);
}
Expand Down Expand Up @@ -75,7 +75,13 @@ export default function ExecutionContainer(props: ExecutionContainerProps) {
const sampleRecordsFinal = useMemo(() => {
if (sampleRecords && sampleRecords.calculatedAttributesDisplay) {
return sampleRecords.calculatedAttributesDisplay.map((record: any, index) => {
const calculatedValue = currentAttributesRef.current.dataType != DataTypeEnum.EMBEDDING_LIST ? record : { id: record.id, value: JSON.parse(record.value) }
let calculatedValue;
if (currentAttributesRef.current.dataType == DataTypeEnum.EMBEDDING_LIST || currentAttributesRef.current.dataType == DataTypeEnum.TEXT_LIST) {
calculatedValue = { id: record.id, value: JSON.parse(record.value) };
}
else {
calculatedValue = record
}
return {
...record,
onClick: viewRecordDetails(index),
Expand All @@ -85,7 +91,6 @@ export default function ExecutionContainer(props: ExecutionContainerProps) {
);
}
}, [sampleRecords]);

return (<div>
<div className="mt-8 text-sm leading-5">
<div className="text-gray-700 font-medium mr-2">
Expand Down Expand Up @@ -136,7 +141,7 @@ export default function ExecutionContainer(props: ExecutionContainerProps) {
<div key={record.id} className="divide-y divide-gray-200 bg-white">
<div className="flex-shrink-0 border-b border-gray-200 shadow-sm flex justify-between items-center">
<div className="flex items-center text-xs leading-5 text-gray-500 font-normal mx-4 my-3 text-justify">
{String(record.value)}
{Array.isArray(record?.calculatedValue?.value) ? JSON.stringify(record?.calculatedValue?.value) : String(record?.calculatedValue?.value)}
</div>
<div className="flex items-center justify-center mr-5 ml-auto">
<KernButton
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ export default function LLMPlaygroundModal() {
<div className="grid grid-cols-2 gap-2 text-sm max-h-52 overflow-y-auto" style={{ gridTemplateColumns: `max-content auto` }}>
{recordKeys.map((rk) => <Fragment key={rk.name}>
<label className="block font-bold text-gray-900">{rk.name}</label>
{recordData.map((record) => rk.dataType == DataTypeEnum.EMBEDDING_LIST ? <div key={record.running_id} className="flex flex-col divide-y divide-gray-200">
{recordData.map((record) => (rk.dataType == DataTypeEnum.EMBEDDING_LIST || rk.dataType == DataTypeEnum.TEXT_LIST) ? <div key={record.running_id} className="flex flex-col divide-y divide-gray-200">
{record[rk.name].map((li, idx) => <span key={idx} className="text-gray-700">{li}</span>)}
</div> : <span key={record.running_id} className="text-gray-700">{record[rk.name]}</span>)}
</Fragment>)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,21 @@ import { ModalEnum } from "@/src/types/shared/modal";
import { useSelector } from "react-redux";
import style from '@/src/styles/components/projects/projectId/attribute-calculation.module.css';
import { RecordDisplay } from "@/src/components/shared/record-display/RecordDisplay";
import { DataTypeEnum } from "@/src/types/shared/general";
import { ViewRecordDetailsModalProps } from "@/src/types/components/projects/projectId/settings/attribute-calculation";
import { selectVisibleAttributesHeuristics } from "@/src/reduxStore/states/pages/settings";
import { useMemo } from "react";

export default function ViewRecordDetailsModal(props: ViewRecordDetailsModalProps) {
const modalViewRecordDetails = useSelector(selectModal(ModalEnum.VIEW_RECORD_DETAILS));
const attributes = useSelector(selectVisibleAttributesHeuristics);

const displayValue = useMemo(() => {
if (!props.sampleRecords || !modalViewRecordDetails.open) return null;
return Array.isArray(props.sampleRecords[modalViewRecordDetails.recordIdx].calculatedValue.value)
? JSON.stringify(props.sampleRecords[modalViewRecordDetails.recordIdx].calculatedValue.value)
: String(props.sampleRecords[modalViewRecordDetails.recordIdx].calculatedValue.value);
}, [props.sampleRecords, modalViewRecordDetails.recordIdx, modalViewRecordDetails.open]);

return (<>
{modalViewRecordDetails.open && modalViewRecordDetails.record && props.sampleRecords && <>
<Modal modalName={ModalEnum.VIEW_RECORD_DETAILS} className="md:max-w-5xl">
Expand All @@ -23,13 +30,9 @@ export default function ViewRecordDetailsModal(props: ViewRecordDetailsModalProp
record={modalViewRecordDetails.record} />
<div className="text-sm leading-5 text-left text-gray-900 font-medium">Calculated value</div>
<div className="text-sm leading-5 text-left text-gray-500 font-normal whitespace-pre-line">
{props.currentAttribute.dataType != DataTypeEnum.EMBEDDING_LIST ? <span>
{props.sampleRecords[modalViewRecordDetails.recordIdx].calculatedValue.value}
</span> : <div className="flex flex-col gap-y-2 divide-y">
{props.sampleRecords[modalViewRecordDetails.recordIdx].calculatedValue.value.map((item: any) => <span key={item} className="mt-1">
{item}
</span>)}
</div>}
<div className="flex flex-col gap-y-2 divide-y">
{displayValue}
</div>
</div>
</div>
</Modal>
Expand Down
20 changes: 11 additions & 9 deletions src/components/projects/projectId/data-browser/DataBrowser.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,24 @@ export default function DataBrowser() {
const activeSlice = useSelector(selectActiveSlice);

const [searchRequest, setSearchRequest] = useState(SEARCH_REQUEST);
const [clearRequest, setClearRequest] = useState(false);

useEffect(() => {
if (!projectId) return;
if (!projectId || !attributes) return;
if (!users || !user) return;
refetchDataSlicesAndProcess();
refetchAttributesAndProcess();
refetchLabelingTasksAndProcess();
refetchEmbeddingsAndPostProcess();
refetchUniqueValuesAndProcess();
}, [projectId, users, user]);

useEffect(() => {
if (!projectId || !attributes) return;
getUniqueValuesByAttributes(projectId, (res) => {
dispatch(setUniqueValuesDict(postProcessUniqueValues(res, attributes)));
});
}, [projectId, attributes]);

useEffect(() => {
if (!projectId || !labelingTasks || !recordList) return;
refetchRecordCommentsAndProcess(recordList);
Expand Down Expand Up @@ -140,14 +147,9 @@ export default function DataBrowser() {
setSearchRequest({ offset: searchRequest.offset + searchRequest.limit, limit: searchRequest.limit });
}

function refetchUniqueValuesAndProcess() {
getUniqueValuesByAttributes(projectId, (res) => {
dispatch(setUniqueValuesDict(postProcessUniqueValues(res, attributes)));
});
}

const setSearchRequestToInit = useCallback(() => {
setSearchRequest(SEARCH_REQUEST);
setClearRequest(true);
}, []);

const handleWebsocketNotification = useCallback((msgParts: string[]) => {
Expand All @@ -171,7 +173,7 @@ export default function DataBrowser() {

return (<>
{projectId && <div className="flex flex-row h-full">
<DataBrowserSidebar />
<DataBrowserSidebar clearRequest={clearRequest} />
<DataBrowserRecords refetchNextRecords={getNextRecords} clearSearchRequest={setSearchRequestToInit} />
</div>}
</>)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { openModal } from '@/src/reduxStore/states/modal';
import { selectActiveSearchParams, selectActiveSlice, selectAdditionalData, selectRecords, selectSimilaritySearch, setActiveDataSlice, setActiveSearchParams, setIsTextHighlightNeeded, setRecordsInDisplay, setTextHighlight, updateAdditionalDataState } from '@/src/reduxStore/states/pages/data-browser';
import { selectActiveSearchParams, selectActiveSlice, selectAdditionalData, selectRecords, selectSimilaritySearch, setActiveDataSlice, setActiveSearchParams, setFullSearchStore, setIsTextHighlightNeeded, setRecordsInDisplay, setTextHighlight, updateAdditionalDataState } from '@/src/reduxStore/states/pages/data-browser';
import style from '@/src/styles/components/projects/projectId/data-browser.module.css';
import { ModalEnum } from '@/src/types/shared/modal';
import { TOOLTIPS_DICT } from '@/src/util/tooltip-constants';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { selectAllUsers } from '@/src/reduxStore/states/general';
import { setModalStates } from '@/src/reduxStore/states/modal';
import { selectActiveSlice, selectAdditionalData, selectDataSlicesAll, setActiveDataSlice, setActiveSearchParams, setFullSearchStore, setIsTextHighlightNeeded, setRecordsInDisplay, setTextHighlight, updateAdditionalDataState } from '@/src/reduxStore/states/pages/data-browser';
import { selectActiveSlice, selectAdditionalData, selectDataSlicesAll, setActiveDataSlice, setActiveSearchParams, setFullSearchStore, setIsTextHighlightNeeded, setRecordsInDisplay, setTextHighlight, setUniqueValuesDict, updateAdditionalDataState } from '@/src/reduxStore/states/pages/data-browser';
import { selectProjectId } from '@/src/reduxStore/states/project';
import style from '@/src/styles/components/projects/projectId/data-browser.module.css';
import { DataSlice } from '@/src/types/components/projects/projectId/data-browser/data-browser';
import { DataBrowserSidebarProps, DataSlice } from '@/src/types/components/projects/projectId/data-browser/data-browser';
import { ModalEnum } from '@/src/types/shared/modal';
import { updateSliceInfoHelper } from '@/src/util/components/projects/projectId/data-browser/data-browser-helper';
import { Slice } from '@/submodules/javascript-functions/enums/enums';
Expand All @@ -17,7 +17,7 @@ import DataSliceInfoModal from './modals/DataSliceInfoModal';
import MultilineTooltip from '@/src/components/shared/multilines-tooltip/MultilineTooltip';
import { MemoIconAlertTriangle, MemoIconInfoCircle, MemoIconLayoutSidebar, MemoIconTrash } from '@/submodules/react-components/components/kern-icons/icons';

export default function DataBrowserSidebar() {
export default function DataBrowserSidebar(props: DataBrowserSidebarProps) {
const dispatch = useDispatch();

const projectId = useSelector(selectProjectId);
Expand Down Expand Up @@ -130,7 +130,7 @@ export default function DataBrowserSidebar() {
</div>
<span className="text-sm text-gray-400">You can filter and order all your data in the browser according to your needs. Selected filter criteria can be saved and used later on.</span>

<SearchGroups />
<SearchGroups clearRequest={props.clearRequest} />
</div>}
</div>
<DeleteSliceModal />
Expand Down
15 changes: 14 additions & 1 deletion src/components/projects/projectId/data-browser/RecordList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ import SimilaritySearchModal from "./modals/SimilaritySeachModal";
import RecordCommentsModal from "./modals/RecordCommentsModal";
import ButtonAsText from "@/submodules/react-components/components/kern-button/ButtonAsText";
import { MemoIconAngle, MemoIconArrowRight, MemoIconEdit, MemoIconNotes } from "@/submodules/react-components/components/kern-icons/icons";
import { useEffect, useMemo } from "react";
import { selectAllProjects, selectProject, setAllProjects } from "@/src/reduxStore/states/project";
import { getAllProjects } from "@/src/services/base/project";

export default function RecordList(props: RecordListProps) {
const dispatch = useDispatch();
Expand All @@ -25,6 +28,16 @@ export default function RecordList(props: RecordListProps) {
const embeddings = useSelector(selectEmbeddings);
const recordComments = useSelector(selectRecordComments);
const attributes = useSelector(selectVisibleAttributesDataBrowser);
const project = useSelector(selectProject);
const allProjects = useSelector(selectAllProjects);

useEffect(() => {
getAllProjects((projects) => dispatch(setAllProjects(projects)));
}, []);

const isIntegrationProject = useMemo(() => {
return allProjects && allProjects.find(p => p.id === project.id)?.isIntegrationProject;
}, [allProjects, project.id]);

return (<>
{recordList && recordList.map((record, index) => (<div key={record.id} className="bg-white overflow-hidden shadow rounded-lg border mb-4 pb-4 relative">
Expand Down Expand Up @@ -71,7 +84,7 @@ export default function RecordList(props: RecordListProps) {
</div>
</div>
</div>
{user?.role == UserRole.ENGINEER && <div className="p-2 cursor-pointer absolute right-2 top-2">
{(user?.role == UserRole.ENGINEER && !isIntegrationProject) && <div className="p-2 cursor-pointer absolute right-2 top-2">
<Tooltip content={TOOLTIPS_DICT.DATA_BROWSER.EDIT_RECORD} color="invert">
<MemoIconEdit className="h-4 w-4" onClick={() => props.editRecord(index)} />
</Tooltip></div>}
Expand Down
24 changes: 16 additions & 8 deletions src/components/projects/projectId/data-browser/SearchGroups.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,12 @@ import { getRecordsByStaticSlice, searchRecordsExtended } from "@/src/services/b
import { staticDataSlicesCurrentCount } from "@/src/services/base/dataSlices";
import KernButton from "@/submodules/react-components/components/kern-button/KernButton";
import { MemoIconArrowDown, MemoIconArrowsRandom, MemoIconFilterOff, MemoIconPlus, MemoIconPointerOff, MemoIconTrash } from "@/submodules/react-components/components/kern-icons/icons";
import { SearchGroupsProps } from "@/src/types/components/projects/projectId/data-browser/data-browser";

const GROUP_SORT_ORDER = 0;
let GLOBAL_SEARCH_GROUP_COUNT = 0;

export default function SearchGroups() {
export default function SearchGroups(props: SearchGroupsProps) {
const dispatch = useDispatch();

const projectId = useSelector(selectProjectId);
Expand Down Expand Up @@ -96,7 +97,7 @@ export default function SearchGroups() {
});
setBackgroundColors(colors);
setAttributeSortOrder(attributesSort);
}, [attributes]);
}, [attributes, props.clearRequest]);

useEffect(() => {
if (!attributesSortOrder || !searchGroupsStore) return;
Expand Down Expand Up @@ -336,7 +337,14 @@ export default function SearchGroups() {
const attributeName = formControlsIdx['name'];
attributeType = getAttributeType(attributesSortOrder, attributeName);
}
if (attributeType !== DataTypeEnum.BOOLEAN) {
if (attributeType == DataTypeEnum.TEXT_LIST) {
operatorsCopy.push({
value: SearchOperator.CONTAINS.split("_").join(" "),
});
tooltipsCopy.push(getSearchOperatorTooltip(SearchOperator.CONTAINS));
formControlsIdx['operator'] = SearchOperator.CONTAINS;

} else if (attributeType !== DataTypeEnum.BOOLEAN) {
for (let t of Object.values(SearchOperator)) {
operatorsCopy.push({
value: t.split("_").join(" "),
Expand Down Expand Up @@ -612,17 +620,17 @@ export default function SearchGroups() {
<div className="flex-grow mr-2.5 flex flex-col mt-2 ">
<div className="flex-grow flex flex-row flex-wrap gap-1">
<div style={{ width: groupItem.operator != '' ? '49%' : '100%' }}>
<KernDropdown options={attributesSortOrder} buttonName={groupItem.name} backgroundColors={backgroundColors}
selectedOption={(option: any) => selectValueDropdown(option.name, index, 'name', group.key)} fontClass="font-dmMono" buttonClasses="text-xs" />
{attributesSortOrder && <KernDropdown options={attributesSortOrder} buttonName={groupItem.name} backgroundColors={backgroundColors}
selectedOption={(option: any) => selectValueDropdown(option.name, index, 'name', group.key)} fontClass="font-dmMono" buttonClasses="text-xs" />}
</div>
<div style={{ width: '49%' }}>
{groupItem.operator != '' &&
{(groupItem.operator != '' && operatorsDropdown) &&
<KernDropdown options={operatorsDropdown} buttonName={groupItem.operator} tooltipsArray={tooltipsArray} tooltipArrayPlacement="right" buttonClasses="text-xs"
selectedOption={(option: any) => selectValueDropdown(option.value, index, 'operator', group.key)} fontClass="font-dmMono" />
}
</div>
</div>
{uniqueValuesDict[groupItem['name']] && groupItem['operator'] != '' && groupItem['operator'] != 'BETWEEN' && groupItem['operator'] != 'IN' && groupItem['operator'] != 'IN WC' ? (
{(uniqueValuesDict && uniqueValuesDict[groupItem['name']] && groupItem['operator'] != '' && groupItem['operator'] != 'BETWEEN' && groupItem['operator'] != 'IN' && groupItem['operator'] != 'IN WC' || saveAttributeType == DataTypeEnum.TEXT_LIST) ? (
<div className="my-2">
<KernDropdown options={uniqueValuesDict[groupItem['name']]} buttonName={groupItem['searchValue'] ? groupItem['searchValue'] : 'Select value'}
selectedOption={(option: any) => selectValueDropdown(option, index, 'searchValue', group.key)} fontClass="font-dmMono" />
Expand All @@ -641,7 +649,7 @@ export default function SearchGroups() {
</div>
)}

{(groupItem['operator'] == "BEGINS WITH" || groupItem['operator'] == "ENDS WITH" || groupItem['operator'] == SearchOperator.CONTAINS || groupItem['operator'] == "IN WC") && (saveAttributeType != DataTypeEnum.INTEGER && saveAttributeType != DataTypeEnum.FLOAT) &&
{(groupItem['operator'] == "BEGINS WITH" || groupItem['operator'] == "ENDS WITH" || groupItem['operator'] == SearchOperator.CONTAINS || groupItem['operator'] == "IN WC") && (saveAttributeType != DataTypeEnum.INTEGER && saveAttributeType != DataTypeEnum.FLOAT && saveAttributeType != DataTypeEnum.TEXT_LIST) &&
<label htmlFor="caseSensitive" className="text-xs text-gray-500 cursor-pointer flex items-center pb-2">
<input name="caseSensitive" className="mr-1 cursor-pointer" id="caseSensitive"
onChange={(e: any) => selectValueDropdown(e.target.checked, index, 'caseSensitive', group.key)} type="checkbox" />Case sensitive</label>}
Expand Down
Loading