folderId: getConversationRootId()

in apps/chat/src/utils/app/import-export.ts [110:382]


        folderId: getConversationRootId(),
      })),
      prompts: [],
      isError: false,
    };
  }

  if (isExportFormatV3(data)) {
    return {
      history: cleanConversationHistory(data.history),
      folders: [...data.folders],
      version: 5,
      prompts: [],
      isError: false,
    };
  }

  if (isExportFormatV4(data)) {
    return {
      ...data,
      version: 5,
      history: cleanConversationHistory(data.history),
      prompts: data.prompts || [],
      isError: false,
    };
  }

  if (isExportFormatV5(data)) {
    return {
      ...data,
      history: cleanConversationHistory(data.history),
      prompts: data.prompts || [],
      isError: false,
    };
  }

  return {
    version: 5,
    history: [],
    folders: [],
    prompts: [],
    isError: true,
  };
}

export function currentDate() {
  const date = new Date();
  const month = date.getMonth() + 1;
  const day = date.getDate();
  return `${month}-${day}`;
}

type ExportType =
  | 'conversation'
  | 'conversations_history'
  | 'prompt'
  | 'prompts_history';

export const getDownloadFileName = (fileName?: string): string =>
  !fileName ? 'ai_dial' : fileName.toLowerCase().replaceAll(' ', '_');

function downloadChatPromptData(
  data: LatestExportConversationsFormat | Prompt[] | PromptsHistory,
  exportType: ExportType,
  fileName?: string,
) {
  const blob = new Blob([JSON.stringify(data, null, 2)], {
    type: 'application/json',
  });
  const url = URL.createObjectURL(blob);
  const downloadName = getDownloadFileName(fileName);

  triggerDownload(
    url,
    `${downloadName}_chat_${exportType}_${currentDate()}.json`,
  );
}

export function downloadApplicationLogs(data: string, fileName?: string) {
  const exportedFileName = [fileName, 'application_logs', currentDate()]
    .filter(Boolean)
    .join('_');

  const blob = new Blob([data], { type: 'text/plain' });
  const url = URL.createObjectURL(blob);

  triggerDownload(url, exportedFileName);
}

const triggerDownloadConversation = (
  data: LatestExportConversationsFormat,
  appName?: string,
) => {
  downloadChatPromptData(data, 'conversation', appName);
};
const triggerDownloadConversationsHistory = (
  data: LatestExportConversationsFormat,
  appName?: string,
) => {
  downloadChatPromptData(data, 'conversations_history', appName);
};

const triggerDownloadPromptsHistory = (
  data: PromptsHistory,
  appName?: string,
) => {
  downloadChatPromptData(data, 'prompts_history', appName);
};

const triggerDownloadPrompt = (data: PromptsHistory, appName?: string) => {
  downloadChatPromptData(data, 'prompt', appName);
};

export const exportConversation = (
  conversation: Conversation,
  folders: FolderInterface[],
  appName?: string,
) => {
  const data: LatestExportConversationsFormat = {
    version: 5,
    history: [excludePublicationInfo(conversation)],
    folders: folders,
  };

  triggerDownloadConversation(data, appName);
};

interface PrepareConversationsForExport {
  conversations: Conversation[];
  folders: FolderInterface[];
}

export const prepareConversationsForExport = ({
  conversations,
  folders,
}: PrepareConversationsForExport) => {
  const data = {
    version: 5,
    history: conversations?.map(excludePublicationInfo) || [],
    folders: folders || [],
  } as LatestExportConversationsFormat;

  return data;
};

export const exportConversations = (
  conversations: Conversation[],
  folders: FolderInterface[],
  appName?: string,
  version = 5,
) => {
  const data = {
    version,
    history: conversations?.map(excludePublicationInfo) || [],
    folders: folders || [],
  } as LatestExportConversationsFormat;

  triggerDownloadConversationsHistory(data, appName);
};

export const exportPrompts = (
  prompts: Prompt[],
  folders: FolderInterface[],
  appName?: string,
) => {
  const data = {
    prompts: prompts.map(excludePublicationInfo),
    folders,
  };
  triggerDownloadPromptsHistory(data, appName);
};

export const exportPrompt = (
  prompt: Prompt,
  folders: FolderInterface[],
  appName?: string,
) => {
  const promptsToExport: Prompt[] = [excludePublicationInfo(prompt)];

  const data: PromptsHistory = {
    prompts: promptsToExport,
    folders,
  };
  triggerDownloadPrompt(data, appName);
};

export const updateAttachment = ({
  oldAttachment,
  uploadedAttachments,
}: {
  oldAttachment: Attachment;
  uploadedAttachments: UploadedAttachment[];
}) => {
  const oldAttachmentUrl = oldAttachment.url || oldAttachment.reference_url;
  if (!oldAttachmentUrl) {
    return oldAttachment;
  }

  const oldAttachmentDecodedUrl = ApiUtils.decodeApiUrl(oldAttachmentUrl);

  const { name, parentPath } = splitEntityId(oldAttachmentDecodedUrl);

  const oldAttachmentRelativePath = constructPath(parentPath, name);

  const splitByHash = (stringToSplit: string) => {
    const nameArr = stringToSplit.split('#');
    const oldName = nameArr[0];
    const oldHash = nameArr[nameArr.length - 1];

    return {
      oldName,
      oldHash,
    };
  };

  const { oldHash } = splitByHash(name);
  const { oldName: cleanOldAttachmentRelativePath } = splitByHash(
    oldAttachmentRelativePath,
  );

  const newAttachmentFile = uploadedAttachments.find(({ oldRelativePath }) => {
    return oldRelativePath === cleanOldAttachmentRelativePath;
  });

  const newAttachmentUrl =
    (oldAttachment.url || oldAttachment.reference_url) &&
    (newAttachmentFile
      ? constructPath(newAttachmentFile.absolutePath, newAttachmentFile.name)
      : constructPath(getFileRootId(), parentPath, name));

  const encodedNewAttachmentUrl =
    newAttachmentUrl && ApiUtils.encodeApiUrl(newAttachmentUrl);
  const newReferenceUrl =
    oldAttachment.reference_url &&
    encodedNewAttachmentUrl &&
    `${encodedNewAttachmentUrl}#${oldHash}`;

  const newType = oldAttachment.type ?? newAttachmentFile?.contentType;

  const newTitle =
    oldAttachment.type === PLOTLY_CONTENT_TYPE
      ? (oldAttachment.title ?? newAttachmentFile?.name)
      : (newAttachmentFile?.name ?? oldAttachment.title);

  const updatedAttachment: Attachment = {
    ...oldAttachment,
    title: newTitle,
    type: newType,
    url: encodedNewAttachmentUrl,
    reference_url: newReferenceUrl,
  };
  return updatedAttachment;
};

export const getDuplicatedConversations = (
  preparedConversations: Conversation[],
): Observable<{
  newConversations: Conversation[];
  duplicatedConversations: Conversation[];
}> => {
  return ConversationService.getConversations(undefined, true).pipe(
    map((conversationsListing) => {
      const existedImportNamesConversations = preparedConversations.filter(
        (importConv) =>
          !isImportEntityNameOnSameLevelUnique({
            entity: importConv,
            entities: conversationsListing,
          }),
      );

      const nonExistedImportNamesConversations = preparedConversations.filter(
        (importConv) => {
          return isImportEntityNameOnSameLevelUnique({