diff --git a/.github/workflows/prjob_build.yml b/.github/workflows/prjob_build.yml index b60e41a2..bf716fbd 100644 --- a/.github/workflows/prjob_build.yml +++ b/.github/workflows/prjob_build.yml @@ -2,7 +2,7 @@ name: Build on: pull_request: branches: - - master + - "*" jobs: build: name: build diff --git a/.github/workflows/prjob_cypress_tests.yml b/.github/workflows/prjob_cypress_tests.yml index 766751f9..bfb395f5 100644 --- a/.github/workflows/prjob_cypress_tests.yml +++ b/.github/workflows/prjob_cypress_tests.yml @@ -3,7 +3,7 @@ name: Cypress Tests on: pull_request: branches: - - master + - "*" jobs: cypress: diff --git a/.github/workflows/prjob_eslint.yml b/.github/workflows/prjob_eslint.yml index f352ab9b..26e3e16b 100644 --- a/.github/workflows/prjob_eslint.yml +++ b/.github/workflows/prjob_eslint.yml @@ -2,7 +2,7 @@ name: Eslint on: pull_request: branches: - - master + - "*" jobs: eslint: name: eslint diff --git a/.github/workflows/prjob_prettier.yml b/.github/workflows/prjob_prettier.yml index ec6403db..0ba179a5 100644 --- a/.github/workflows/prjob_prettier.yml +++ b/.github/workflows/prjob_prettier.yml @@ -2,7 +2,7 @@ name: Prettier on: pull_request: branches: - - master + - "*" jobs: prettier: diff --git a/.github/workflows/prjob_tests.yml b/.github/workflows/prjob_tests.yml index 55a57645..f6de37fe 100644 --- a/.github/workflows/prjob_tests.yml +++ b/.github/workflows/prjob_tests.yml @@ -2,7 +2,7 @@ name: Tests on: pull_request: branches: - - master + - "*" jobs: test-jest: name: Jest diff --git a/cypress/e2e/53_workspaceMission.cy.ts b/cypress/e2e/53_workspaceMission.cy.ts index 131c9bcd..d6549dc2 100644 --- a/cypress/e2e/53_workspaceMission.cy.ts +++ b/cypress/e2e/53_workspaceMission.cy.ts @@ -1,5 +1,5 @@ describe('Create Workspace And Update Mission', () => { - it('Creating an Workspace', () => { + it('Creating A Workspace', () => { cy.login('carol'); cy.wait(1000); diff --git a/cypress/e2e/54_addFeature.cy.ts b/cypress/e2e/54_addFeature.cy.ts new file mode 100644 index 00000000..b1f21a66 --- /dev/null +++ b/cypress/e2e/54_addFeature.cy.ts @@ -0,0 +1,49 @@ +describe('Add feature To Workspace', () => { + it('Creating A Workspace', () => { + cy.login('carol'); + cy.wait(1000); + + const WorkSpaceName = 'Workspace Feature'; + + const workspace = { + loggedInAs: 'carol', + name: WorkSpaceName, + description: 'We are testing out our workspace feature', + website: 'https://community.sphinx.chat', + github: 'https://github.com/stakwork/sphinx-tribes-frontend' + }; + + cy.create_workspace(workspace); + cy.wait(1000); + + cy.contains(workspace.name).contains('Manage').click(); + cy.wait(1000); + + cy.get('[data-testid="mission-link"]') + .invoke('show') + .then(($link: JQuery) => { + const modifiedHref = $link.attr('href'); + cy.wrap($link).invoke('removeAttr', 'target'); + cy.wrap($link).click(); + cy.url().should('include', modifiedHref); + }); + cy.wait(1000); + + cy.contains('No mission yet'); + cy.contains('No tactics yet'); + + cy.get('[data-testid="new-feature-btn"]').click(); + cy.wait(1000); + + cy.contains('Add New Feature'); + + const newFeature = 'This is my Feature'; + cy.get('[data-testid="feature-input"]').type(newFeature); + cy.get('[data-testid="add-feature-btn"]').click(); + cy.wait(1000); + + cy.contains(newFeature).should('exist', { timeout: 3000 }); + + cy.logout('carol'); + }); +}); diff --git a/cypress/e2e/55_updateFeature.cy.ts b/cypress/e2e/55_updateFeature.cy.ts new file mode 100644 index 00000000..2ae37f7b --- /dev/null +++ b/cypress/e2e/55_updateFeature.cy.ts @@ -0,0 +1,60 @@ +describe('Update feature To Workspace', () => { + it('Updating A Workspace Feature', () => { + cy.login('carol'); + cy.wait(1000); + + const WorkSpaceName = 'WS Feature Update'; + + const workspace = { + loggedInAs: 'carol', + name: WorkSpaceName, + description: 'We are testing out our workspace feature', + website: 'https://community.sphinx.chat', + github: 'https://github.com/stakwork/sphinx-tribes-frontend' + }; + + cy.create_workspace(workspace); + cy.wait(1000); + + cy.contains(workspace.name).contains('Manage').click(); + cy.wait(1000); + + cy.get('[data-testid="mission-link"]') + .invoke('show') + .then(($link: JQuery) => { + const modifiedHref = $link.attr('href'); + cy.wrap($link).invoke('removeAttr', 'target'); + cy.wrap($link).click(); + cy.url().should('include', modifiedHref); + }); + cy.wait(1000); + + cy.contains('No mission yet'); + cy.contains('No tactics yet'); + + cy.get('[data-testid="new-feature-btn"]').click(); + cy.wait(1000); + + cy.contains('Add New Feature'); + + const newFeature = 'A new Feature'; + cy.get('[data-testid="feature-input"]').type(newFeature); + cy.get('[data-testid="add-feature-btn"]').click(); + cy.wait(1000); + + cy.contains(newFeature).should('exist', { timeout: 3000 }); + cy.wait(1000); + + cy.get('[data-testid="architecture-option-btn"]').click(); + cy.get('[data-testid="architecture-edit-btn"]').click(); + + const updatedFeature = 'Feature Architecture'; + cy.get('[data-testid="architecture-textarea"]').type(updatedFeature); + cy.get('[data-testid="architecture-update-btn"]').click(); + cy.wait(1000); + + cy.contains(updatedFeature).should('exist', { timeout: 1000 }); + + cy.logout('carol'); + }); +}); diff --git a/src/__test__/__mockData__/persons.ts b/src/__test__/__mockData__/persons.ts index c3f4852a..d1487d4a 100644 --- a/src/__test__/__mockData__/persons.ts +++ b/src/__test__/__mockData__/persons.ts @@ -1,4 +1,4 @@ -import { Person } from '../../store/main'; +import { Person } from '../../store/interface'; export const people: Person[] = [ { diff --git a/src/__test__/__mockData__/userTickets.ts b/src/__test__/__mockData__/userTickets.ts index c23ba558..b888bceb 100644 --- a/src/__test__/__mockData__/userTickets.ts +++ b/src/__test__/__mockData__/userTickets.ts @@ -1,4 +1,4 @@ -import { PersonBounty } from 'store/main'; +import { PersonBounty } from 'store/interface'; export const userAssignedBounties: PersonBounty[] = [ { diff --git a/src/__test__/__mockData__/workspace.ts b/src/__test__/__mockData__/workspace.ts index 582310cb..7f244969 100644 --- a/src/__test__/__mockData__/workspace.ts +++ b/src/__test__/__mockData__/workspace.ts @@ -1,4 +1,4 @@ -import { Workspace } from 'store/main'; +import { Workspace } from 'store/interface'; export const mockWorkspaces: Workspace[] = [ { diff --git a/src/__test__/__mockStore__/useMockSelfProfileStore.ts b/src/__test__/__mockStore__/useMockSelfProfileStore.ts index e4d64fcf..2012f862 100644 --- a/src/__test__/__mockStore__/useMockSelfProfileStore.ts +++ b/src/__test__/__mockStore__/useMockSelfProfileStore.ts @@ -1,7 +1,7 @@ import { user } from '__test__/__mockData__/user'; import { useEffect } from 'react'; import { useStores } from 'store'; -import { Person } from 'store/main'; +import { Person } from 'store/interface'; export const useMockSelfProfileStore = ({ enabled }: { enabled: boolean }) => { const { ui, main } = useStores(); diff --git a/src/bounties/interfaces.ts b/src/bounties/interfaces.ts index 88193954..14e375ba 100644 --- a/src/bounties/interfaces.ts +++ b/src/bounties/interfaces.ts @@ -1,5 +1,5 @@ import { CodingLanguageLabel } from 'people/interfaces'; -import { Person } from 'store/main'; +import { Person } from 'store/interface'; export interface BountiesDescriptionProps { description?: any; diff --git a/src/hooks/usePerson.ts b/src/hooks/usePerson.ts index 648527fb..85d6123c 100644 --- a/src/hooks/usePerson.ts +++ b/src/hooks/usePerson.ts @@ -1,4 +1,4 @@ -import { Person } from '../store/main'; +import { Person } from '../store/interface'; import { useStores } from '../store'; export const usePerson = (id: any) => { diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 0bd1c8d0..e4422ade 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -5,6 +5,7 @@ import { AppMode } from 'config'; import { Route, Switch } from 'react-router-dom'; import { observer } from 'mobx-react-lite'; import WorkspaceMission from 'people/widgetViews/WorkspaceMission'; +import WorkspaceFeature from 'people/widgetViews/WorkspaceFeature'; import PeopleHeader from '../people/main/Header'; import TokenRefresh from '../people/utils/TokenRefresh'; import BotsBody from './bots/Body'; @@ -48,6 +49,9 @@ const modeDispatchPages: Record React.ReactElement> = { + + + diff --git a/src/pages/leaderboard/__tests__/leaderboard.spec.tsx b/src/pages/leaderboard/__tests__/leaderboard.spec.tsx index 7fb99425..a4d994dc 100644 --- a/src/pages/leaderboard/__tests__/leaderboard.spec.tsx +++ b/src/pages/leaderboard/__tests__/leaderboard.spec.tsx @@ -2,7 +2,8 @@ import '@testing-library/jest-dom'; import { act, fireEvent, render, screen, waitFor } from '@testing-library/react'; import React from 'react'; import { useStores } from '../../../store'; -import { mainStore, Person } from '../../../store/main.ts'; +import { Person } from '../../../store/interface'; +import { mainStore } from '../../../store/main.ts'; import { leaderboardStore } from '../store.ts'; import { LeaderboardPage } from '../index.tsx'; diff --git a/src/pages/leaderboard/leaderboardItem/__tests__/LeaerboardItem.spec.tsx b/src/pages/leaderboard/leaderboardItem/__tests__/LeaerboardItem.spec.tsx index db5571c0..83efb2cf 100644 --- a/src/pages/leaderboard/leaderboardItem/__tests__/LeaerboardItem.spec.tsx +++ b/src/pages/leaderboard/leaderboardItem/__tests__/LeaerboardItem.spec.tsx @@ -1,6 +1,5 @@ import '@testing-library/jest-dom'; import { render, screen } from '@testing-library/react'; -import userEvent from '@testing-library/user-event'; import nock from 'nock'; import React from 'react'; import { setupStore } from '../../../../__test__/__mockData__/setupStore'; diff --git a/src/pages/leaderboard/top3/index.tsx b/src/pages/leaderboard/top3/index.tsx index acbc8f7b..46a6c62f 100644 --- a/src/pages/leaderboard/top3/index.tsx +++ b/src/pages/leaderboard/top3/index.tsx @@ -6,7 +6,7 @@ import { DollarConverter } from 'helpers'; import React, { useEffect, useState } from 'react'; import { Link } from 'react-router-dom'; import { useStores } from 'store'; -import { Person } from 'store/main'; +import { Person } from 'store/interface'; import styled from 'styled-components'; import { LeaderItem } from '../store'; diff --git a/src/pages/leaderboard/userInfo/index.tsx b/src/pages/leaderboard/userInfo/index.tsx index e31cd810..fc54eb66 100644 --- a/src/pages/leaderboard/userInfo/index.tsx +++ b/src/pages/leaderboard/userInfo/index.tsx @@ -7,7 +7,7 @@ import styled from 'styled-components'; import { colors } from '../../../config'; import ConnectCard from '../../../people/utils/ConnectCard'; import { useStores } from '../../../store'; -import { Person } from '../../../store/main'; +import { Person } from '../../../store/interface'; const UserItemContainer = styled.div` display: flex; gap: 1rem; diff --git a/src/pages/people/peopleList/PeopleList.tsx b/src/pages/people/peopleList/PeopleList.tsx index 0843beff..3ce9f45a 100644 --- a/src/pages/people/peopleList/PeopleList.tsx +++ b/src/pages/people/peopleList/PeopleList.tsx @@ -5,7 +5,7 @@ import PageLoadSpinner from 'people/utils/PageLoadSpinner'; import React from 'react'; import { useHistory } from 'react-router-dom'; import { useStores } from 'store'; -import { queryLimit } from 'store/main'; +import { queryLimit } from 'store/interface'; import styled from 'styled-components'; import { observer } from 'mobx-react-lite'; import Person from '../Person'; diff --git a/src/pages/people/tabs/Wanted.tsx b/src/pages/people/tabs/Wanted.tsx index 891b388a..ffa5c492 100644 --- a/src/pages/people/tabs/Wanted.tsx +++ b/src/pages/people/tabs/Wanted.tsx @@ -10,7 +10,7 @@ import PageLoadSpinner from 'people/utils/PageLoadSpinner'; import React, { useCallback, useEffect, useState } from 'react'; import { Route, Switch, useHistory, useRouteMatch, useParams } from 'react-router-dom'; import { useStores } from 'store'; -import { paginationQueryLimit } from 'store/main'; +import { paginationQueryLimit } from 'store/interface'; import styled from 'styled-components'; import { LoadMoreContainer } from '../../../people/widgetViews/WidgetSwitchViewer'; import { colors } from '../../../config/colors'; diff --git a/src/pages/superadmin/header/HeaderStyles.tsx b/src/pages/superadmin/header/HeaderStyles.tsx index de0fb7b5..ff9d9e69 100644 --- a/src/pages/superadmin/header/HeaderStyles.tsx +++ b/src/pages/superadmin/header/HeaderStyles.tsx @@ -156,7 +156,7 @@ export const Option = styled.div` top: 65px; right: 48px; width: 169px; - height: 157px; + height: 167px; display: inline-flex; padding: 12px 28px 12px 28px; flex-direction: column; @@ -231,7 +231,7 @@ export const WorkspaceOption = styled.div` `; export const WorkspaceText = styled.div` - flex: 2, + flex: 2; text-align: 'center'; white-space: nowrap; overflow: hidden; diff --git a/src/pages/superadmin/header/__tests__/SuperAdminHeader.spec.tsx b/src/pages/superadmin/header/__tests__/SuperAdminHeader.spec.tsx index 25379c43..e6c15992 100644 --- a/src/pages/superadmin/header/__tests__/SuperAdminHeader.spec.tsx +++ b/src/pages/superadmin/header/__tests__/SuperAdminHeader.spec.tsx @@ -1,4 +1,5 @@ import '@testing-library/jest-dom'; +import { waitFor } from '@testing-library/dom'; import { render, screen, within, act, fireEvent } from '@testing-library/react'; import moment from 'moment'; import nock from 'nock'; @@ -8,11 +9,11 @@ import { user } from '../../../../__test__/__mockData__/user'; import { mockUsehistory } from '../../../../__test__/__mockFn__/useHistory'; import { Header } from '../'; -beforeAll(() => { - nock.disableNetConnect(); - setupStore(); - mockUsehistory(); -}); +// beforeAll(() => { +// nock.disableNetConnect(); +// setupStore(); +// mockUsehistory(); +// }); /** * @jest-environment jsdom @@ -206,6 +207,7 @@ describe('Header Component', () => { expect(screen.getByText(exportCSVText)).toBeInTheDocument(); }); + test('displays "Custom" when dates are selected', async () => { const setStartDateMock = jest.fn(); const setEndDateMock = jest.fn(); @@ -230,4 +232,44 @@ describe('Header Component', () => { expect(dropDownButton).toHaveTextContent('Custom'); }); + + test('displays current month and number of days dynamically based on current date', async () => { + const setStartDateMock = jest.fn(); + const setEndDateMock = jest.fn(); + const setWorkspaceMock = jest.fn(); + + const endDate = moment().startOf('day').unix(); + const startDate = moment().startOf('month').unix(); + + render( +
+ ); + + const dropDownButton = screen.getByTestId('DropDown'); + fireEvent.click(dropDownButton); + + const CurrentMonthOption = screen.getByText('Current Month'); + fireEvent.click(CurrentMonthOption); + + const expectedTextContent = 'Current Month'; + + await waitFor(() => expect(dropDownButton).toHaveTextContent(expectedTextContent)); + + const leftWrapperElement = screen.getByTestId('leftWrapper'); + const monthElement = within(leftWrapperElement).getByTestId('month'); + + expect(monthElement).toBeInTheDocument(); + + const expectedDateRange = `${moment.unix(startDate).format('DD MMM')} - ${moment + .unix(endDate) + .format('DD MMM YYYY')}`; + expect(monthElement).toHaveTextContent(expectedDateRange); + }); }); diff --git a/src/pages/superadmin/header/index.tsx b/src/pages/superadmin/header/index.tsx index e16bb655..e9e90a6e 100644 --- a/src/pages/superadmin/header/index.tsx +++ b/src/pages/superadmin/header/index.tsx @@ -1,6 +1,7 @@ import React, { useState, useRef, useEffect, useCallback } from 'react'; import moment from 'moment'; -import { mainStore, Workspace } from 'store/main'; +import { Workspace } from 'store/interface'; +import { mainStore } from 'store/main'; import { AlternateWrapper, ButtonWrapper, @@ -111,6 +112,9 @@ export const Header = ({ case 90: text = 'Last 90 Days'; break; + case moment().date(): + text = `Current Month`; + break; default: break; } @@ -239,6 +243,7 @@ export const Header = ({
  • handleDropDownChange(7)}>7 Days
  • handleDropDownChange(30)}>30 Days
  • handleDropDownChange(90)}>90 Days
  • +
  • handleDropDownChange(moment().date())}>Current Month
  • handleDropDownChange('Custom')}> Custom diff --git a/src/pages/superadmin/index.tsx b/src/pages/superadmin/index.tsx index bd05c2ed..890245c4 100644 --- a/src/pages/superadmin/index.tsx +++ b/src/pages/superadmin/index.tsx @@ -5,7 +5,7 @@ import React, { useCallback, useEffect, useState } from 'react'; import { EuiLoadingSpinner } from '@elastic/eui'; import styled from 'styled-components'; -import { BountyMetrics, defaultSuperAdminBountyStatus, Person } from 'store/main'; +import { BountyMetrics, defaultSuperAdminBountyStatus, Person } from 'store/interface'; import { useStores } from 'store'; import moment from 'moment'; import { useInViewPort } from 'hooks'; diff --git a/src/pages/superadmin/statistics/index.tsx b/src/pages/superadmin/statistics/index.tsx index f054886c..0f45ee6d 100644 --- a/src/pages/superadmin/statistics/index.tsx +++ b/src/pages/superadmin/statistics/index.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { BountyMetrics } from 'store/main'; +import { BountyMetrics } from 'store/interface'; import { convertToLocaleString, formatPercentage } from 'helpers/helpers-extended'; import copy from '../header/icons/copy.svg'; import hunter from '../header/icons/hunter.svg'; diff --git a/src/pages/superadmin/tableComponent/index.tsx b/src/pages/superadmin/tableComponent/index.tsx index 28d84579..7ab1e702 100644 --- a/src/pages/superadmin/tableComponent/index.tsx +++ b/src/pages/superadmin/tableComponent/index.tsx @@ -3,7 +3,7 @@ import styled from 'styled-components'; import moment from 'moment'; import { EuiCheckboxGroup, EuiPopover, EuiText } from '@elastic/eui'; import MaterialIcon from '@material/react-material-icon'; -import { Person } from 'store/main'; +import { Person } from 'store/interface'; import paginationarrow1 from '../header/icons/paginationarrow1.svg'; import paginationarrow2 from '../header/icons/paginationarrow2.svg'; import defaultPic from '../../../public/static/profile_avatar.svg'; diff --git a/src/pages/superadmin/utils/metrics.ts b/src/pages/superadmin/utils/metrics.ts index 7ec598cb..cc76df06 100644 --- a/src/pages/superadmin/utils/metrics.ts +++ b/src/pages/superadmin/utils/metrics.ts @@ -1,4 +1,4 @@ -import { BountyMetrics } from '../../../store/main'; +import { BountyMetrics } from '../../../store/interface'; export const normalizeMetrics = (data: any): BountyMetrics => ({ bounties_posted: data.BountiesPosted || data.bounties_posted, diff --git a/src/pages/tickets/TicketModalPage.tsx b/src/pages/tickets/TicketModalPage.tsx index 6c5d37d9..40312e52 100644 --- a/src/pages/tickets/TicketModalPage.tsx +++ b/src/pages/tickets/TicketModalPage.tsx @@ -9,7 +9,7 @@ import FocusedView from '../../people/main/FocusView'; import { widgetConfigs } from '../../people/utils/Constants'; import { AlreadyDeleted } from '../../components/common/AfterDeleteNotification/AlreadyDeleted'; import { useStores } from '../../store'; -import { PersonBounty } from '../../store/main'; +import { PersonBounty } from '../../store/interface'; const color = colors['light']; const focusedDesktopModalStyles = widgetConfigs.bounties.modalStyle; diff --git a/src/pages/tickets/Tickets.tsx b/src/pages/tickets/Tickets.tsx index 87b95d19..ef34f3d9 100644 --- a/src/pages/tickets/Tickets.tsx +++ b/src/pages/tickets/Tickets.tsx @@ -5,7 +5,7 @@ import BountyHeader from 'people/widgetViews/BountyHeader'; import WidgetSwitchViewer from 'people/widgetViews/WidgetSwitchViewer'; import React, { useCallback, useEffect, useState } from 'react'; import { useHistory } from 'react-router'; -import { queryLimit, defaultBountyStatus } from 'store/main'; +import { queryLimit, defaultBountyStatus } from 'store/interface'; import { useLocation } from 'react-router-dom'; import { colors } from '../../config/colors'; import { useIsMobile } from '../../hooks'; diff --git a/src/pages/tickets/style.ts b/src/pages/tickets/style.ts index 4ad6dda2..b4be453e 100644 --- a/src/pages/tickets/style.ts +++ b/src/pages/tickets/style.ts @@ -19,6 +19,157 @@ export const WorkspaceBody = styled.div` overflow-x: hidden; `; +export const FeatureBody = styled.div` + display: flex; + flex-direction: column; + background: var(--Search-bar-background, #f2f3f5); + height: 100vh; + overflow-y: auto; + overflow-x: hidden; +`; + +export const Header = styled.div` + height: 130px; + width: 65%; + display: flex; + align-items: center; + justify-content: space-between; + background: #fff; +`; + +export const Leftheader = styled.div` + display: flex; + gap: 20px; + align-items: center; + justify-content: center; +`; + +export const HeaderWrap = styled.div` + display: flex; + width: 100%; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + background: #fff; +`; + +export const DataWrap = styled.div` + padding: 40px 50px; + display: flex; + width: 50%; + margin: 0 auto; + display: flex; + flex-direction: column; + align-items: left; + justify-content: center; + + @media only screen and (max-width: 900px) { + width: 90%; + padding: 30px 40px; + } + + @media only screen and (max-width: 500px) { + width: 90%; + padding: 20px 10px; + } +`; + +export const FieldWrap = styled.div` + margin-bottom: 30px; +`; + +export const Label = styled.h5` + font-size: 1.12rem; + font-weight: bolder; +`; + +export const Data = styled.div` + border: 1px solid #ccc; + min-height: 50px; + border-radius: 5px; + padding: 20px 30px; + position: relative; + display: flex; + flex-direction: column; + white-space: pre-wrap; + + .MaterialIcon { + font-style: normal; + font-weight: 900; + font-size: 1.4rem; + color: #000000; + } +`; + +export const OptionsWrap = styled.div` + position: absolute; + right: 6px; + top: 4px; + cursor: pointer; + display: flex; + flex-direction: column; + align-items: center; + + button { + border: 0.5px solid #000000; + font-size: 0.8rem; + font-weight: 700; + border-radius: 5px; + padding: 2px 10px; + } +`; + +export const TextArea = styled.textarea` + padding: 0.5rem 1rem; + border-radius: 0.375rem; + border: 2px solid #dde1e5; + outline: none; + caret-color: #618aff; + color: #3c3f41; + font-family: 'Barlow'; + font-size: 1rem; + font-style: normal; + font-weight: 500; + line-height: 20px; + width: 100%; + resize: none; + min-height: 5.9375rem; + + ::placeholder { + color: #b0b7bc; + font-family: 'Barlow'; + font-size: 13px; + font-style: normal; + font-weight: 400; + line-height: 20px; + } + :focus { + border: 2px solid #82b4ff; + } +`; + +interface ButtonProps { + color?: string; +} + +export const FeatureLabel = styled.p` + color: var(--Text-2, #3c3f41); + font-family: Barlow; + font-size: 28px; + font-style: normal; + font-weight: 700; + margin: 2px; + display: flex; + align-items: center; +`; + +export const FeatureName = styled.div` + display: flex; + flex-direction: column; + justify-content: center; +`; + export const Backdrop = styled.div` position: fixed; z-index: 1; diff --git a/src/pages/tickets/workspace/WorkspaceTickets.tsx b/src/pages/tickets/workspace/WorkspaceTickets.tsx index 4856f0f3..08b69194 100644 --- a/src/pages/tickets/workspace/WorkspaceTickets.tsx +++ b/src/pages/tickets/workspace/WorkspaceTickets.tsx @@ -10,7 +10,7 @@ import { colors } from '../../../config/colors'; import { useIsMobile } from '../../../hooks'; import { useStores } from '../../../store'; import { WorkspaceBody, Body, Backdrop } from '../style'; -import { Workspace, queryLimit } from '../../../store/main'; +import { Workspace, queryLimit } from '../../../store/interface'; import { WorkspaceHeader } from './workspaceHeader'; function WorkspaceBodyComponent() { diff --git a/src/pages/tickets/workspace/workspaceHeader/WorkspaceHeaderStyles.tsx b/src/pages/tickets/workspace/workspaceHeader/WorkspaceHeaderStyles.tsx index bab407f0..ca28d2bd 100644 --- a/src/pages/tickets/workspace/workspaceHeader/WorkspaceHeaderStyles.tsx +++ b/src/pages/tickets/workspace/workspaceHeader/WorkspaceHeaderStyles.tsx @@ -5,15 +5,6 @@ interface styledProps { color?: any; } -export const Header = styled.div` - height: 130px; - width: 65%; - display: flex; - align-items: center; - justify-content: space-between; - background: #fff; -`; - export const UrlButtonContainer = styled.div` width: 180px; display: flex; @@ -133,12 +124,6 @@ export const FilterLabel = styled.label` line-height: 17px; letter-spacing: 0.15px; `; -export const Leftheader = styled.div` - display: flex; - gap: 20px; - align-items: center; - justify-content: center; -`; export const CompanyNameAndLink = styled.div` display: flex; flex-direction: column; diff --git a/src/pages/tickets/workspace/workspaceHeader/index.tsx b/src/pages/tickets/workspace/workspaceHeader/index.tsx index fb0f46f5..e7c83e35 100644 --- a/src/pages/tickets/workspace/workspaceHeader/index.tsx +++ b/src/pages/tickets/workspace/workspaceHeader/index.tsx @@ -8,6 +8,7 @@ import { WorkspaceBountyHeaderProps } from '../../../../people/interfaces.ts'; import { SearchBar } from '../../../../components/common/index.tsx'; import { useStores } from '../../../../store/index.tsx'; import { userCanManageBounty, filterCount } from '../../../../helpers/index.ts'; +import { Leftheader, Header } from '../../style.ts'; import addBounty from './Icons/addBounty.svg'; import file from './Icons/file.svg'; import githubIcon from './Icons/githubIcon.svg'; @@ -25,11 +26,9 @@ import { FillContainer, Filters, FiltersRight, - Header, ImageContainer, Img, InternalContainer, - Leftheader, NewStatusContainer, NumberOfBounties, PrimaryText, diff --git a/src/people/interfaces.ts b/src/people/interfaces.ts index 4bd08699..c7a983b3 100644 --- a/src/people/interfaces.ts +++ b/src/people/interfaces.ts @@ -1,6 +1,6 @@ import React, { ReactNode } from 'react'; import { Extras } from '../components/form/inputs/widgets/interfaces'; -import { Workspace, Person, PersonBounty } from '../store/main'; +import { Workspace, Person, PersonBounty } from '../store/interface'; import { MeData } from '../store/ui'; import { Widget } from './main/types'; import { coding_languages } from './utils/languageLabelStyle'; diff --git a/src/people/main/Body.tsx b/src/people/main/Body.tsx index ea9e3743..cdb8e6c3 100644 --- a/src/people/main/Body.tsx +++ b/src/people/main/Body.tsx @@ -4,7 +4,7 @@ import { useHistory } from 'react-router'; import styled from 'styled-components'; import { EuiGlobalToastList, EuiLoadingSpinner } from '@elastic/eui'; import PeopleHeader from 'people/widgetViews/PeopleHeader'; -import type { Person } from 'store/main'; +import type { Person } from 'store/interface'; import { SearchTextInput } from '../../components/common'; import { colors } from '../../config/colors'; import { useIsMobile, usePageScroll, useScreenWidth } from '../../hooks'; diff --git a/src/people/main/FocusView.tsx b/src/people/main/FocusView.tsx index 3a051253..e5e3a2df 100644 --- a/src/people/main/FocusView.tsx +++ b/src/people/main/FocusView.tsx @@ -4,7 +4,7 @@ import { cloneDeep } from 'lodash'; import { observer } from 'mobx-react-lite'; import { FocusViewProps } from 'people/interfaces'; import { EuiGlobalToastList } from '@elastic/eui'; -import { Workspace } from 'store/main'; +import { Workspace } from 'store/interface'; import { Box } from '@mui/system'; import { uiStore } from 'store/ui'; import { useStores } from '../../store'; diff --git a/src/people/main/bountyModal/BountyModal.tsx b/src/people/main/bountyModal/BountyModal.tsx index abaea4cb..b2d1038a 100644 --- a/src/people/main/bountyModal/BountyModal.tsx +++ b/src/people/main/bountyModal/BountyModal.tsx @@ -5,7 +5,7 @@ import React, { useEffect, useState, useCallback } from 'react'; import { useHistory, useParams } from 'react-router-dom'; import { useStores } from 'store'; import { BountyModalProps } from 'people/interfaces'; -import { PersonBounty } from 'store/main'; +import { PersonBounty } from 'store/interface'; import FocusedView from '../FocusView'; const config = widgetConfigs.bounties; diff --git a/src/people/utils/__test__/__mockData__/users.ts b/src/people/utils/__test__/__mockData__/users.ts index 158cb758..11e95f3b 100644 --- a/src/people/utils/__test__/__mockData__/users.ts +++ b/src/people/utils/__test__/__mockData__/users.ts @@ -1,4 +1,4 @@ -import { Person } from 'store/main'; +import { Person } from 'store/interface'; export const users: Person[] = [ { diff --git a/src/people/utils/filterPeople.ts b/src/people/utils/filterPeople.ts index 55c97994..472cbfa8 100644 --- a/src/people/utils/filterPeople.ts +++ b/src/people/utils/filterPeople.ts @@ -1,4 +1,4 @@ -import { Person } from 'store/main'; +import { Person } from 'store/interface'; interface CodingLanguage { [language: string]: boolean; diff --git a/src/people/widgetViews/UserTicketsView.tsx b/src/people/widgetViews/UserTicketsView.tsx index f26aaa80..df07d379 100644 --- a/src/people/widgetViews/UserTicketsView.tsx +++ b/src/people/widgetViews/UserTicketsView.tsx @@ -8,7 +8,7 @@ import { Spacer } from 'people/main/Body'; import styled from 'styled-components'; import { BountyModal } from 'people/main/bountyModal/BountyModal'; import PageLoadSpinner from 'people/utils/PageLoadSpinner'; -import { Person } from 'store/main'; +import { Person } from 'store/interface'; import PopoverCheckbox from 'pages/people/tabs/popoverCheckboxStyles'; import history from '../../config/history'; import { colors } from '../../config/colors'; diff --git a/src/people/widgetViews/WidgetSwitchViewer.tsx b/src/people/widgetViews/WidgetSwitchViewer.tsx index 44516bf2..91fafb6a 100644 --- a/src/people/widgetViews/WidgetSwitchViewer.tsx +++ b/src/people/widgetViews/WidgetSwitchViewer.tsx @@ -2,7 +2,7 @@ import React, { useState } from 'react'; import styled from 'styled-components'; import { observer } from 'mobx-react-lite'; import { useIsMobile } from 'hooks/uiHooks'; -import { queryLimit } from 'store/main'; +import { queryLimit } from 'store/interface'; import { Spacer } from '../main/Body'; import NoResults from '../utils/NoResults'; import { uiStore } from '../../store/ui'; diff --git a/src/people/widgetViews/WorkspaceDetails.tsx b/src/people/widgetViews/WorkspaceDetails.tsx index 0780c91f..dc37ee83 100644 --- a/src/people/widgetViews/WorkspaceDetails.tsx +++ b/src/people/widgetViews/WorkspaceDetails.tsx @@ -15,7 +15,7 @@ import { WorkspaceBudget, PaymentHistory, Person -} from 'store/main'; +} from 'store/interface'; import MaterialIcon from '@material/react-material-icon'; import { Route, Router, Switch, useRouteMatch } from 'react-router-dom'; import { satToUsd, userHasRole } from 'helpers'; diff --git a/src/people/widgetViews/WorkspaceFeature.tsx b/src/people/widgetViews/WorkspaceFeature.tsx new file mode 100644 index 00000000..0f4445f8 --- /dev/null +++ b/src/people/widgetViews/WorkspaceFeature.tsx @@ -0,0 +1,163 @@ +import { EuiGlobalToastList, EuiLoadingSpinner } from '@elastic/eui'; +import { + Body, + FeatureBody, + FeatureLabel, + FeatureName, + Leftheader, + Header, + HeaderWrap, + DataWrap, + FieldWrap, + Label, + Data, + OptionsWrap, + TextArea +} from 'pages/tickets/style'; +import React, { useCallback, useEffect, useState } from 'react'; +import { useParams } from 'react-router-dom'; +import { useStores } from 'store'; +import { Feature } from 'store/interface'; +import MaterialIcon from '@material/react-material-icon'; +import { ActionButton, ButtonWrap } from './workspace/style'; + +const WorkspaceFeature = () => { + const { main, ui } = useStores(); + const { feature_uuid } = useParams<{ feature_uuid: string }>(); + const [featureData, setFeatureData] = useState(); + const [loading, setLoading] = useState(true); + const [displayArchitecture, setDidplayArchitecture] = useState(false); + const [editArchitecture, setEditArchitecture] = useState(false); + const [architecture, setArchitecture] = useState(featureData?.architecture); + + const getFeatureData = useCallback(async () => { + if (!feature_uuid) return; + const featureData = await main.getFeaturesByUuid(feature_uuid); + if (!featureData) return; + setFeatureData(featureData); + + setLoading(false); + }, [feature_uuid, main]); + + useEffect(() => { + getFeatureData(); + }, [getFeatureData]); + + const toastsEl = ( + ui.setToasts([])} + toastLifeTimeMs={3000} + /> + ); + + if (loading) { + return ( + + + + ); + } + + const editArchitectureActions = () => { + setEditArchitecture(!editArchitecture); + setDidplayArchitecture(false); + }; + + const architectureChange = (e: React.ChangeEvent) => { + const newValue = e.target.value; + if (newValue.length) { + setArchitecture(newValue); + } + }; + + const submitArchitecture = async () => { + const body = { + architecture: architecture ?? '', + uuid: featureData?.uuid ?? '', + workspace_uuid: featureData?.workspace_uuid ?? '' + }; + await main.addWorkspaceFeature(body); + await getFeatureData(); + setEditArchitecture(false); + }; + + return ( + !loading && ( + + +
    + + + {featureData?.name} + + +
    +
    + + + + + + setDidplayArchitecture(!displayArchitecture)} + data-testid="architecture-option-btn" + /> + + + {!editArchitecture && ( +
    ') + : 'No architecture yet' + }} + /> + )} + + {editArchitecture && ( + <> +