From 6b37dcd8aed87b016ef87fd4e3412ee607acc180 Mon Sep 17 00:00:00 2001
From: elforjani13 <39470382+elforjani13@users.noreply.github.com>
Date: Tue, 30 Aug 2022 18:48:08 +0200
Subject: [PATCH] feat: add project list field cell
---
.../DataTableCells/ProjectsListFieldCell.tsx | 43 +++++
src/components/DataTableCells/index.tsx | 2 +
.../components/ProjectSuggestField.tsx | 151 ++++++++++++++++++
src/containers/Projects/components/index.ts | 1 +
4 files changed, 197 insertions(+)
create mode 100644 src/components/DataTableCells/ProjectsListFieldCell.tsx
create mode 100644 src/containers/Projects/components/ProjectSuggestField.tsx
diff --git a/src/components/DataTableCells/ProjectsListFieldCell.tsx b/src/components/DataTableCells/ProjectsListFieldCell.tsx
new file mode 100644
index 000000000..1d611c722
--- /dev/null
+++ b/src/components/DataTableCells/ProjectsListFieldCell.tsx
@@ -0,0 +1,43 @@
+import React, { useCallback } from 'react';
+import { FormGroup, Intent, Classes } from '@blueprintjs/core';
+import classNames from 'classnames';
+
+import { CellType } from '@/constants';
+import { ProjectSuggestField } from '@/containers/Projects/components';
+
+/**
+ * projects list field cell.
+ * @returns
+ */
+export function ProjectsListFieldCell({
+ column: { id },
+ row: { index, original },
+ payload: { projects, updateData, errors },
+}) {
+ const handleProjectSelected = useCallback(
+ (project) => {
+ updateData(index, 'project_id', project.id);
+ },
+ [updateData, index],
+ );
+
+ const error = errors?.[index]?.[id];
+ return (
+
+
+
+ );
+}
+
+ProjectsListFieldCell.cellType = CellType.Field;
diff --git a/src/components/DataTableCells/index.tsx b/src/components/DataTableCells/index.tsx
index 84ef9d344..02fb0ebb4 100644
--- a/src/components/DataTableCells/index.tsx
+++ b/src/components/DataTableCells/index.tsx
@@ -10,6 +10,7 @@ import CheckBoxFieldCell from './CheckBoxFieldCell';
import SwitchFieldCell from './SwitchFieldCell';
import TextAreaCell from './TextAreaCell';
import BranchesListFieldCell from './BranchesListFieldCell';
+import { ProjectsListFieldCell } from './ProjectsListFieldCell';
import { TextOverviewTooltipCell } from './TextOverviewTooltipCell';
export {
@@ -26,5 +27,6 @@ export {
SwitchFieldCell,
TextAreaCell,
BranchesListFieldCell,
+ ProjectsListFieldCell,
TextOverviewTooltipCell,
};
diff --git a/src/containers/Projects/components/ProjectSuggestField.tsx b/src/containers/Projects/components/ProjectSuggestField.tsx
new file mode 100644
index 000000000..ede0e53a0
--- /dev/null
+++ b/src/containers/Projects/components/ProjectSuggestField.tsx
@@ -0,0 +1,151 @@
+import React from 'react';
+import styled from 'styled-components';
+import intl from 'react-intl-universal';
+import { Menu, MenuItem } from '@blueprintjs/core';
+import { Suggest } from '@blueprintjs/select';
+import { FormattedMessage as T } from '@/components';
+
+import classNames from 'classnames';
+import { CLASSES } from '@/constants/classes';
+import { firstLettersArgs } from '@/utils';
+
+/**
+ * project suggest field.
+ * @returns
+ */
+export function ProjectSuggestField({
+ projects,
+ initialProjectId,
+ selectedProjectId,
+ defaultSelectText = intl.get('select_project'),
+ popoverFill = false,
+ onProjectSelected,
+ ...suggestProps
+}) {
+ const initialProject = React.useMemo(
+ () => projects.find((b) => b.id === initialProjectId),
+ [initialProjectId, projects],
+ );
+
+ const [selectedProject, setSelectedProject] = React.useState(
+ initialProject || null,
+ );
+
+ React.useEffect(() => {
+ if (typeof selectedProjectId !== 'undefined') {
+ const project = selectedProjectId
+ ? projects.find((a) => a.id === selectedProjectId)
+ : null;
+ setSelectedProject(project);
+ }
+ }, [selectedProjectId, projects, setSelectedProject]);
+
+ /**
+ * @param {*} project
+ * @param {*} param1
+ * @returns {JSX.Element}
+ */
+ const projectsItemRenderer = (project, { handleClick, modifiers, query }) => {
+ return (
+
+ }
+ disabled={modifiers.disabled}
+ key={project.id}
+ text={project.name}
+ onClick={handleClick}
+ />
+
+ );
+ };
+
+ /**
+ *
+ * @param {*} query
+ * @param {*} project
+ * @param {*} _index
+ * @param {*} exactMatch
+ * @returns
+ */
+ const projectsItemPredicate = (query, project, _index, exactMatch) => {
+ const normalizedTitle = project.name.toLowerCase();
+ const normalizedQuery = query.toLowerCase();
+
+ if (exactMatch) {
+ return normalizedTitle === normalizedQuery;
+ } else {
+ return (
+ `${project.name}. ${normalizedTitle}`.indexOf(normalizedQuery) >= 0
+ );
+ }
+ };
+
+ /**
+ *
+ * @param {*} project
+ * @returns
+ */
+ const projectItemSelect = React.useCallback(
+ (project) => {
+ if (project.id) {
+ setSelectedProject({ ...project });
+ onProjectSelected && onProjectSelected(project);
+ }
+ },
+ [setSelectedProject, onProjectSelected],
+ );
+
+ /**
+ *
+ * @param {*} inputVaue
+ * @returns
+ */
+ const projectInputValueRenderer = (inputValue) => {
+ if (inputValue) {
+ return inputValue.name.toString();
+ }
+ return '';
+ };
+
+ return (
+ } />}
+ itemRenderer={projectsItemRenderer}
+ itemPredicate={projectsItemPredicate}
+ onItemSelect={projectItemSelect}
+ selectedItem={selectedProject}
+ inputProps={{ placeholder: defaultSelectText }}
+ resetOnClose={true}
+ fill={true}
+ popoverProps={{ minimal: true, boundary: 'window' }}
+ inputValueRenderer={projectInputValueRenderer}
+ className={classNames(CLASSES.FORM_GROUP_LIST_SELECT, {
+ [CLASSES.SELECT_LIST_FILL_POPOVER]: popoverFill,
+ })}
+ {...suggestProps}
+ />
+ );
+}
+
+const AvatarSelect = ({ text }) => {
+ return {firstLettersArgs(text?.name)};
+};
+
+const MenuContent = styled(Menu)`
+ .bp3-menu {
+ margin: 5px;
+ }
+`;
+
+const AvaterContent = styled.div`
+ display: inline-block;
+ background: #adbcc9;
+ text-align: center;
+ font-weight: 400;
+ color: #fff;
+ height: 25px;
+ width: 25px;
+ line-height: 25px;
+ font-size: 12px;
+`;
diff --git a/src/containers/Projects/components/index.ts b/src/containers/Projects/components/index.ts
index 93edd1b79..5a15d6891 100644
--- a/src/containers/Projects/components/index.ts
+++ b/src/containers/Projects/components/index.ts
@@ -4,3 +4,4 @@ export * from './TaskSelect';
export * from './ProjectsSelect';
export * from './ProjectMultiSelect'
export * from './FInputGroupComponent';
+export * from './ProjectSuggestField'
\ No newline at end of file