feat: add ui skeleton to Task Details while loading
This commit is contained in:
		@@ -1,6 +1,7 @@
 | 
				
			|||||||
import React, { useState } from 'react';
 | 
					import React, { useState } from 'react';
 | 
				
			||||||
import Modal from 'shared/components/Modal';
 | 
					import Modal from 'shared/components/Modal';
 | 
				
			||||||
import TaskDetails from 'shared/components/TaskDetails';
 | 
					import TaskDetails from 'shared/components/TaskDetails';
 | 
				
			||||||
 | 
					import TaskDetailsLoading from 'shared/components/TaskDetails/Loading';
 | 
				
			||||||
import { Popup, usePopup } from 'shared/components/PopupMenu';
 | 
					import { Popup, usePopup } from 'shared/components/PopupMenu';
 | 
				
			||||||
import MemberManager from 'shared/components/MemberManager';
 | 
					import MemberManager from 'shared/components/MemberManager';
 | 
				
			||||||
import { useRouteMatch, useHistory } from 'react-router';
 | 
					import { useRouteMatch, useHistory } from 'react-router';
 | 
				
			||||||
@@ -407,9 +408,7 @@ const Details: React.FC<DetailsProps> = ({
 | 
				
			|||||||
  });
 | 
					  });
 | 
				
			||||||
  const [updateTaskComment] = useUpdateTaskCommentMutation();
 | 
					  const [updateTaskComment] = useUpdateTaskCommentMutation();
 | 
				
			||||||
  const [editableComment, setEditableComment] = useState<null | string>(null);
 | 
					  const [editableComment, setEditableComment] = useState<null | string>(null);
 | 
				
			||||||
  if (!data) {
 | 
					  const isLoading = true;
 | 
				
			||||||
    return null;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <>
 | 
					    <>
 | 
				
			||||||
      <Modal
 | 
					      <Modal
 | 
				
			||||||
@@ -418,7 +417,7 @@ const Details: React.FC<DetailsProps> = ({
 | 
				
			|||||||
          history.push(projectURL);
 | 
					          history.push(projectURL);
 | 
				
			||||||
        }}
 | 
					        }}
 | 
				
			||||||
        renderContent={() => {
 | 
					        renderContent={() => {
 | 
				
			||||||
          return (
 | 
					          return data ? (
 | 
				
			||||||
            <TaskDetails
 | 
					            <TaskDetails
 | 
				
			||||||
              onCancelCommentEdit={() => setEditableComment(null)}
 | 
					              onCancelCommentEdit={() => setEditableComment(null)}
 | 
				
			||||||
              onUpdateComment={(commentID, message) => {
 | 
					              onUpdateComment={(commentID, message) => {
 | 
				
			||||||
@@ -647,6 +646,8 @@ const Details: React.FC<DetailsProps> = ({
 | 
				
			|||||||
                );
 | 
					                );
 | 
				
			||||||
              }}
 | 
					              }}
 | 
				
			||||||
            />
 | 
					            />
 | 
				
			||||||
 | 
					          ) : (
 | 
				
			||||||
 | 
					            <TaskDetailsLoading />
 | 
				
			||||||
          );
 | 
					          );
 | 
				
			||||||
        }}
 | 
					        }}
 | 
				
			||||||
      />
 | 
					      />
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,9 @@
 | 
				
			|||||||
import React, { useRef, useState, useEffect } from 'react';
 | 
					import React, { useRef, useState, useEffect } from 'react';
 | 
				
			||||||
 | 
					import { usePopup } from 'shared/components/PopupMenu';
 | 
				
			||||||
 | 
					import useOnOutsideClick from 'shared/hooks/onOutsideClick';
 | 
				
			||||||
 | 
					import { At, Paperclip, Smile } from 'shared/icons';
 | 
				
			||||||
 | 
					import { Picker, Emoji } from 'emoji-mart';
 | 
				
			||||||
 | 
					import Task from 'shared/icons/Task';
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
  CommentTextArea,
 | 
					  CommentTextArea,
 | 
				
			||||||
  CommentEditorContainer,
 | 
					  CommentEditorContainer,
 | 
				
			||||||
@@ -8,11 +13,6 @@ import {
 | 
				
			|||||||
  CommentProfile,
 | 
					  CommentProfile,
 | 
				
			||||||
  CommentInnerWrapper,
 | 
					  CommentInnerWrapper,
 | 
				
			||||||
} from './Styles';
 | 
					} from './Styles';
 | 
				
			||||||
import { usePopup } from 'shared/components/PopupMenu';
 | 
					 | 
				
			||||||
import useOnOutsideClick from 'shared/hooks/onOutsideClick';
 | 
					 | 
				
			||||||
import { At, Paperclip, Smile } from 'shared/icons';
 | 
					 | 
				
			||||||
import { Picker, Emoji } from 'emoji-mart';
 | 
					 | 
				
			||||||
import Task from 'shared/icons/Task';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
type CommentCreatorProps = {
 | 
					type CommentCreatorProps = {
 | 
				
			||||||
  me?: TaskUser;
 | 
					  me?: TaskUser;
 | 
				
			||||||
@@ -21,10 +21,12 @@ type CommentCreatorProps = {
 | 
				
			|||||||
  message?: string | null;
 | 
					  message?: string | null;
 | 
				
			||||||
  onCreateComment: (message: string) => void;
 | 
					  onCreateComment: (message: string) => void;
 | 
				
			||||||
  onCancelEdit?: () => void;
 | 
					  onCancelEdit?: () => void;
 | 
				
			||||||
 | 
					  disabled?: boolean;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const CommentCreator: React.FC<CommentCreatorProps> = ({
 | 
					const CommentCreator: React.FC<CommentCreatorProps> = ({
 | 
				
			||||||
  me,
 | 
					  me,
 | 
				
			||||||
 | 
					  disabled = false,
 | 
				
			||||||
  message,
 | 
					  message,
 | 
				
			||||||
  onMemberProfile,
 | 
					  onMemberProfile,
 | 
				
			||||||
  onCreateComment,
 | 
					  onCreateComment,
 | 
				
			||||||
@@ -70,6 +72,7 @@ const CommentCreator: React.FC<CommentCreatorProps> = ({
 | 
				
			|||||||
          showCommentActions={showCommentActions}
 | 
					          showCommentActions={showCommentActions}
 | 
				
			||||||
          placeholder="Write a comment..."
 | 
					          placeholder="Write a comment..."
 | 
				
			||||||
          ref={$comment}
 | 
					          ref={$comment}
 | 
				
			||||||
 | 
					          disabled={disabled}
 | 
				
			||||||
          value={comment}
 | 
					          value={comment}
 | 
				
			||||||
          onChange={e => setComment(e.currentTarget.value)}
 | 
					          onChange={e => setComment(e.currentTarget.value)}
 | 
				
			||||||
          onFocus={() => {
 | 
					          onFocus={() => {
 | 
				
			||||||
@@ -91,12 +94,11 @@ const CommentCreator: React.FC<CommentCreatorProps> = ({
 | 
				
			|||||||
                <div ref={$emojiCart}>
 | 
					                <div ref={$emojiCart}>
 | 
				
			||||||
                  <Picker
 | 
					                  <Picker
 | 
				
			||||||
                    onClick={emoji => {
 | 
					                    onClick={emoji => {
 | 
				
			||||||
                      console.log(emoji);
 | 
					 | 
				
			||||||
                      if ($comment && $comment.current) {
 | 
					                      if ($comment && $comment.current) {
 | 
				
			||||||
                        let textToInsert = `${emoji.colons} `;
 | 
					                        const textToInsert = `${emoji.colons} `;
 | 
				
			||||||
                        let cursorPosition = $comment.current.selectionStart;
 | 
					                        const cursorPosition = $comment.current.selectionStart;
 | 
				
			||||||
                        let textBeforeCursorPosition = $comment.current.value.substring(0, cursorPosition);
 | 
					                        const textBeforeCursorPosition = $comment.current.value.substring(0, cursorPosition);
 | 
				
			||||||
                        let textAfterCursorPosition = $comment.current.value.substring(
 | 
					                        const textAfterCursorPosition = $comment.current.value.substring(
 | 
				
			||||||
                          cursorPosition,
 | 
					                          cursorPosition,
 | 
				
			||||||
                          $comment.current.value.length,
 | 
					                          $comment.current.value.length,
 | 
				
			||||||
                        );
 | 
					                        );
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										162
									
								
								frontend/src/shared/components/TaskDetails/Loading.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										162
									
								
								frontend/src/shared/components/TaskDetails/Loading.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,162 @@
 | 
				
			|||||||
 | 
					import React, { useState, useRef } from 'react';
 | 
				
			||||||
 | 
					import {
 | 
				
			||||||
 | 
					  Plus,
 | 
				
			||||||
 | 
					  User,
 | 
				
			||||||
 | 
					  Trash,
 | 
				
			||||||
 | 
					  Paperclip,
 | 
				
			||||||
 | 
					  Clone,
 | 
				
			||||||
 | 
					  Share,
 | 
				
			||||||
 | 
					  Tags,
 | 
				
			||||||
 | 
					  Checkmark,
 | 
				
			||||||
 | 
					  CheckSquareOutline,
 | 
				
			||||||
 | 
					  At,
 | 
				
			||||||
 | 
					  Smile,
 | 
				
			||||||
 | 
					} from 'shared/icons';
 | 
				
			||||||
 | 
					import { toArray } from 'react-emoji-render';
 | 
				
			||||||
 | 
					import DOMPurify from 'dompurify';
 | 
				
			||||||
 | 
					import TaskAssignee from 'shared/components/TaskAssignee';
 | 
				
			||||||
 | 
					import useOnOutsideClick from 'shared/hooks/onOutsideClick';
 | 
				
			||||||
 | 
					import { usePopup } from 'shared/components/PopupMenu';
 | 
				
			||||||
 | 
					import CommentCreator from 'shared/components/TaskDetails/CommentCreator';
 | 
				
			||||||
 | 
					import { AngleDown } from 'shared/icons/AngleDown';
 | 
				
			||||||
 | 
					import Editor from 'rich-markdown-editor';
 | 
				
			||||||
 | 
					import dark from 'shared/utils/editorTheme';
 | 
				
			||||||
 | 
					import styled from 'styled-components';
 | 
				
			||||||
 | 
					import ReactMarkdown from 'react-markdown';
 | 
				
			||||||
 | 
					import { Picker, Emoji } from 'emoji-mart';
 | 
				
			||||||
 | 
					import 'emoji-mart/css/emoji-mart.css';
 | 
				
			||||||
 | 
					import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd';
 | 
				
			||||||
 | 
					import dayjs from 'dayjs';
 | 
				
			||||||
 | 
					import Task from 'shared/icons/Task';
 | 
				
			||||||
 | 
					import {
 | 
				
			||||||
 | 
					  ActivityItemHeader,
 | 
				
			||||||
 | 
					  ActivityItemTimestamp,
 | 
				
			||||||
 | 
					  ActivityItem,
 | 
				
			||||||
 | 
					  ActivityItemCommentAction,
 | 
				
			||||||
 | 
					  ActivityItemCommentActions,
 | 
				
			||||||
 | 
					  TaskDetailLabel,
 | 
				
			||||||
 | 
					  CommentContainer,
 | 
				
			||||||
 | 
					  ActivityItemCommentContainer,
 | 
				
			||||||
 | 
					  MetaDetailContent,
 | 
				
			||||||
 | 
					  TaskDetailsAddLabelIcon,
 | 
				
			||||||
 | 
					  ActionButton,
 | 
				
			||||||
 | 
					  AssignUserIcon,
 | 
				
			||||||
 | 
					  AssignUserLabel,
 | 
				
			||||||
 | 
					  AssignUsersButton,
 | 
				
			||||||
 | 
					  AssignedUsersSection,
 | 
				
			||||||
 | 
					  ViewRawButton,
 | 
				
			||||||
 | 
					  DueDateTitle,
 | 
				
			||||||
 | 
					  Container,
 | 
				
			||||||
 | 
					  LeftSidebar,
 | 
				
			||||||
 | 
					  SidebarSkeleton,
 | 
				
			||||||
 | 
					  ContentContainer,
 | 
				
			||||||
 | 
					  LeftSidebarContent,
 | 
				
			||||||
 | 
					  LeftSidebarSection,
 | 
				
			||||||
 | 
					  SidebarTitle,
 | 
				
			||||||
 | 
					  SidebarButton,
 | 
				
			||||||
 | 
					  SidebarButtonText,
 | 
				
			||||||
 | 
					  MarkCompleteButton,
 | 
				
			||||||
 | 
					  HeaderContainer,
 | 
				
			||||||
 | 
					  HeaderLeft,
 | 
				
			||||||
 | 
					  HeaderInnerContainer,
 | 
				
			||||||
 | 
					  TaskDetailsTitleWrapper,
 | 
				
			||||||
 | 
					  TaskDetailsTitle,
 | 
				
			||||||
 | 
					  ExtraActionsSection,
 | 
				
			||||||
 | 
					  HeaderRight,
 | 
				
			||||||
 | 
					  HeaderActionIcon,
 | 
				
			||||||
 | 
					  EditorContainer,
 | 
				
			||||||
 | 
					  InnerContentContainer,
 | 
				
			||||||
 | 
					  DescriptionContainer,
 | 
				
			||||||
 | 
					  Labels,
 | 
				
			||||||
 | 
					  ChecklistSection,
 | 
				
			||||||
 | 
					  MemberList,
 | 
				
			||||||
 | 
					  TaskMember,
 | 
				
			||||||
 | 
					  TabBarSection,
 | 
				
			||||||
 | 
					  TabBarItem,
 | 
				
			||||||
 | 
					  ActivitySection,
 | 
				
			||||||
 | 
					  TaskDetailsEditor,
 | 
				
			||||||
 | 
					  ActivityItemHeaderUser,
 | 
				
			||||||
 | 
					  ActivityItemHeaderTitle,
 | 
				
			||||||
 | 
					  ActivityItemHeaderTitleName,
 | 
				
			||||||
 | 
					  ActivityItemComment,
 | 
				
			||||||
 | 
					} from './Styles';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type TaskDetailsProps = {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const TaskDetailsLoading: React.FC<TaskDetailsProps> = () => {
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    <Container>
 | 
				
			||||||
 | 
					      <LeftSidebar>
 | 
				
			||||||
 | 
					        <LeftSidebarContent>
 | 
				
			||||||
 | 
					          <LeftSidebarSection>
 | 
				
			||||||
 | 
					            <SidebarTitle>TASK GROUP</SidebarTitle>
 | 
				
			||||||
 | 
					            <SidebarButton loading>
 | 
				
			||||||
 | 
					              <SidebarSkeleton />
 | 
				
			||||||
 | 
					            </SidebarButton>
 | 
				
			||||||
 | 
					            <DueDateTitle>DUE DATE</DueDateTitle>
 | 
				
			||||||
 | 
					            <SidebarButton loading>
 | 
				
			||||||
 | 
					              <SidebarSkeleton />
 | 
				
			||||||
 | 
					            </SidebarButton>
 | 
				
			||||||
 | 
					          </LeftSidebarSection>
 | 
				
			||||||
 | 
					          <AssignedUsersSection>
 | 
				
			||||||
 | 
					            <DueDateTitle>MEMBERS</DueDateTitle>
 | 
				
			||||||
 | 
					            <SidebarButton loading>
 | 
				
			||||||
 | 
					              <SidebarSkeleton />
 | 
				
			||||||
 | 
					            </SidebarButton>
 | 
				
			||||||
 | 
					          </AssignedUsersSection>
 | 
				
			||||||
 | 
					          <ExtraActionsSection>
 | 
				
			||||||
 | 
					            <DueDateTitle>ACTIONS</DueDateTitle>
 | 
				
			||||||
 | 
					            <ActionButton disabled icon={<Tags width={12} height={12} />}>
 | 
				
			||||||
 | 
					              Labels
 | 
				
			||||||
 | 
					            </ActionButton>
 | 
				
			||||||
 | 
					            <ActionButton disabled icon={<CheckSquareOutline width={12} height={12} />}>
 | 
				
			||||||
 | 
					              Checklist
 | 
				
			||||||
 | 
					            </ActionButton>
 | 
				
			||||||
 | 
					            <ActionButton disabled>Cover</ActionButton>
 | 
				
			||||||
 | 
					          </ExtraActionsSection>
 | 
				
			||||||
 | 
					        </LeftSidebarContent>
 | 
				
			||||||
 | 
					      </LeftSidebar>
 | 
				
			||||||
 | 
					      <ContentContainer>
 | 
				
			||||||
 | 
					        <HeaderContainer>
 | 
				
			||||||
 | 
					          <HeaderInnerContainer>
 | 
				
			||||||
 | 
					            <HeaderLeft>
 | 
				
			||||||
 | 
					              <MarkCompleteButton disabled invert={false}>
 | 
				
			||||||
 | 
					                <Checkmark width={8} height={8} />
 | 
				
			||||||
 | 
					                <span>Mark complete</span>
 | 
				
			||||||
 | 
					              </MarkCompleteButton>
 | 
				
			||||||
 | 
					            </HeaderLeft>
 | 
				
			||||||
 | 
					            <HeaderRight>
 | 
				
			||||||
 | 
					              <HeaderActionIcon>
 | 
				
			||||||
 | 
					                <Paperclip width={16} height={16} />
 | 
				
			||||||
 | 
					              </HeaderActionIcon>
 | 
				
			||||||
 | 
					              <HeaderActionIcon>
 | 
				
			||||||
 | 
					                <Clone width={16} height={16} />
 | 
				
			||||||
 | 
					              </HeaderActionIcon>
 | 
				
			||||||
 | 
					              <HeaderActionIcon>
 | 
				
			||||||
 | 
					                <Share width={16} height={16} />
 | 
				
			||||||
 | 
					              </HeaderActionIcon>
 | 
				
			||||||
 | 
					              <HeaderActionIcon>
 | 
				
			||||||
 | 
					                <Trash width={16} height={16} />
 | 
				
			||||||
 | 
					              </HeaderActionIcon>
 | 
				
			||||||
 | 
					            </HeaderRight>
 | 
				
			||||||
 | 
					          </HeaderInnerContainer>
 | 
				
			||||||
 | 
					          <TaskDetailsTitleWrapper loading>
 | 
				
			||||||
 | 
					            <TaskDetailsTitle value="" disabled loading />
 | 
				
			||||||
 | 
					          </TaskDetailsTitleWrapper>
 | 
				
			||||||
 | 
					        </HeaderContainer>
 | 
				
			||||||
 | 
					        <InnerContentContainer>
 | 
				
			||||||
 | 
					          <DescriptionContainer />
 | 
				
			||||||
 | 
					          <TabBarSection>
 | 
				
			||||||
 | 
					            <TabBarItem>Activity</TabBarItem>
 | 
				
			||||||
 | 
					          </TabBarSection>
 | 
				
			||||||
 | 
					          <ActivitySection />
 | 
				
			||||||
 | 
					        </InnerContentContainer>
 | 
				
			||||||
 | 
					        <CommentContainer>
 | 
				
			||||||
 | 
					          <CommentCreator disabled onCreateComment={() => null} onMemberProfile={() => null} />
 | 
				
			||||||
 | 
					        </CommentContainer>
 | 
				
			||||||
 | 
					      </ContentContainer>
 | 
				
			||||||
 | 
					    </Container>
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default TaskDetailsLoading;
 | 
				
			||||||
@@ -1,8 +1,9 @@
 | 
				
			|||||||
import styled, { css } from 'styled-components';
 | 
					import styled, { css, keyframes } from 'styled-components';
 | 
				
			||||||
import TextareaAutosize from 'react-autosize-textarea';
 | 
					import TextareaAutosize from 'react-autosize-textarea';
 | 
				
			||||||
import { mixin } from 'shared/utils/styles';
 | 
					import { mixin } from 'shared/utils/styles';
 | 
				
			||||||
import Button from 'shared/components/Button';
 | 
					import Button from 'shared/components/Button';
 | 
				
			||||||
import TaskAssignee from 'shared/components/TaskAssignee';
 | 
					import TaskAssignee from 'shared/components/TaskAssignee';
 | 
				
			||||||
 | 
					import theme from 'App/ThemeStyles';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const Container = styled.div`
 | 
					export const Container = styled.div`
 | 
				
			||||||
  display: flex;
 | 
					  display: flex;
 | 
				
			||||||
@@ -16,7 +17,7 @@ export const LeftSidebar = styled.div`
 | 
				
			|||||||
  background: #222740;
 | 
					  background: #222740;
 | 
				
			||||||
`;
 | 
					`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const MarkCompleteButton = styled.button<{ invert: boolean }>`
 | 
					export const MarkCompleteButton = styled.button<{ invert: boolean; disabled?: boolean }>`
 | 
				
			||||||
  padding: 4px 8px;
 | 
					  padding: 4px 8px;
 | 
				
			||||||
  position: relative;
 | 
					  position: relative;
 | 
				
			||||||
  border: none;
 | 
					  border: none;
 | 
				
			||||||
@@ -62,6 +63,11 @@ export const MarkCompleteButton = styled.button<{ invert: boolean }>`
 | 
				
			|||||||
            color: ${props.theme.colors.success};
 | 
					            color: ${props.theme.colors.success};
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        `}
 | 
					        `}
 | 
				
			||||||
 | 
					  ${props =>
 | 
				
			||||||
 | 
					    props.invert &&
 | 
				
			||||||
 | 
					    css`
 | 
				
			||||||
 | 
					      opacity: 0.6;
 | 
				
			||||||
 | 
					    `}
 | 
				
			||||||
`;
 | 
					`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const LeftSidebarContent = styled.div`
 | 
					export const LeftSidebarContent = styled.div`
 | 
				
			||||||
@@ -89,24 +95,55 @@ export const SidebarTitle = styled.div`
 | 
				
			|||||||
  text-transform: uppercase;
 | 
					  text-transform: uppercase;
 | 
				
			||||||
`;
 | 
					`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const SidebarButton = styled.div`
 | 
					export const defaultBaseColor = theme.colors.bg.primary;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const defaultHighlightColor = mixin.lighten(theme.colors.bg.primary, 0.25);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const skeletonKeyframes = keyframes`
 | 
				
			||||||
 | 
					  0% {
 | 
				
			||||||
 | 
					    background-position: -200px 0;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  100% {
 | 
				
			||||||
 | 
					    background-position: calc(200px + 100%) 0;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  `;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const SidebarButton = styled.div<{ loading?: boolean }>`
 | 
				
			||||||
  font-size: 14px;
 | 
					  font-size: 14px;
 | 
				
			||||||
  color: ${props => props.theme.colors.text.primary};
 | 
					  color: ${props => props.theme.colors.text.primary};
 | 
				
			||||||
  min-height: 32px;
 | 
					  min-height: 32px;
 | 
				
			||||||
  width: 100%;
 | 
					  width: 100%;
 | 
				
			||||||
 | 
					 | 
				
			||||||
  padding: 9px 8px 7px 8px;
 | 
					 | 
				
			||||||
  border-color: transparent;
 | 
					 | 
				
			||||||
  border-radius: 6px;
 | 
					  border-radius: 6px;
 | 
				
			||||||
  border-width: 1px;
 | 
					
 | 
				
			||||||
  border-style: solid;
 | 
					  ${props =>
 | 
				
			||||||
 | 
					    props.loading
 | 
				
			||||||
 | 
					      ? css`
 | 
				
			||||||
 | 
					          background: ${props.theme.colors.bg.primary};
 | 
				
			||||||
 | 
					        `
 | 
				
			||||||
 | 
					      : css`
 | 
				
			||||||
 | 
					          padding: 9px 8px 7px 8px;
 | 
				
			||||||
 | 
					          cursor: pointer;
 | 
				
			||||||
 | 
					          border-color: transparent;
 | 
				
			||||||
 | 
					          border-width: 1px;
 | 
				
			||||||
 | 
					          border-style: solid;
 | 
				
			||||||
 | 
					          &:hover {
 | 
				
			||||||
 | 
					            border-color: #414561;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        `};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  display: inline-block;
 | 
					  display: inline-block;
 | 
				
			||||||
  outline: 0;
 | 
					  outline: 0;
 | 
				
			||||||
  cursor: pointer;
 | 
					`;
 | 
				
			||||||
  &:hover {
 | 
					
 | 
				
			||||||
    border-color: #414561;
 | 
					export const SidebarSkeleton = styled.div`
 | 
				
			||||||
  }
 | 
					  background-image: linear-gradient(90deg, ${defaultBaseColor}, ${defaultHighlightColor}, ${defaultBaseColor});
 | 
				
			||||||
 | 
					  background-size: 200px 100%;
 | 
				
			||||||
 | 
					  background-repeat: no-repeat;
 | 
				
			||||||
 | 
					  border-radius: 6px;
 | 
				
			||||||
 | 
					  padding: 1px;
 | 
				
			||||||
 | 
					  animation: ${skeletonKeyframes} 1.2s ease-in-out infinite;
 | 
				
			||||||
 | 
					  width: 100%;
 | 
				
			||||||
 | 
					  height: 100%;
 | 
				
			||||||
`;
 | 
					`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const SidebarButtonText = styled.span`
 | 
					export const SidebarButtonText = styled.span`
 | 
				
			||||||
@@ -141,18 +178,18 @@ export const HeaderLeft = styled.div`
 | 
				
			|||||||
  justify-content: flex-start;
 | 
					  justify-content: flex-start;
 | 
				
			||||||
`;
 | 
					`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const TaskDetailsTitleWrapper = styled.div`
 | 
					export const TaskDetailsTitleWrapper = styled.div<{ loading?: boolean }>`
 | 
				
			||||||
  width: 100%;
 | 
					  width: 100%;
 | 
				
			||||||
  margin: 8px 0 4px 0;
 | 
					  margin: 8px 0 4px 0;
 | 
				
			||||||
  display: inline-block;
 | 
					  display: flex;
 | 
				
			||||||
 | 
					  border-radius: 6px;
 | 
				
			||||||
 | 
					  ${props => props.loading && `background: ${props.theme.colors.bg.primary};`}
 | 
				
			||||||
`;
 | 
					`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const TaskDetailsTitle = styled(TextareaAutosize)`
 | 
					export const TaskDetailsTitle = styled(TextareaAutosize)<{ loading?: boolean }>`
 | 
				
			||||||
  padding: 9px 8px 7px 8px;
 | 
					  padding: 9px 8px 7px 8px;
 | 
				
			||||||
  border-color: transparent;
 | 
					  border-color: transparent;
 | 
				
			||||||
  border-radius: 6px;
 | 
					  border-radius: 6px;
 | 
				
			||||||
  border-width: 1px;
 | 
					 | 
				
			||||||
  border-style: solid;
 | 
					 | 
				
			||||||
  width: 100%;
 | 
					  width: 100%;
 | 
				
			||||||
  color: #c2c6dc;
 | 
					  color: #c2c6dc;
 | 
				
			||||||
  display: inline-block;
 | 
					  display: inline-block;
 | 
				
			||||||
@@ -161,13 +198,25 @@ export const TaskDetailsTitle = styled(TextareaAutosize)`
 | 
				
			|||||||
  font-weight: 700;
 | 
					  font-weight: 700;
 | 
				
			||||||
  background: none;
 | 
					  background: none;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  &:hover {
 | 
					  ${props =>
 | 
				
			||||||
    border-color: #414561;
 | 
					    props.loading
 | 
				
			||||||
  }
 | 
					      ? css`
 | 
				
			||||||
 | 
					          background-image: linear-gradient(90deg, ${defaultBaseColor}, ${defaultHighlightColor}, ${defaultBaseColor});
 | 
				
			||||||
 | 
					          background-size: 200px 100%;
 | 
				
			||||||
 | 
					          background-repeat: no-repeat;
 | 
				
			||||||
 | 
					          animation: ${skeletonKeyframes} 1.2s ease-in-out infinite;
 | 
				
			||||||
 | 
					        `
 | 
				
			||||||
 | 
					      : css`
 | 
				
			||||||
 | 
					          &:hover {
 | 
				
			||||||
 | 
					            border-color: #414561;
 | 
				
			||||||
 | 
					            border-width: 1px;
 | 
				
			||||||
 | 
					            border-style: solid;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  &:focus {
 | 
					          &:focus {
 | 
				
			||||||
    border-color: ${props => props.theme.colors.primary};
 | 
					            border-color: ${props.theme.colors.primary};
 | 
				
			||||||
  }
 | 
					          }
 | 
				
			||||||
 | 
					        `}
 | 
				
			||||||
`;
 | 
					`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const DueDateTitle = styled.div`
 | 
					export const DueDateTitle = styled.div`
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user