Browse Source

Merge pull request 'staging' (#71) from staging into master

Reviewed-on: ordo/adw-frontend#71
pull/2/head
ibnu 1 year ago
parent
commit
9fe1bae0be
  1. 57
      cypress/e2e/addProject.cy.js
  2. 9
      cypress/e2e/tests/gantt-duration-edit.cy.js
  3. 81
      src/containers/DefaultLayout/DefaultLayout.js
  4. 148
      src/views/SimproV2/CreatedProyek/ImportActivity/index.js

57
cypress/e2e/addProject.cy.js

@ -0,0 +1,57 @@
describe("Test a page", () => {
beforeEach(() => {
cy.login("admin", "1nt3gr4s14");
cy.url({ timeout: 20000 }).should("include", "/dashboard");
cy.visit("http://localhost:3000/#/projects");
});
it("Add project normal case", () => {
cy.intercept('GET', 'http://localhost/adw-backend/api/currency/list').as('getCurrency');
cy.intercept('GET', 'http://localhost/adw-backend/api/project-type/list').as('getType');
cy.intercept('GET', 'http://localhost/adw-backend/api/divisi/list').as('getDivisi');
cy.intercept('GET', 'http://localhost/adw-backend/api/project-phase/list').as('getPhase');
cy.intercept('GET', 'http://localhost/adw-backend/api/human-resource/list').as('getHr');
cy.get('[style="background: rgb(76, 175, 80); color: rgb(255, 255, 255);"]').click();
cy.get(':nth-child(2) > :nth-child(1) > .form-group > .form-control').type('Automated Test');
cy.get(':nth-child(2) > :nth-child(2) > .form-group > .form-control').type('AT');
cy.wait("@getType").then((xhr) => {
cy.get('#rc_select_1').type('template detail{enter}');
});
cy.wait("@getHr").then((xhr) => {
cy.get('#rc_select_2').type('admin adw{enter}');
});
cy.get(':nth-child(2) > .form-group > .ant-picker > .ant-picker-input > input').click();
cy.contains('td[title="2023-08-04"].ant-picker-cell', '4').click();
cy.get(':nth-child(5) > :nth-child(1) > .form-group > .form-control').type('Indramayu');
cy.get(':nth-child(5) > :nth-child(2) > .form-group > .form-control').type('Integrasia Utama');
cy.wait("@getCurrency").then((xhr) => {
cy.get('.col-md-4 > .ant-select > .ant-select-selector').click();
cy.get('[title="USD"] > .ant-select-item-option-content').click();
cy.get('.col-md-8 > .form-control').type(20000);
});
cy.get(':nth-child(6) > :nth-child(2) > .form-group > .form-control').type('Implement Automated Testing For Development');
cy.wait("@getDivisi").then((xhr) => {
cy.get('#rc_select_4').click();
cy.get('[title=" Construction"] > .ant-select-item-option-content').click();
});
cy.wait("@getPhase").then((xhr) => {
cy.get('#rc_select_5').click();
cy.get('.ant-select-item-option-content').contains('Inisiasi').click();
});
cy.get('#rc_select_6').click();
cy.get('.ant-select-item-option-content').contains('On budget').click();
cy.get('.btn-primary').click();
});
});

9
cypress/e2e/tests/gantt-duration-edit.cy.js

@ -1,9 +0,0 @@
describe("Test a page", () => {
beforeEach(() => {
cy.visit("http://localhost:3000/#/login");
});
it("should visit the authenticated page", () => {
// Continue with your assertions or other test steps
});
});

81
src/containers/DefaultLayout/DefaultLayout.js

@ -17,6 +17,7 @@ import {
AppBreadcrumb2 as AppBreadcrumb,
AppSidebarNav2 as AppSidebarNav,
} from '@coreui/react';
import LayoutHelper from '../../../node_modules/@coreui/react/lib/Shared/layout/layout';
import navigation from '../../_nav';
import routes from '../../routes';
import { emptyConstants } from '../../const/MapConst.js';
@ -44,6 +45,7 @@ class DefaultLayout extends Component {
routes2: routes,
finalRoutes: [],
breadrCrumbReady: false,
minimized: true
}
}
@ -70,7 +72,10 @@ class DefaultLayout extends Component {
}
}
toggleMinimized = () => {
this.setState((prevState) => ({ minimized: !prevState.minimized }));
LayoutHelper.sidebarToggle(!this.state.minimized);
};
setFinalRoutes = () => {
const { routes2 } = this.state;
@ -229,52 +234,54 @@ class DefaultLayout extends Component {
}
render() {
const { location } = this.props;
const { pathname } = location;
let renderSidebar = false
const { location } = this.props;
const { pathname } = location;
let renderSidebar = false
if (pathname.includes("/dashboard-project")) {
// Remove the base URL and hash
const path = pathname.replace("/dashboard-project/", "");
if (pathname.includes("/dashboard-project")) {
// Remove the base URL and hash
const path = pathname.replace("/dashboard-project/", "");
// Split the remaining path by "/"
const parts = path.split("/");
if (parts[2] == "1") {
renderSidebar = true
}
}
// Split the remaining path by "/"
const parts = path.split("/");
if (parts[2] == "1") {
renderSidebar = true
}
}
return (
<div className="app">
<div className="app-body">
{!window.location.href.includes("dashboard-project") || renderSidebar ? (
<AppSidebar minimized={true} fixed display="lg">
{/* <div class="sidebar-header">
{!window.location.href.includes("dashboard-project") || renderSidebar ? (
<AppSidebar minimized={this.state.minimized} fixed display="lg">
{/* <div class="sidebar-header">
<Suspense fallback={this.loading()}>
<DefaultHeader history={this.props.history} onLogout={e => this.signOut(e)} />
</Suspense>
</div> */}
<hr />
<AppSidebarHeader />
<AppSidebarForm />
<Suspense>
{this.getMenu()}
</Suspense>
<AppSidebarFooter />
<UncontrolledDropdown direction="down">
<DropdownToggle nav>
<i className="nav-icon fa fa-user-circle"></i> {localStorage.getItem('user_name')}
</DropdownToggle>
<DropdownMenu right>
<DropdownItem color="primary" size="sm" onClick={() => handleChangeLng("id")}>ID</DropdownItem>
<DropdownItem color="success" size="sm" onClick={() => handleChangeLng("en")}>EN</DropdownItem>
<DropdownItem href="#/settings"><i className="fa fa-user"></i>Profile</DropdownItem>
<DropdownItem onClick={e => this.signOut(e)}><i className="fa fa-sign-out"></i> Logout</DropdownItem>
</DropdownMenu>
</UncontrolledDropdown>
<AppSidebarMinimizer />
</AppSidebar>
) : null }
<hr />
<AppSidebarHeader />
<AppSidebarForm />
<Suspense>
{this.getMenu()}
</Suspense>
<AppSidebarFooter />
{this.state.minimized ? null :
<UncontrolledDropdown direction="down">
<DropdownToggle nav>
<i className="nav-icon fa fa-user-circle"></i> {localStorage.getItem('user_name')}
</DropdownToggle>
<DropdownMenu right>
<DropdownItem color="primary" size="sm" onClick={() => handleChangeLng("id")}>ID</DropdownItem>
<DropdownItem color="success" size="sm" onClick={() => handleChangeLng("en")}>EN</DropdownItem>
<DropdownItem href="#/settings"><i className="fa fa-user"></i>Profile</DropdownItem>
<DropdownItem onClick={e => this.signOut(e)}><i className="fa fa-sign-out"></i> Logout</DropdownItem>
</DropdownMenu>
</UncontrolledDropdown>}
<button className='sidebar-minimizer mt-auto' type='button' onClick={this.toggleMinimized}>
</button>
</AppSidebar>
) : null}
<main className="main">
{this.state.breadrCrumbReady ? this.getAppBreadcrumb() : null}
<Container fluid>

148
src/views/SimproV2/CreatedProyek/ImportActivity/index.js

@ -2,9 +2,9 @@ import React, { useState, useEffect, useMemo } from 'react';
import axios from "../../../../const/interceptorApi"
import { Card, CardBody, CardHeader, Col, Row, Input } from 'reactstrap';
import { NotificationContainer, NotificationManager } from 'react-notifications';
import { Button, Table, Form, Upload, Tooltip, Alert, Spin } from 'antd';
import { Button, Table, Form, Upload, Tooltip, Alert, Spin } from 'antd';
import { InboxOutlined, UploadOutlined } from '@ant-design/icons';
import {OutTable, ExcelRenderer} from 'react-excel-renderer';
import { OutTable, ExcelRenderer } from 'react-excel-renderer';
import './table.css';
import { BASE_OSPRO, ASSIGN_HR_PROJECT_SEARCH } from '../../../../const/ApiConst';
import { Prompt } from 'react-router-dom';
@ -89,60 +89,60 @@ const ImportActivity = ({ params }) => {
const pageName = params.name;
const [dataTable, setDatatable] = useState([])
const [dataUserToProject, setdataUserToProject] = useState([])
const [dataUserToProject, setdataUserToProject] = useState([])
//
const [isMovePage, setIsMovePage] = useState(false);
const [isPreview, setIsPreview] = useState(false);
useEffect(() => {
useEffect(() => {
getDataAssignHr();
}, [])
const getDataAssignHr = async () => {
const getDataAssignHr = async () => {
let url = window.location.href;
let urlSplitted = url.split('/')
const payload = {
"paging": {
"start": 0,
"length": -1
},
"columns": [
{ "name": "name", "logic_operator": "ilike", "value": "", "table_name": "m_users" },
{ "name": "proyek_id", "logic_operator": "=", "value": urlSplitted[6] }
],
"joins": [
{ "name": "m_users", "column_join": "user_id", "column_results": ["name", "ktp_number"] },
{ "name": "m_role_proyek", "column_join": "project_role", "column_results": ["name"] },
],
"orders": {
"columns": [
"id"
],
"ascending": false
}
}
const URL = ASSIGN_HR_PROJECT_SEARCH
const result = await axios
.post(URL, payload, HEADER)
.then(res => res)
.catch((error) => error.response);
if (result && result.data && result.data.code == 200) {
let dataRes = result.data.data || []
setdataUserToProject(dataRes);
} else {
NotificationManager.error('Gagal Mengambil Data!!', 'Failed');
}
}
const payload = {
"paging": {
"start": 0,
"length": -1
},
"columns": [
{ "name": "name", "logic_operator": "ilike", "value": "", "table_name": "m_users" },
{ "name": "proyek_id", "logic_operator": "=", "value": urlSplitted[6] }
],
"joins": [
{ "name": "m_users", "column_join": "user_id", "column_results": ["name", "ktp_number"] },
{ "name": "m_role_proyek", "column_join": "project_role", "column_results": ["name"] },
],
"orders": {
"columns": [
"id"
],
"ascending": false
}
}
const URL = ASSIGN_HR_PROJECT_SEARCH
const result = await axios
.post(URL, payload, HEADER)
.then(res => res)
.catch((error) => error.response);
if (result && result.data && result.data.code == 200) {
let dataRes = result.data.data || []
setdataUserToProject(dataRes);
} else {
NotificationManager.error('Gagal Mengambil Data!!', 'Failed');
}
}
const fileHandler = (file) => {
setIsMovePage(true);
if(file.name.slice(file.name.lastIndexOf('.')+1) === "xlsx"){
if (file.name.slice(file.name.lastIndexOf('.') + 1) === "xlsx") {
// NotificationManager.info('Loading...',' ');
setTimeout(() => {
setTimeout(() => {
previewHandler(file);
setIsMovePage(false);
}, 5000);
}, 5000);
} else {
NotificationManager.error('file harus dalam format .xlsx', 'Failed');
}
@ -156,7 +156,7 @@ const ImportActivity = ({ params }) => {
let dataMapped = []
ExcelRenderer(fileObj, (err, resp) => {
if(err){
if (err) {
console.log(err)
errorHandler()
} else {
@ -167,7 +167,7 @@ const ImportActivity = ({ params }) => {
return el.length > 0;
});
for(let i = 5; i < rows.length; i++){
for (let i = 5; i < rows.length; i++) {
let extractedRow = {}
for (var prop in columnToIndexs) {
@ -175,27 +175,33 @@ const ImportActivity = ({ params }) => {
let columnData = rows[i][columnToIndexs[prop]]
// remove leading whitespace
if(typeof(columnData) == 'string') {
if (typeof (columnData) == 'string') {
columnData = columnData.trim().replace(/&nbsp;/g, '').replace(/<[^\/>][^>]*><\/[^>]+>/g, "")
}
if(["nik"].includes(prop)){
if(columnData){
let index = dataUserToProject.findIndex((x) => columnData == x.join_first_ktp_number);
if(index >= 0) {
columnData = dataUserToProject[index].join_first_ktp_number;
} else {
columnData = '';
}
}
}
if(prop == 'weight'){
if (columnData == null) {
columnData = 0;
}
if (["nik"].includes(prop)) {
if (columnData) {
let index = dataUserToProject.findIndex((x) => columnData == x.join_first_ktp_number);
if (index >= 0) {
columnData = dataUserToProject[index].join_first_ktp_number;
} else {
columnData = '';
}
}
}
if (prop == 'weight') {
if (columnData == null) {
columnData = 0;
}
columnData = columnData * 100
}
if (prop == 'duration') {
if (columnData == null) {
columnData = 0;
}
}
extractedRow[prop] = columnData
@ -232,13 +238,13 @@ const ImportActivity = ({ params }) => {
console.log(result)
if (result.data.code == 200) {
const timestamp = Date.now();
const newTimestamp = timestamp + 60000;
const timestamp = Date.now();
const newTimestamp = timestamp + 60000;
window.location = urlSplitted[0] + '//' + urlSplitted[2] + `/#/projects/` + ganttId + '/' + result.data.projectId + '/' + newTimestamp + '/gantt'
}
setIsMovePage(true);
setIsPreview(true);
setIsPreview(true);
}
const columns = [
@ -268,7 +274,7 @@ const ImportActivity = ({ params }) => {
key: 'name',
render: (text, record) => {
let prepend = ""
for(let i = 1; i < record.level; i++) {
for (let i = 1; i < record.level; i++) {
prepend = prepend + "--"
}
@ -329,7 +335,7 @@ const ImportActivity = ({ params }) => {
listType="text"
accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
maxCount={1}
beforeUpload={(file)=> fileHandler(file)}
beforeUpload={(file) => fileHandler(file)}
showUploadList={false}
>
<Button icon={<UploadOutlined />}>Import Excel</Button>
@ -338,11 +344,11 @@ const ImportActivity = ({ params }) => {
</Form.Item>
</Form>
</Col>
<Col span={2} style={{display: 'flex', justifyContent: 'flex-end'}}>
<Col span={2} style={{ display: 'flex', justifyContent: 'flex-end' }}>
<Button
style={{ marginLeft: "5px", marginRight: "10px" }}
disabled={dataTable.length > 0 ? false : true}
onClick={(e)=> saveHandler(e)}
onClick={(e) => saveHandler(e)}
>
<i className="fa fa-save" style={{ marginRight: "5px" }}></i> Save
</Button>
@ -356,7 +362,7 @@ const ImportActivity = ({ params }) => {
<CardBody>
<Spin tip="Loading...">
<Table
rowClassName={(record, index) => index % 2 == 0 ? 'table-row-light' : 'table-row-dark'}
rowClassName={(record, index) => index % 2 == 0 ? 'table-row-light' : 'table-row-dark'}
dataSource={dataTable}
columns={columns}
pagination={false}
@ -397,7 +403,7 @@ const ImportActivity = ({ params }) => {
listType="text"
accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
maxCount={1}
beforeUpload={(file)=> fileHandler(file)}
beforeUpload={(file) => fileHandler(file)}
showUploadList={false}
>
<Button icon={<UploadOutlined />}>Import Excel</Button>
@ -406,11 +412,11 @@ const ImportActivity = ({ params }) => {
</Form.Item>
</Form>
</Col>
<Col span={2} style={{display: 'flex', justifyContent: 'flex-end'}}>
<Col span={2} style={{ display: 'flex', justifyContent: 'flex-end' }}>
<Button
style={{ marginLeft: "5px", marginRight: "10px" }}
disabled={dataTable.length > 0 ? false : true}
onClick={(e)=> saveHandler(e)}
onClick={(e) => saveHandler(e)}
>
<i className="fa fa-save" style={{ marginRight: "5px" }}></i> Save
</Button>
@ -423,7 +429,7 @@ const ImportActivity = ({ params }) => {
</CardHeader>
<CardBody>
<Table
rowClassName={(record, index) => index % 2 == 0 ? 'table-row-light' : 'table-row-dark'}
rowClassName={(record, index) => index % 2 == 0 ? 'table-row-light' : 'table-row-dark'}
dataSource={dataTable}
columns={columns}
pagination={false}

Loading…
Cancel
Save