Skip to content

Commit

Permalink
Merge pull request stakwork#541 from Ekep-Obasi/feat/add-phase-to-fea…
Browse files Browse the repository at this point in the history
…tures

Add Phases to Feature [feature-add-phases-to-feature]
  • Loading branch information
fvalentiner authored May 25, 2024
2 parents 1a228c7 + 2a0a729 commit c4be3d3
Show file tree
Hide file tree
Showing 8 changed files with 732 additions and 20 deletions.
82 changes: 82 additions & 0 deletions cypress/e2e/59_updateWorkspaceFeaturePhase.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
describe('Workspace Phasing Feature Tests', () => {
it('Create, Update and Delete Feature Phase functionality', () => {
cy.login('alice');
cy.wait(1000);

const workspaceName = 'Dark Mode 500';

const workspace = {
loggedInAs: 'alice',
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(3000);

cy.contains(workspace.name).contains('Manage').click();
cy.wait(1000);

cy.get('[data-testid="mission-link"]')
.invoke('show')
.then(($link: JQuery<HTMLElement>) => {
const modifiedHref = $link.attr('href');
cy.wrap($link).invoke('removeAttr', 'target');
cy.wrap($link).click();
cy.url().should('include', modifiedHref);
});
cy.wait(1000);

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');
cy.wait(1000);

cy.get('[data-testid="phase-add-btn"]').click();
cy.wait(1000);

const newPhase = 'Bounties Super Admin';

cy.get('[data-testid="add-phase-input"]').type(newPhase);
cy.contains('Save').click();
cy.wait(1000);

cy.contains(newPhase).should('exist');
cy.wait(1000);

cy.get('[data-testid="phase-option-btn"]').click();
cy.wait(500);
cy.get('[data-testid="phase-edit-btn"]').click();
cy.wait(1000);

const editedPhase = 'Super Admin';
cy.get('[data-testid="edit-phase-input"]').clear().type(editedPhase);
cy.contains('Save').click();
cy.wait(1000);

cy.contains(editedPhase).should('exist');
cy.wait(1000);

cy.get('[data-testid="phase-option-btn"]').click();
cy.wait(500);
cy.get('[data-testid="phase-edit-btn"]').click();
cy.wait(1000);
cy.contains('Delete').click();
cy.wait(1000);
cy.get('[data-testid="confirm-delete-phase"]').click();
cy.wait(1000);

cy.contains(editedPhase).should('not.exist');

cy.logout('alice');
});
});
69 changes: 51 additions & 18 deletions src/people/widgetViews/WorkspaceFeature.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ import {
ButtonGroup,
StoryButtonWrap
} from './workspace/style';
import WorkspacePhasingTabs from './workspace/WorkspacePhase';
import { Phase, Toast } from './workspace/interface';

interface WSEditableFieldProps {
label: string;
Expand Down Expand Up @@ -112,9 +114,10 @@ const WorkspaceEditableField = ({

// Replace the markdown image syntax with HTML <img> tag
return input
.replace(imageMarkdownRegex, (match: string, p1: string) => {
return `<img src="${p1}" alt="Uploaded Image" />`;
})
.replace(
imageMarkdownRegex,
(match: string, p1: string) => `<img src="${p1}" alt="Uploaded Image" />`
)
.replace(/\n/g, '<br/>');
};

Expand Down Expand Up @@ -255,7 +258,7 @@ const UserStoryModal: React.FC<UserStoryModalProps> = ({
);
};

const WorkspaceFeature: React.FC = () => {
const WorkspaceFeature = () => {
const { main, ui } = useStores();
const { feature_uuid } = useParams<{ feature_uuid: string }>();
const [featureData, setFeatureData] = useState<Feature | null>(null);
Expand All @@ -264,6 +267,7 @@ const WorkspaceFeature: React.FC = () => {
const [userStoryPriority, setUserStoryPriority] = useState<number>(0);
const [featureStories, setFeatureStories] = useState<FeatureStory[] | undefined>([]);
const [brief, setBrief] = useState<string>('');
const [phases, setPhases] = useState<Phase[]>([]);
const [architecture, setArchitecture] = useState<string>('');
const [requirements, setRequirements] = useState<string>('');
const [editBrief, setEditBrief] = useState<boolean>(false);
Expand All @@ -277,8 +281,9 @@ const WorkspaceFeature: React.FC = () => {
);
const [modalOpen, setModalOpen] = useState<boolean>(false);
const [editUserStory, setEditUserStory] = useState<FeatureStory>();
const [toasts, setToasts] = useState<Toast[]>([]);

const getFeatureData = useCallback(async (): Promise<void> => {
const getFeatureData = useCallback(async () => {
if (!feature_uuid) return;
const data = await main.getFeaturesByUuid(feature_uuid);

Expand All @@ -288,7 +293,18 @@ const WorkspaceFeature: React.FC = () => {
setArchitecture(data.architecture);
setRequirements(data.requirements);
}
setLoading(false);

return data;
}, [feature_uuid, main]);

const getFeaturePhaseData = useCallback(async () => {
if (!feature_uuid) return;
const phases = await main.getFeaturePhases(feature_uuid);

if (phases) {
setPhases(phases);
}
return phases;
}, [feature_uuid, main]);

const getFeatureStoryData = useCallback(async (): Promise<void> => {
Expand All @@ -302,9 +318,10 @@ const WorkspaceFeature: React.FC = () => {
}, [feature_uuid, main]);

useEffect(() => {
getFeatureData();
getFeatureStoryData();
}, [getFeatureData, getFeatureStoryData]);
Promise.all([getFeatureData(), getFeaturePhaseData(), getFeatureStoryData()]).finally(() => {
setLoading(false);
});
}, [getFeatureData, getFeaturePhaseData, getFeatureStoryData]);

const submitField = async (
field: string,
Expand Down Expand Up @@ -398,9 +415,21 @@ const WorkspaceFeature: React.FC = () => {
deleteHandler();
};

const updateFeaturePhase = (reason: any, title: string, message: string) => {
getFeaturePhaseData();
setToasts([
{
id: '1',
title,
color: (reason === 'success' ? 'sucess' : 'danger') as any,
text: message
}
]);
};

const toastsEl = (
<EuiGlobalToastList
toasts={ui.toasts}
toasts={toasts}
dismissToast={() => ui.setToasts([])}
toastLifeTimeMs={3000}
/>
Expand Down Expand Up @@ -482,7 +511,6 @@ const WorkspaceFeature: React.FC = () => {
</UserStoryFields>
</Data>
</FieldWrap>

<WorkspaceEditableField
label="Feature Brief"
value={brief}
Expand Down Expand Up @@ -522,15 +550,20 @@ const WorkspaceFeature: React.FC = () => {
onSubmit={() => submitField('architecture', architecture, setEditArchitecture)}
main={main}
/>
<WorkspacePhasingTabs
featureId={feature_uuid}
phases={phases}
updateFeaturePhase={updateFeaturePhase}
/>
<UserStoryModal
open={modalOpen}
storyDescription={editUserStory?.description as string}
handleClose={handleModalClose}
handleSave={handleModalSave}
handleDelete={handleModalDelete}
/>
</FeatureDataWrap>
{toastsEl}
<UserStoryModal
open={modalOpen}
storyDescription={editUserStory?.description as string}
handleClose={handleModalClose}
handleSave={handleModalSave}
handleDelete={handleModalDelete}
/>
</FeatureBody>
);
};
Expand Down
2 changes: 1 addition & 1 deletion src/people/widgetViews/WorkspaceMission.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -702,7 +702,7 @@ const WorkspaceMission = () => {
<a
href={workspaceData?.schematic_url}
target="_blank"
rel="noopener"
rel="noopener noreferrer"
data-testid="schematic-url"
style={{ marginLeft: '0.5rem' }}
>
Expand Down
Loading

0 comments on commit c4be3d3

Please sign in to comment.