Skip to content

Added warning message for integration projects #74

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

Merged
merged 18 commits into from
Jul 4, 2025
Merged
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
3 changes: 3 additions & 0 deletions src/components/projects/ProjectCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ export default function ProjectCard(props: ProjectCardProps) {
<span className="text-sm text-gray-900 ">{props.project.time}</span>
</>}
</div>}
{props.project.is_integration_project && <div className="absolute bottom-0 left-2/4 flex flex-row flex-nowrap gap-x-1 bg-gray-100 px-1 rounded-br rounded-bl" style={{ 'transform': 'translate(-50%' }}>
<span className="text-sm text-red-500">This is an integration project, please do not delete it unless the integration is deleted</span>
</div>}
{(isAdmin && props.project.status !== ProjectStatus.INIT_SAMPLE_PROJECT) &&
<div className="absolute top-0 left-0 cursor-pointer" onClick={adminOpenOrDeleteProjectFunc}>
<Tooltip content={TOOLTIPS_DICT.PROJECTS.QUICK_DELETE} color="invert" offset={2} placement="right">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Statuses from "@/src/components/shared/statuses/Statuses";
import { selectAllLookupLists, setAllLookupLists } from "@/src/reduxStore/states/pages/lookup-lists";
import { selectAttributes, selectVisibleAttributeAC, setAllAttributes, setLabelingTasksAll, updateAttributeById } from "@/src/reduxStore/states/pages/settings";
import { selectAttributes, selectVisibleAttributeAC, selectVisibleAttributesWithoutPermissions, setAllAttributes, setLabelingTasksAll, updateAttributeById } from "@/src/reduxStore/states/pages/settings";
import { selectProjectId } from "@/src/reduxStore/states/project"
import { Attribute, AttributeState, AttributeVisibility, AttributeWithOnClick, LLMConfig } from "@/src/types/components/projects/projectId/settings/data-schema";
import { DataTypeEnum } from "@/src/types/shared/general";
Expand Down Expand Up @@ -52,7 +52,7 @@ export default function AttributeCalculation() {

const projectId = useSelector(selectProjectId);
const attributes = useSelector(selectAttributes);
const usableAttributes = useSelector(selectVisibleAttributeAC)
const usableAttributes = useSelector(selectVisibleAttributesWithoutPermissions);
const lookupLists = useSelector(selectAllLookupLists);
const allUsers = useSelector(selectAllUsers);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,12 @@ export default function ExecutionContainer(props: ExecutionContainerProps) {

const sampleRecordsFinal = useMemo(() => {
if (sampleRecords && sampleRecords.calculatedAttributesDisplay) {
return sampleRecords.calculatedAttributesDisplay.map((record: any) => {
return sampleRecords.calculatedAttributesDisplay.map((record: any, index) => {
const calculatedValue = currentAttributesRef.current.dataType != DataTypeEnum.EMBEDDING_LIST ? record : { id: record.id, value: JSON.parse(record.value) }
return {
...record,
onClick: viewRecordDetails(record.id)
onClick: viewRecordDetails(index),
calculatedValue: calculatedValue
}
}
);
Expand Down Expand Up @@ -130,7 +132,7 @@ export default function ExecutionContainer(props: ExecutionContainerProps) {
<div className="inline-block min-w-full align-middle">
<div className="overflow-hidden shadow ring-1 ring-black ring-opacity-5 md:rounded-lg">
<div className="min-w-full border divide-y divide-gray-300">
{sampleRecordsFinal.map((record: any, index: number) => (
{sampleRecordsFinal.map((record: any) => (
<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">
Expand All @@ -151,7 +153,7 @@ export default function ExecutionContainer(props: ExecutionContainerProps) {
</div>
</div >}

<ViewRecordDetailsModal currentAttribute={props.currentAttribute} sampleRecords={sampleRecords} />
<ViewRecordDetailsModal currentAttribute={props.currentAttribute} sampleRecords={sampleRecordsFinal} />
<ConfirmExecutionModal currentAttributeId={props.currentAttribute.id} />
</div >)
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ export default function ViewRecordDetailsModal(props: ViewRecordDetailsModalProp
<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.calculatedAttributes[modalViewRecordDetails.recordIdx]}
{props.sampleRecords[modalViewRecordDetails.recordIdx].calculatedValue.value}
</span> : <div className="flex flex-col gap-y-2 divide-y">
{props.sampleRecords.calculatedAttributesListDisplay[modalViewRecordDetails.recordIdx].map((item: any) => <span key={item.id} className="mt-1">
{props.sampleRecords.calculatedAttributesList[modalViewRecordDetails.recordIdx]}
{props.sampleRecords[modalViewRecordDetails.recordIdx].calculatedValue.value.map((item: any) => <span key={item} className="mt-1">
{item}
</span>)}
</div>}
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ export default function SearchGroups() {
});
colors.push('gray');
visibleAttributes.forEach((att) => {
if (att.dataType == DataTypeEnum.PERMISSION) return;
attributesSort.push({
name: att.name,
key: att.id,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { postProcessCurrentHeuristic, postProcessLastTaskLogs } from "@/src/util
import { Tooltip } from "@nextui-org/react";
import { TOOLTIPS_DICT } from "@/src/util/tooltip-constants";
import { postProcessLabelingTasksSchema } from "@/src/util/components/projects/projectId/settings/labeling-tasks-helper";
import { selectVisibleAttributesHeuristics, selectLabelingTasksAll, setLabelingTasksAll } from "@/src/reduxStore/states/pages/settings";
import { selectVisibleAttributesHeuristics, selectLabelingTasksAll, setLabelingTasksAll, selectVisibleAttributesWithoutPermissions } from "@/src/reduxStore/states/pages/settings";
import HeuristicsEditor from "../shared/HeuristicsEditor";
import DangerZone from "@/src/components/shared/danger-zone/DangerZone";
import HeuristicRunButtons from "../shared/HeuristicRunButtons";
Expand Down Expand Up @@ -46,7 +46,7 @@ export default function LabelingFunction() {
const projectId = useSelector(selectProjectId);
const currentHeuristic = useSelector(selectHeuristic);
const labelingTasks = useSelector(selectLabelingTasksAll);
const attributes = useSelector(selectVisibleAttributesHeuristics);
const attributes = useSelector(selectVisibleAttributesWithoutPermissions);
const allUsers = useSelector(selectAllUsers);

const [lastTaskLogs, setLastTaskLogs] = useState<string[]>([]);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Statuses from "@/src/components/shared/statuses/Statuses";
import { selectHeuristic, setActiveHeuristics, updateHeuristicsState } from "@/src/reduxStore/states/pages/heuristics";
import { selectAllLookupLists, setAllLookupLists } from "@/src/reduxStore/states/pages/lookup-lists";
import { selectVisibleAttributesHeuristics, setAllAttributes } from "@/src/reduxStore/states/pages/settings";
import { selectVisibleAttributesHeuristics, selectVisibleAttributesWithoutPermissions, setAllAttributes } from "@/src/reduxStore/states/pages/settings";
import { selectProjectId } from "@/src/reduxStore/states/project"
import { HeuristicsProperty } from "@/src/types/components/projects/projectId/heuristics/heuristicId/heuristics-details";
import { Attribute } from "@/src/types/components/projects/projectId/settings/data-schema";
Expand All @@ -26,7 +26,7 @@ export default function HeuristicsLayout(props: any) {

const projectId = useSelector(selectProjectId);
const currentHeuristic = useSelector(selectHeuristic);
const usableAttributes = useSelector(selectVisibleAttributesHeuristics);
const usableAttributes = useSelector(selectVisibleAttributesWithoutPermissions);
const lookupLists = useSelector(selectAllLookupLists);

const [isHeaderNormal, setIsHeaderNormal] = useState(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { useCallback, useEffect, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import QuestionHistory from "./QuestionHistory";
import { MemoIconPlus, MemoIconWand } from "@/submodules/react-components/components/kern-icons/icons";
import { postProcessUpdateAndSortRecords } from "@/submodules/javascript-functions/post-process-functions";

const ACCEPT_BUTTON = { buttonCaption: 'Create', useButton: true };
const SEARCH_REQUEST = { offset: 0, limit: 20 };
Expand Down Expand Up @@ -129,16 +130,7 @@ export default function CreateEvaluationSetModal(props: CreateEvaluationSetsModa
}

function updateAndSortRecordList(newRecords = []) {
setRecordList((prev) => {
const merged = [...prev, ...newRecords];
const uniqueRecords = Array.from(
new Map(merged.map((item) => [item.data?.running_id, item])).values()
);
uniqueRecords.sort(
(a, b) => (a.data?.running_id || 0) - (b.data?.running_id || 0)
);
return uniqueRecords;
});
setRecordList((prev) => postProcessUpdateAndSortRecords(prev, newRecords));
}

function resetState() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { toPythonFunctionName } from "@/submodules/javascript-functions/python-f
import KernDropdown from "@/submodules/react-components/components/KernDropdown";
import { Tooltip } from "@nextui-org/react";
import { useRouter } from "next/router";
import { useCallback, useEffect, useState } from "react";
import { useCallback, useEffect, useMemo, useState } from "react";
import { useDispatch, useSelector } from "react-redux";

const ACCEPT_BUTTON = { buttonCaption: "Accept", useButton: true, disabled: true }
Expand Down Expand Up @@ -58,6 +58,10 @@ export default function CreateNewAttributeModal() {
setDuplicateNameExists(checkName);
}

const filteredDataTypes = useMemo(() => {
return DATA_TYPES.filter(type => type.value !== 'PERMISSION');
}, []);

return (<Modal modalName={ModalEnum.CREATE_NEW_ATTRIBUTE} acceptButton={acceptButton}>
<div className="flex flex-grow justify-center text-lg leading-6 text-gray-900 font-medium">
Add new attribute </div>
Expand All @@ -73,7 +77,7 @@ export default function CreateNewAttributeModal() {
<Tooltip content={TOOLTIPS_DICT.PROJECT_SETTINGS.SELECT_ATTRIBUTE_TYPE} color="invert" placement="right">
<span className="cursor-help card-title mb-0 label-text font-normal"><span className="underline filtersUnderline">Attribute type</span></span>
</Tooltip>
<KernDropdown buttonName={attributeType ? attributeType.name : 'Select type'} options={DATA_TYPES} selectedOption={(option: any) => setAttributeType(option)} />
<KernDropdown buttonName={attributeType ? attributeType.name : 'Select type'} options={filteredDataTypes} selectedOption={(option: any) => setAttributeType(option)} />
</div>
{duplicateNameExists && <div className="text-red-700 text-xs mt-2">Attribute name exists</div>}
{attributeType.name == 'Embedding List' && <div className="border border-gray-300 text-xs text-gray-500 p-2.5 rounded-lg text-justify mt-2 max-w-2xl">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ export default function ProjectMetaData() {
<div className="text-gray-900 text-lg leading-6 font-medium">Danger zone</div>
<div className="text-sm leading-5 font-normal mt-2 text-gray-500 inline-block">This action can not be reversed.
Are you sure you want to delete this project?</div>
{project.is_integration_project && <div className="text-sm text-red-500 italic">
This is an integration project, please do not delete it unless the integration is deleted
</div>}
<div className="form-control">
<div className="flex space-x-2 items-center">
<input className="h-9 w-full text-sm border-gray-300 rounded-md placeholder-italic border text-gray-900 pl-4 placeholder:text-gray-400 focus:outline-none focus:ring-2 focus:ring-gray-300 focus:ring-offset-2 focus:ring-offset-gray-100"
Expand Down
8 changes: 4 additions & 4 deletions src/components/shared/record-display/RecordDisplay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ import { selectAttributesDict } from "@/src/reduxStore/states/pages/settings";
import { LineBreaksType } from "@/src/types/components/projects/projectId/data-browser/data-browser";
import { Attribute } from "@/src/types/components/projects/projectId/settings/data-schema";
import { DataTypeEnum } from "@/src/types/shared/general";
import { postProcessAttributes, postProcessRecord } from "@/src/util/shared/record-display-helper";
import { useEffect, useState } from "react";
import { useSelector } from "react-redux";
import Highlight from "../highlight/Highlight";
import { MemoIconAlertCircle } from "@/submodules/react-components/components/kern-icons/icons";
import { postProcessAttributes, postProcessRecord } from "@/submodules/javascript-functions/post-process-functions";

export function RecordDisplay(props: any) {
const attributesDict = useSelector(selectAttributesDict);
Expand All @@ -33,16 +33,16 @@ export function RecordDisplay(props: any) {
</div>
</div>
{attributesDict[attribute.id] && <div className="text-gray-800 text-sm mb-4 overflow-anywhere flex text-left">
{attribute.dataType == DataTypeEnum.EMBEDDING_LIST ? (<div className="flex flex-col gap-y-1 divide-y">
{preparedRecord.data[attributesDict[attribute.key].name] && preparedRecord.data[attributesDict[attribute.key].name].map((item, indexJ) => (<div key={indexJ} className="pt-1">
{attribute.dataType === DataTypeEnum.EMBEDDING_LIST || attribute.dataType === DataTypeEnum.PERMISSION ? (<div className="flex flex-col gap-y-1 divide-y">
{preparedRecord.data[attributesDict[attribute.key].name] ? preparedRecord.data[attributesDict[attribute.key].name].map((item, indexJ) => (<div key={indexJ} className="pt-1">
{(configuration.highlightText && isTextHighlightNeeded[attribute.key]) ? (<Highlight text={item.toString()}
additionalClasses={[configuration.lineBreaks == LineBreaksType.NORMAL ? '' : (configuration.lineBreaks == LineBreaksType.IS_PRE_WRAP ? 'whitespace-pre-wrap' : 'whitespace-pre-line')]}
searchForExtended={textHighlight[attribute.id]} />) : (
<span className={configuration && configuration.lineBreaks != LineBreaksType.NORMAL ? (configuration.lineBreaks == LineBreaksType.IS_PRE_WRAP ? 'whitespace-pre-wrap' : 'whitespace-pre-line') : ''}>
{item != null && item !== '' ? item : <NotPresentInRecord />}
</span>
)}
</div>))}
</div>)) : <NotPresentInRecord />}
</div>) : (<>
{(configuration.highlightText && isTextHighlightNeeded[attribute.key]) ? (<Highlight text={preparedRecord.data[attributesDict[attribute.key].name]?.toString()}
additionalClasses={[configuration.lineBreaks == LineBreaksType.NORMAL ? '' : (configuration.lineBreaks == LineBreaksType.IS_PRE_WRAP ? 'whitespace-pre-wrap' : 'whitespace-pre-line')]}
Expand Down
10 changes: 8 additions & 2 deletions src/reduxStore/StoreManagerComponent.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useEffect, useState } from "react";
import { useRouter } from "next/router";
import { useDispatch, useSelector } from "react-redux";
import { selectIsAdmin, selectOrganization, setAllUsers, setIsAdmin, setOrganization, setRouteColor, setUser } from "./states/general";
import { selectIsAdmin, selectOrganization, selectUser, setAllUsers, setIsAdmin, setOrganization, setRouteColor, setUser } from "./states/general";
import { getUserAvatarUri } from "@/submodules/javascript-functions/general";
import { setActiveProject } from "./states/project";
import { WebSocketsService } from "../../submodules/react-components/hooks/web-socket/WebSocketsService";
Expand All @@ -18,12 +18,14 @@ import { getProjectByProjectId } from "../services/base/project";
import { getIsAdmin, getVersionOverview } from "../services/base/misc";
import { getUserInfo, getOrganization, getOrganizationUsers } from "../services/base/organization";
import { getAllTokenizerOptions, getEmbeddingPlatforms, getRecommendedEncoders } from "../services/base/embedding";
import { UserRole } from "../types/shared/sidebar";

export function GlobalStoreDataComponent(props: React.PropsWithChildren) {
const router = useRouter();
const dispatch = useDispatch();
const isAdmin = useSelector(selectIsAdmin);
const organization = useSelector(selectOrganization);
const userRole = useSelector(selectUser)?.role;

const [dataLoaded, setDataLoaded] = useState(false);

Expand All @@ -33,6 +35,10 @@ export function GlobalStoreDataComponent(props: React.PropsWithChildren) {
});

getUserInfo((res) => {
if (res.role == UserRole.ANNOTATOR || res.role == UserRole.EXPERT) {
window.location.href = '/cognition';
return;
}
const userInfo = { ...res };
userInfo.avatarUri = getUserAvatarUri(res);
dispatch(setUser(userInfo));
Expand Down Expand Up @@ -106,6 +112,6 @@ export function GlobalStoreDataComponent(props: React.PropsWithChildren) {
})
}, [ConfigManager.isInit()]);

if (!dataLoaded) return <></>;
if (!dataLoaded || userRole !== UserRole.ENGINEER) return <></>;
return <div>{props.children}</div>;
}
1 change: 1 addition & 0 deletions src/reduxStore/states/pages/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ export const selectVisibleAttributesDataBrowser = createSelector([selectUsableAt
export const selectVisibleAttributeAC = createSelector([selectUsableAttributesFiltered], (a): any => a ? a.filter((a) => a.visibility != AttributeVisibility.HIDE) : null);
export const selectVisibleAttributesHeuristics = createSelector([selectUsableAttributesFiltered], (a): any => a ? a.filter((a) => a.visibility != AttributeVisibility.HIDE) : null);
export const selectOnAttributeEmbeddings = createSelector([selectEmbeddings], (a): any => a ? a.filter((embedding) => embedding.type == EmbeddingType.ON_ATTRIBUTE && embedding.state == Status.FINISHED) : null);
export const selectVisibleAttributesWithoutPermissions = createSelector([selectUsableAttributesFiltered], (a): any => a ? a.filter((a) => a.dataType != DataTypeEnum.PERMISSION) : null);

export const { setAllAttributes, extendAllAttributes, removeFromAllAttributesById, updateAttributeById, setAllEmbeddings, setFilteredEmbeddings, removeFromAllEmbeddingsById, setAllRecommendedEncodersDict, setRecommendedEncodersAll, setLabelingTasksAll, removeFromAllLabelingTasksById, removeLabelFromLabelingTask } = settingsSlice.actions;
export const settingsReducer = settingsSlice.reducer;
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export type SampleRecord = {
calculatedAttributesList: any[];
calculatedAttributesDisplay: any[];
calculatedAttributesListDisplay: any[];
id: number;
};

export type ContainerLogsProps = {
Expand All @@ -31,7 +32,7 @@ export type Record = {

export type ViewRecordDetailsModalProps = {
currentAttribute: Attribute;
sampleRecords: SampleRecord;
sampleRecords: any;
}

export type ConfirmExecutionModalProps = {
Expand Down
1 change: 1 addition & 0 deletions src/types/components/projects/projects-list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export type Project = {
timeStamp: string;
date: string;
time: string
is_integration_project: boolean;
}

export enum ProjectStatus {
Expand Down
Loading