@ecoba-vn/tender-feature
Version:
1,197 lines (1,170 loc) • 183 kB
JavaScript
/* Version: 1.1.17 - May 26, 2023 09:39:50 */
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var clientCore = require('@ecoba-vn/client-core');
var jsxRuntime = require('react/jsx-runtime');
var React = require('react');
var reactRouterDom = require('react-router-dom');
var styles = require('@material-ui/core/styles');
var core = require('@material-ui/core');
var clientSharedUi = require('@ecoba-vn/client-shared-ui');
var reactFontawesome = require('@fortawesome/react-fontawesome');
var clsx = require('clsx');
var HotTable = require('@handsontable/react');
var registry = require('handsontable/registry');
require('handsontable/dist/handsontable.full.min.css');
var materialUiDropzone = require('material-ui-dropzone');
var xlsx = require('xlsx');
var styled = require('styled-components');
var lab = require('@material-ui/lab');
var colors = require('@material-ui/core/colors');
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
function _interopNamespace(e) {
if (e && e.__esModule) return e;
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n["default"] = e;
return Object.freeze(n);
}
var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
var clsx__default = /*#__PURE__*/_interopDefaultLegacy(clsx);
var HotTable__default = /*#__PURE__*/_interopDefaultLegacy(HotTable);
var xlsx__namespace = /*#__PURE__*/_interopNamespace(xlsx);
var styled__default = /*#__PURE__*/_interopDefaultLegacy(styled);
/******************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
function __awaiter(thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
}
const baseUrl$d = `${process.env.REACT_APP_API_HOSTNAME}`;
const MOD_ROLE$1 = "MOD_ROLE";
const PLANNER_ROLE = "PLANNER_ROLE";
function checkPermission$5() {
return __awaiter(this, void 0, void 0, function* () {
try {
const res = yield clientCore.axiosBuilder
.getInstance(baseUrl$d)
.get("api/v1/td/user-roles/users/check-permission");
return res.data;
}
catch (_a) {
return false;
}
});
}
function checkModRolePermission$1() {
return __awaiter(this, void 0, void 0, function* () {
try {
const res = yield clientCore.axiosBuilder
.getInstance(baseUrl$d)
.get(`api/v1/td/user-roles/users/check-role-permission?role=${MOD_ROLE$1}`);
return res.data;
}
catch (_a) {
return false;
}
});
}
function checkPlannerRolePermission() {
return __awaiter(this, void 0, void 0, function* () {
try {
const res = yield clientCore.axiosBuilder
.getInstance(baseUrl$d)
.get(`api/v1/td/user-roles/users/check-role-permission?role=${PLANNER_ROLE}`);
return res.data;
}
catch (_a) {
return false;
}
});
}
function getAll$7() {
return __awaiter(this, void 0, void 0, function* () {
const res = yield clientCore.axiosBuilder.getInstance(baseUrl$d).get("api/v1/u/users");
return res.data;
});
}
const userService = {
getAll: getAll$7,
checkPermission: checkPermission$5,
checkModRolePermission: checkModRolePermission$1,
checkPlannerRolePermission,
};
const baseUrl$c = `${process.env.REACT_APP_API_HOSTNAME}`;
function getAll$6() {
return __awaiter(this, void 0, void 0, function* () {
const res = yield clientCore.axiosBuilder.getInstance(baseUrl$c).get("api/v1/td/projects");
return res.data;
});
}
function get$1(projectCode) {
return __awaiter(this, void 0, void 0, function* () {
const res = yield clientCore.axiosBuilder
.getInstance(baseUrl$c)
.get(`api/v1/td/projects/${projectCode}`);
return res.data;
});
}
function me() {
return __awaiter(this, void 0, void 0, function* () {
const res = yield clientCore.axiosBuilder
.getInstance(baseUrl$c)
.get(`api/v1/td/projects/me`);
return res.data;
});
}
function create$1(model) {
return __awaiter(this, void 0, void 0, function* () {
const res = yield clientCore.axiosBuilder
.getInstance(baseUrl$c)
.post(`api/v1/td/projects`, model);
return res.data;
});
}
function update(projectCode, model) {
return __awaiter(this, void 0, void 0, function* () {
const res = yield clientCore.axiosBuilder
.getInstance(baseUrl$c)
.put(`api/v1/td/projects/${projectCode}`, model);
return res.data;
});
}
function close(projectCode) {
return __awaiter(this, void 0, void 0, function* () {
const res = yield clientCore.axiosBuilder
.getInstance(baseUrl$c)
.put(`api/v1/td/projects/${projectCode}/close`);
return res.data;
});
}
const projectService = {
getAll: getAll$6,
get: get$1,
me,
create: create$1,
update,
close,
};
const baseUrl$b = `${process.env.REACT_APP_API_HOSTNAME}`;
const MOD_ROLE = "MOD_ROLE";
const ELEMENT = "ELEMENT";
const COMPONENT = "COMPONENT";
const ACTIVITY = "ACTIVITY";
const MAPPING = "MAPPING";
const BILL = "BILL";
const SHORTCUT = "SHORTCUT";
const PERMISSION_BLOCK = 0;
const PERMISSION_VIEW = 1;
const PERMISSION_EDIT = 2;
const roles = [
{
name: ELEMENT,
description: "WBS",
},
{
name: COMPONENT,
description: "Cấu kiện",
},
{
name: ACTIVITY,
description: "Khối lượng",
},
{
name: MAPPING,
description: "Mapping",
},
{
name: BILL,
description: "BOQ",
},
{
name: SHORTCUT,
description: "ID code",
},
];
const PermissionsValue = [
{
name: "---",
value: PERMISSION_BLOCK,
},
{
name: "Xem",
value: PERMISSION_VIEW,
},
{
name: "Sửa",
value: PERMISSION_EDIT,
},
];
function checkModRolePermission() {
return __awaiter(this, void 0, void 0, function* () {
const res = yield clientCore.axiosBuilder
.getInstance(baseUrl$b)
.get(`api/v1/td/user-roles/users/check-role-permission?role=${MOD_ROLE}`);
return res.data;
});
}
function getAll$5(projectCode) {
return __awaiter(this, void 0, void 0, function* () {
const res = yield clientCore.axiosBuilder
.getInstance(baseUrl$b)
.get(`api/v1/td/projects/${projectCode}/members`);
return res.data;
});
}
function createMember(projectCode, userNumber) {
return __awaiter(this, void 0, void 0, function* () {
const res = yield clientCore.axiosBuilder
.getInstance(baseUrl$b)
.post(`api/v1/td/projects/${projectCode}/members/${userNumber}`);
return res.data;
});
}
function removeMember(projectCode, userNumber) {
return __awaiter(this, void 0, void 0, function* () {
const res = yield clientCore.axiosBuilder
.getInstance(baseUrl$b)
.delete(`api/v1/td/projects/${projectCode}/members/${userNumber}`);
return res.data;
});
}
function copyRole(projectCode, fromUserNumber, toUserNumber) {
return __awaiter(this, void 0, void 0, function* () {
const res = yield clientCore.axiosBuilder
.getInstance(baseUrl$b)
.post(`api/v1/td/projects/${projectCode}/members/${fromUserNumber}/copy/${toUserNumber}`);
return res.data;
});
}
function modify(projectCode, userNumber, roleCode, permission) {
return __awaiter(this, void 0, void 0, function* () {
const res = yield clientCore.axiosBuilder
.getInstance(baseUrl$b)
.put(`api/v1/td/projects/${projectCode}/members/${userNumber}/modify?roleCode=${roleCode}&permissionValue=${permission}`);
return res.data;
});
}
const memberService = {
checkModRolePermission,
getAll: getAll$5,
createMember,
removeMember,
copyRole,
modify,
};
const useStyles$u = styles.makeStyles((theme) => core.createStyles({
root: {
width: "100%",
height: "100%",
overflowY: "auto",
padding: 16,
},
card: {
width: "100%",
},
bullet: {
display: "inline-block",
margin: "0 2px",
transform: "scale(0.8)",
},
title: {
fontSize: 14,
},
code: {
fontSize: "1.3rem",
fontWeight: 500,
},
pos: {
marginBottom: 12,
},
search: {
width: "100%",
position: "relative",
borderRadius: theme.shape.borderRadius,
border: "1px solid rgb(224,224,224)",
backgroundColor: "white",
},
searchIcon: {
padding: theme.spacing(0, 2),
height: "100%",
position: "absolute",
pointerEvents: "none",
display: "flex",
alignItems: "center",
justifyContent: "center",
},
wrapSearch: {
position: "relative",
display: "flex",
alignItems: "center",
gap: "10px",
width: "100%",
[theme.breakpoints.up("sm")]: {
width: "40%",
},
[theme.breakpoints.down("md")]: {
flexFlow: "row wrap",
},
margin: "auto",
},
inputRoot: {
color: "inherit",
},
inputInput: {
padding: theme.spacing(1, 1, 1, 0),
paddingLeft: `calc(1em + ${theme.spacing(4)}px)`,
transition: theme.transitions.create("width"),
width: "100%",
},
}));
const Projects$1 = function () {
const classes = useStyles$u();
const { setStatus, showAlert } = React__default["default"].useContext(clientCore.AppContext);
const [projects, setProjects] = React__default["default"].useState([]);
const [text, setText] = React__default["default"].useState("");
const [isMod, setMod] = React__default["default"].useState(false);
const refresh = () => __awaiter(this, void 0, void 0, function* () {
setStatus(true, "Đang tải dữ liệu ...");
try {
if (process.env.NODE_ENV === "production") {
setProjects(yield projectService.me());
}
if (process.env.NODE_ENV === "development" ||
process.env.REACT_APP_ENV === "Staging") {
setProjects(yield projectService.getAll());
}
}
catch (_a) {
showAlert("error", "Tải dữ liệu thất bại!");
}
finally {
setStatus(false, "");
}
});
React__default["default"].useEffect(() => {
refresh();
checkIsMod();
}, []);
const checkIsMod = () => __awaiter(this, void 0, void 0, function* () {
try {
setMod(yield memberService.checkModRolePermission());
}
catch (error) {
return false;
}
});
return (jsxRuntime.jsx("div", Object.assign({ className: classes.root }, { children: jsxRuntime.jsxs(core.Grid, Object.assign({ container: true, spacing: 2 }, { children: [jsxRuntime.jsx(core.Grid, Object.assign({ item: true, xs: 12 }, { children: jsxRuntime.jsxs("div", Object.assign({ className: classes.wrapSearch }, { children: [jsxRuntime.jsxs("div", Object.assign({ className: classes.search }, { children: [jsxRuntime.jsx("div", Object.assign({ className: classes.searchIcon }, { children: jsxRuntime.jsx(reactFontawesome.FontAwesomeIcon, { icon: "search" }, void 0) }), void 0), jsxRuntime.jsx(core.InputBase, { placeholder: "T\u00ECm ki\u1EBFm ...", classes: {
root: classes.inputRoot,
input: classes.inputInput,
}, value: text, onChange: (e) => {
setText(e.currentTarget.value);
}, inputProps: { "aria-label": "search" } }, void 0)] }), void 0), isMod && (jsxRuntime.jsx(reactRouterDom.Link, Object.assign({ to: `/tender/mod`, style: { textDecoration: "none" } }, { children: jsxRuntime.jsx(clientSharedUi.IconButton, { icon: "user-cog", text: "Admin", variant: "contained" }, void 0) }), void 0))] }), void 0) }), void 0), projects
.filter((x) => x.projectCode.toUpperCase().includes(text.toUpperCase()) ||
x.projectName.toUpperCase().includes(text.toUpperCase()))
.map((p) => (jsxRuntime.jsx(core.Grid, Object.assign({ item: true, xs: 12, md: 4, lg: 3 }, { children: jsxRuntime.jsxs(core.Card, Object.assign({ className: classes.card, variant: "outlined" }, { children: [jsxRuntime.jsxs(core.CardContent, { children: [jsxRuntime.jsx(core.Typography, Object.assign({ className: classes.title, color: "textSecondary", gutterBottom: true }, { children: p.projectName }), void 0), jsxRuntime.jsx(core.Typography, Object.assign({ variant: "h5", component: "h2", className: classes.code }, { children: p.projectCode }), void 0)] }, void 0), jsxRuntime.jsx(core.CardActions, { children: jsxRuntime.jsxs(core.Grid, Object.assign({ container: true, spacing: 1 }, { children: [jsxRuntime.jsx(core.Grid, Object.assign({ item: true }, { children: jsxRuntime.jsx(reactRouterDom.Link, Object.assign({ to: `/tender/projects/${p.projectCode}/sale`, style: { textDecoration: "none" } }, { children: jsxRuntime.jsx(clientSharedUi.IconButton, { text: "H\u1EE3p \u0111\u1ED3ng A", icon: "cart-plus" }, void 0) }), void 0) }), void 0), jsxRuntime.jsx(core.Grid, Object.assign({ item: true }, { children: jsxRuntime.jsx(reactRouterDom.Link, Object.assign({ to: `/tender/projects/${p.projectCode}/scope/elements/${p.projectCode}`, style: { textDecoration: "none" } }, { children: jsxRuntime.jsx(clientSharedUi.IconButton, { text: "Ph\u1EA1m vi", icon: "qrcode" }, void 0) }), void 0) }), void 0), jsxRuntime.jsx(core.Grid, Object.assign({ item: true }, { children: jsxRuntime.jsx(reactRouterDom.Link, Object.assign({ to: `/tender/projects/${p.projectCode}/quantity`, style: { textDecoration: "none" } }, { children: jsxRuntime.jsx(clientSharedUi.IconButton, { text: "Kh\u1ED1i l\u01B0\u1EE3ng", icon: "drafting-compass" }, void 0) }), void 0) }), void 0), jsxRuntime.jsx(core.Grid, Object.assign({ item: true }, { children: jsxRuntime.jsx(reactRouterDom.Link, Object.assign({ to: `/tender/projects/${p.projectCode}/norms`, style: { textDecoration: "none" } }, { children: jsxRuntime.jsx(clientSharedUi.IconButton, { text: "\u0110\u1ECBnh m\u1EE9c", icon: "sliders-h" }, void 0) }), void 0) }), void 0), jsxRuntime.jsx(core.Grid, Object.assign({ item: true }, { children: jsxRuntime.jsx(reactRouterDom.Link, Object.assign({ to: `/tender/projects/${p.projectCode}/reports`, style: { textDecoration: "none" } }, { children: jsxRuntime.jsx(clientSharedUi.IconButton, { text: "B\u00E1o c\u00E1o", icon: "file-alt" }, void 0) }), void 0) }), void 0), jsxRuntime.jsx(core.Grid, Object.assign({ item: true }, { children: jsxRuntime.jsx(reactRouterDom.Link, Object.assign({ to: `/tender/projects/${p.projectCode}/requests`, style: { textDecoration: "none" } }, { children: jsxRuntime.jsx(clientSharedUi.IconButton, { text: "Ph\u00EA duy\u1EC7t", icon: "thumbs-up" }, void 0) }), void 0) }), void 0), jsxRuntime.jsx(core.Grid, Object.assign({ item: true }, { children: jsxRuntime.jsx(reactRouterDom.Link, Object.assign({ to: `/tender/projects/${p.projectCode}/versions`, style: { textDecoration: "none" } }, { children: jsxRuntime.jsx(clientSharedUi.IconButton, { text: "Phi\u00EAn b\u1EA3n", icon: "code-branch" }, void 0) }), void 0) }), void 0)] }), void 0) }, void 0)] }), void 0) }), p.projectCode)))] }), void 0) }), void 0));
};
const useStyles$t = core.makeStyles(() => ({
root: {
display: "flex",
backgroundColor: "rgb(34,34,34)",
height: 32,
},
label: {
flexGrow: 1,
lineHeight: "32px",
paddingLeft: 16,
color: "white",
fontWeight: 600,
fontSize: "0.9rem",
},
nav: {
position: "relative",
minWidth: 80,
lineHeight: "32px",
textDecoration: "none",
textAlign: "center",
paddingLeft: 12,
paddingRight: 12,
color: "white",
fontWeight: 500,
borderLeft: "1px solid white",
cursor: "pointer",
"&:hover": {
backgroundColor: "#4c8beb",
},
},
wrapSubmenu: {
marginTop: 5,
marginLeft: 0,
width: "100%",
zIndex: 1000,
},
paper: {
backgroundColor: "rgb(34,34,34)",
},
subMenu: {
display: "block",
cursor: "pointer",
color: "white",
textDecoration: "none",
textAlign: "center",
paddingLeft: 12,
paddingRight: 12,
"&:hover": {
backgroundColor: "#4c8beb",
},
},
active: {
backgroundColor: "rgb(59,134,246)",
},
text: {
fontSize: "0.75rem",
textTransform: "uppercase",
},
}));
const Nav = function () {
const { projectCode } = reactRouterDom.useParams();
const classes = useStyles$t();
const [project, setProject] = React__default["default"].useState(null);
const refresh = () => __awaiter(this, void 0, void 0, function* () {
if (projectCode === undefined)
return;
try {
setProject(yield projectService.get(projectCode));
}
catch (_a) {
setProject(null);
}
});
React__default["default"].useEffect(() => {
refresh();
}, [projectCode]);
return (jsxRuntime.jsxs("div", Object.assign({ className: classes.root }, { children: [jsxRuntime.jsx(reactRouterDom.Link, Object.assign({ to: "/tender", className: classes.nav }, { children: jsxRuntime.jsxs("span", Object.assign({ className: classes.text }, { children: [jsxRuntime.jsx(reactFontawesome.FontAwesomeIcon, { style: { marginRight: 4 }, icon: "list-alt" }, void 0), "D\u1EF1 \u00E1n"] }), void 0) }), void 0), jsxRuntime.jsx("div", Object.assign({ className: classes.label }, { children: `Dự án: ${projectCode}${project !== null ? ` - ${project.projectName}` : ""}` }), void 0), jsxRuntime.jsx(reactRouterDom.NavLink, Object.assign({ to: `sale`, className: ({ isActive }) => isActive ? clsx__default["default"](classes.nav, classes.active) : classes.nav }, { children: jsxRuntime.jsxs("span", Object.assign({ className: classes.text }, { children: [jsxRuntime.jsx(reactFontawesome.FontAwesomeIcon, { style: { marginRight: 4 }, icon: "cart-plus" }, void 0), "H\u1EE3p \u0111\u1ED3ng A"] }), void 0) }), void 0), jsxRuntime.jsx(reactRouterDom.NavLink, Object.assign({ to: `scope/elements`, className: ({ isActive }) => isActive ? clsx__default["default"](classes.nav, classes.active) : classes.nav }, { children: jsxRuntime.jsxs("span", Object.assign({ className: classes.text }, { children: [jsxRuntime.jsx(reactFontawesome.FontAwesomeIcon, { style: { marginRight: 4 }, icon: "qrcode" }, void 0), "Ph\u1EA1m vi"] }), void 0) }), void 0), jsxRuntime.jsx(reactRouterDom.NavLink, Object.assign({ to: `quantity`, className: ({ isActive }) => isActive ? clsx__default["default"](classes.nav, classes.active) : classes.nav }, { children: jsxRuntime.jsxs("span", Object.assign({ className: classes.text }, { children: [jsxRuntime.jsx(reactFontawesome.FontAwesomeIcon, { style: { marginRight: 4 }, icon: "drafting-compass" }, void 0), "Kh\u1ED1i l\u01B0\u1EE3ng"] }), void 0) }), void 0), jsxRuntime.jsx(reactRouterDom.NavLink, Object.assign({ to: `norms`, className: ({ isActive }) => isActive ? clsx__default["default"](classes.nav, classes.active) : classes.nav }, { children: jsxRuntime.jsxs("span", Object.assign({ className: classes.text }, { children: [jsxRuntime.jsx(reactFontawesome.FontAwesomeIcon, { style: { marginRight: 4 }, icon: "sliders-h" }, void 0), "\u0110\u1ECBnh m\u1EE9c"] }), void 0) }), void 0), jsxRuntime.jsx(reactRouterDom.NavLink, Object.assign({ to: `reports`, className: ({ isActive }) => isActive ? clsx__default["default"](classes.nav, classes.active) : classes.nav }, { children: jsxRuntime.jsxs("span", Object.assign({ className: classes.text }, { children: [jsxRuntime.jsx(reactFontawesome.FontAwesomeIcon, { style: { marginRight: 4 }, icon: "file-alt" }, void 0), "B\u00E1o c\u00E1o"] }), void 0) }), void 0), jsxRuntime.jsx(reactRouterDom.NavLink, Object.assign({ to: `requests`, className: ({ isActive }) => isActive ? clsx__default["default"](classes.nav, classes.active) : classes.nav }, { children: jsxRuntime.jsxs("span", Object.assign({ className: classes.text }, { children: [jsxRuntime.jsx(reactFontawesome.FontAwesomeIcon, { style: { marginRight: 4 }, icon: "thumbs-up" }, void 0), "Ph\u00EA duy\u1EC7t"] }), void 0) }), void 0), jsxRuntime.jsx(reactRouterDom.NavLink, Object.assign({ to: "versions", className: ({ isActive }) => isActive ? clsx__default["default"](classes.nav, classes.active) : classes.nav }, { children: jsxRuntime.jsxs("span", Object.assign({ className: classes.text }, { children: [jsxRuntime.jsx(reactFontawesome.FontAwesomeIcon, { style: { marginRight: 4 }, icon: "code-branch" }, void 0), "Phi\u00EAn b\u1EA3n"] }), void 0) }), void 0)] }), void 0));
};
const baseUrl$a = `${process.env.REACT_APP_API_HOSTNAME}`;
//Get
function getComponentsByProject(projectCode) {
return __awaiter(this, void 0, void 0, function* () {
const res = yield clientCore.axiosBuilder
.getInstance(baseUrl$a)
.get(`api/v1/td/projects/${projectCode}/components`);
return res.data;
});
}
//Get Activities
function getComponentActivities(projectCode, componentCode) {
return __awaiter(this, void 0, void 0, function* () {
const res = yield clientCore.axiosBuilder
.getInstance(baseUrl$a)
.get(`api/v1/td/projects/${projectCode}/components/${componentCode}/activities`);
return res.data;
});
}
// Upload components
function uploadComponent(projectCode, files) {
return __awaiter(this, void 0, void 0, function* () {
const formData = new FormData();
files.forEach((file) => formData.append("files", file));
formData.append("projectCode", projectCode);
const config = {
headers: {
"content-type": "multipart/form-data",
},
};
const res = yield clientCore.axiosBuilder
.getInstance(baseUrl$a)
.post(`api/v1/td/projects/${projectCode}/components/upload`, formData, config);
return res.data;
});
}
// Upload activities
function uploadActivity(projectCode, files) {
return __awaiter(this, void 0, void 0, function* () {
const formData = new FormData();
files.forEach((file) => formData.append("files", file));
formData.append("projectCode", projectCode);
const config = {
headers: {
"content-type": "multipart/form-data",
},
};
const res = yield clientCore.axiosBuilder
.getInstance(baseUrl$a)
.post(`api/v1/td/projects/${projectCode}/components/upload-activities`, formData, config);
return res.data;
});
}
const service$2 = {
getComponentsByProject,
getComponentActivities,
uploadComponent,
uploadActivity,
};
const useStyles$s = core.makeStyles({
root: {
display: "flex",
flexDirection: "column",
maxWidth: "350px",
height: "100%",
padding: "0 0 8px 8px",
background: "#fff",
overflow: "auto",
},
buttonList: {
display: "flex",
height: "30px",
marginBottom: "8px",
alignItems: "flex-end",
},
button: {
marginRight: "3px",
},
data: {
width: "100%",
flexGrow: 1,
display: "flex",
overflow: "auto",
},
table: {
width: "100%",
display: "block",
borderCollapse: "collapse",
borderSpacing: 0,
},
body: {
width: "100%",
"& > tr:nth-child(even)": {
backgroundColor: "rgb(245,245,245)",
},
},
row: {
borderBottom: "1px dotted rgb(224,224,224)",
},
cell: {
height: 22,
whiteSpace: "nowrap",
borderBottom: "1px dotted rgb(224,224,224)",
fontSize: 13,
padding: "1px 4px 1px 4px",
backgroundColor: "inherit",
},
cellCode: {
fontWeight: 500,
width: 200,
borderRight: "1px dotted rgb(224,224,224)",
},
cellText: {
minWidth: "calc(100% - 200px)",
fontWeight: 400,
fontStyle: "italic",
},
current: {
backgroundColor: "rgb(27,237,247)",
},
});
function ComponentNav() {
const classes = useStyles$s();
const { projectCode } = reactRouterDom.useParams();
const match = reactRouterDom.useMatch("/tender/projects/:projectCode/quantity/activities/:componentCode");
const currentNode = match !== null ? match.params.componentCode : undefined;
const [components, setComponents] = React__default["default"].useState([]);
const [search, setSearch] = React__default["default"].useState("");
const refresh = () => __awaiter(this, void 0, void 0, function* () {
if (projectCode !== undefined) {
try {
setComponents(yield service$2.getComponentsByProject(projectCode));
}
catch (_a) {
setComponents([]);
}
}
});
React__default["default"].useEffect(() => {
refresh();
}, [projectCode]);
return (jsxRuntime.jsxs("div", Object.assign({ className: classes.root }, { children: [jsxRuntime.jsx("div", Object.assign({ className: classes.buttonList }, { children: jsxRuntime.jsx(clientSharedUi.TextField, { placeholder: "T\u00ECm ki\u1EBFm...", value: search, onChange: (e) => {
setSearch(e.currentTarget.value);
} }, void 0) }), void 0), jsxRuntime.jsx("div", Object.assign({ className: classes.data }, { children: jsxRuntime.jsx("table", Object.assign({ className: classes.table }, { children: jsxRuntime.jsx("tbody", Object.assign({ className: classes.body }, { children: components
.filter((x) => x.componentCode
.toUpperCase()
.includes(search.toUpperCase()) ||
x.componentName.toUpperCase().includes(search.toUpperCase()))
.map((c) => (jsxRuntime.jsx(reactRouterDom.NavLink, Object.assign({ to: `${c.componentCode}`, style: { textDecoration: "none", color: "black" } }, { children: jsxRuntime.jsxs("tr", Object.assign({ className: classes.row }, { children: [jsxRuntime.jsx("td", Object.assign({ className: clsx__default["default"](classes.cellCode, classes.cell, currentNode === c.componentCode ? classes.current : "") }, { children: jsxRuntime.jsx("span", Object.assign({ style: { cursor: "pointer" } }, { children: c.componentCode }), void 0) }), void 0), jsxRuntime.jsx("td", Object.assign({ className: clsx__default["default"](classes.cellText, classes.cell, currentNode === c.componentCode ? classes.current : "") }, { children: c.componentName }), void 0)] }), void 0) }), c.componentCode))) }), void 0) }), void 0) }), void 0)] }), void 0));
}
/**
* Format date
* @param date
* @param formatString
* dd - Day
* MM - Month
* yy - Year
* yyyy - Full year
* hh - Hour
* mm - minute
* ss - second
* @returns
*/
function formatDate(date, formatString = "dd/MM/yyyy") {
let result = formatString;
const format = [
{
symbol: "dd",
value: date.getDate() < 10 ? `0${date.getDate()}` : date.getDate(),
},
{
symbol: "MM",
value: date.getMonth() + 1 < 10
? `0${date.getMonth() + 1}`
: `${date.getMonth() + 1}`,
},
{
symbol: "yyyy",
value: date.getFullYear(),
},
{
symbol: "hh",
value: date.getHours() < 10 ? `0${date.getHours()}` : date.getHours(),
},
{
symbol: "mm",
value: date.getMinutes() < 10 ? `0${date.getMinutes()}` : date.getMinutes(),
},
{
symbol: "ss",
value: date.getSeconds() < 10 ? `0${date.getSeconds()}` : date.getSeconds(),
},
{
symbol: "yy",
value: `${date.getFullYear()}`.substring(2),
},
];
format.map((f) => {
result = result.replace(f.symbol, f.value);
return f.symbol;
});
return result;
}
function formatNumber(value, frac = 0, locate = "en-US", currency) {
const options = {
currency: currency,
maximumFractionDigits: frac,
minimumFractionDigits: frac,
};
const numberFormat = new Intl.NumberFormat(locate, options);
return numberFormat.format(value);
}
const compare = new Intl.Collator(undefined, {
numeric: true,
sensitivity: "base",
}).compare;
const ascCompare = (value, newValue) => {
if (compare(value, newValue) === 1)
return 1;
if (compare(value, newValue) === -1)
return -1;
return 0;
};
const descCompare = (value, newValue) => {
if (compare(value, newValue) === 1)
return -1;
if (compare(value, newValue) === -1)
return 1;
return 0;
};
function sortFunction(sortOrderType) {
if (sortOrderType === "asc")
return ascCompare;
return descCompare;
}
registry.registerAllModules();
const useStyles$r = core.makeStyles({
root: {
width: "100%",
height: "100%",
display: "flex",
flexDirection: "column",
overflow: "hidden",
paddingBottom: 16,
},
toolbar: {
display: "flex",
height: "30px",
border: "1px solid rgb(204,204,204)",
borderBottom: 0,
backgroundColor: "rgb(240,240,240)",
flexDirection: "row",
},
data: {
flexGrow: 1,
backgroundColor: "rgb(191,191,191)",
},
});
const dataFromItem = (item) => {
return {
idCode: item.idCode,
description: item.description,
unit: item.unit,
quantity: item.quantity,
orderItemCode: item.billCode !== null ? item.billCode : "",
orderItemDesc: item.billDescription !== null ? item.billDescription : "",
orderItemUnit: item.billUnit !== null ? item.billUnit : "",
serviceCode: item.serviceCode !== null ? item.serviceCode : "",
};
};
function Activities() {
const classes = useStyles$r();
const { projectCode, componentCode } = reactRouterDom.useParams();
const [activities, setActivities] = React__default["default"].useState([]);
const [isLoading, setIsLoading] = React__default["default"].useState(false);
const refresh = () => __awaiter(this, void 0, void 0, function* () {
if (projectCode === undefined || componentCode === undefined)
return;
try {
const data = yield service$2.getComponentActivities(projectCode, componentCode);
setActivities(data.map((x) => dataFromItem(x)));
}
catch (err) {
setActivities([]);
}
finally {
setIsLoading(false);
}
});
React__default["default"].useEffect(() => {
refresh();
}, [projectCode, componentCode]);
return (jsxRuntime.jsx("div", Object.assign({ className: classes.root }, { children: jsxRuntime.jsx("div", Object.assign({ className: classes.data }, { children: jsxRuntime.jsx(HotTable.HotTable, { data: activities, rowHeaders: true, dropdownMenu: true, filters: true, manualColumnResize: true, height: "100%", columnSorting: true, licenseKey: "non-commercial-and-evaluation" // for non-commercial use only
, colHeaders: [
"Mã ID",
"Diễn giải ID",
"Đơn vị",
"Khối lượng",
"Mã BOQ",
"Diễn giải BOQ",
"Đơn vị",
"Mã BOS",
], columns: [
{
data: "idCode",
columnSorting: { compareFunctionFactory: (s) => sortFunction(s) },
readOnly: true,
},
{ data: "description", width: 800, readOnly: true },
{ data: "unit", readOnly: true },
{
data: "quantity",
type: "numeric",
numericFormat: {
pattern: "0,0.00",
culture: "en-US",
},
readOnly: true,
},
{
data: "orderItemCode",
columnSorting: { compareFunctionFactory: (s) => sortFunction(s) },
readOnly: true,
},
{
data: "orderItemDesc",
width: 800,
readOnly: true,
},
{ data: "orderItemUnit", readOnly: true },
{
data: "serviceCode",
columnSorting: { compareFunctionFactory: (s) => sortFunction(s) },
readOnly: true,
},
] }, void 0) }), void 0) }), void 0));
}
const baseUrl$9 = `${process.env.REACT_APP_API_HOSTNAME}`;
//Get
function getAll$4(projectCode) {
return __awaiter(this, void 0, void 0, function* () {
const res = yield clientCore.axiosBuilder
.getInstance(baseUrl$9)
.get(`api/v1/td/projects/${projectCode}/bills`);
return res.data;
});
}
function getView(projectCode, version = "working") {
return __awaiter(this, void 0, void 0, function* () {
const res = yield clientCore.axiosBuilder
.getInstance(baseUrl$9)
.get(`api/v1/td/projects/${projectCode}/bills/view?version=${version}`);
return res.data;
});
}
// Upload bills
function upload$5(projectCode, files) {
return __awaiter(this, void 0, void 0, function* () {
const formData = new FormData();
files.forEach((file) => formData.append("files", file));
formData.append("projectCode", projectCode);
const config = {
headers: {
"content-type": "multipart/form-data",
},
};
const res = yield clientCore.axiosBuilder
.getInstance(baseUrl$9)
.post(`api/v1/td/projects/${projectCode}/bills/upload`, formData, config);
return res.data;
});
}
const billService = {
getAll: getAll$4,
getView,
upload: upload$5,
};
const baseUrl$8 = `${process.env.REACT_APP_API_HOSTNAME}`;
//Get
function getAll$3(projectCode) {
return __awaiter(this, void 0, void 0, function* () {
const res = yield clientCore.axiosBuilder
.getInstance(baseUrl$8)
.get(`api/v1/td/projects/${projectCode}/shortcuts`);
return res.data;
});
}
// Upload shortcuts
function upload$4(projectCode, files) {
return __awaiter(this, void 0, void 0, function* () {
const formData = new FormData();
files.forEach((file) => formData.append("files", file));
formData.append("projectCode", projectCode);
const config = {
headers: {
"content-type": "multipart/form-data",
},
};
const res = yield clientCore.axiosBuilder
.getInstance(baseUrl$8)
.post(`api/v1/td/projects/${projectCode}/shortcuts/upload`, formData, config);
return res.data;
});
}
const service$1 = {
getAll: getAll$3,
upload: upload$4,
};
const baseUrl$7 = `${process.env.REACT_APP_API_HOSTNAME}`;
//Get
function getProjectELement(projectCode, versionCode = "working") {
return __awaiter(this, void 0, void 0, function* () {
const res = yield clientCore.axiosBuilder
.getInstance(baseUrl$7)
.get(`api/v1/td/projects/${projectCode}/elements?versionCode=${versionCode}`);
return res.data;
});
}
// Upload element
function upload$3(projectCode, files) {
return __awaiter(this, void 0, void 0, function* () {
const formData = new FormData();
files.forEach((file) => formData.append("files", file));
formData.append("projectCode", projectCode);
const config = {
headers: {
"content-type": "multipart/form-data",
},
};
const res = yield clientCore.axiosBuilder
.getInstance(baseUrl$7)
.post(`api/v1/td/projects/${projectCode}/elements/upload`, formData, config);
return res.data;
});
}
const elementService = {
getProjectELement,
upload: upload$3,
};
const baseUrl$6 = `${process.env.REACT_APP_API_HOSTNAME}`;
//Get
function getAll$2() {
return __awaiter(this, void 0, void 0, function* () {
const res = yield clientCore.axiosBuilder
.getInstance(baseUrl$6)
.get(`api/v1/td/option-configs`);
return res.data;
});
}
// Upload config
function upload$2(files) {
return __awaiter(this, void 0, void 0, function* () {
const formData = new FormData();
files.forEach((file) => formData.append("files", file));
const config = {
headers: {
"content-type": "multipart/form-data",
},
};
const res = yield clientCore.axiosBuilder
.getInstance(baseUrl$6)
.post(`api/v1/td/option-configs/upload`, formData, config);
return res.data;
});
}
const optionService$1 = {
getAll: getAll$2,
upload: upload$2,
};
const useStyles$q = core.makeStyles({
button: {
height: 30,
width: "auto",
padding: "0 6px",
color: "rgb(68,68,68)",
textAlign: "center",
lineHeight: "30px",
cursor: "pointer",
"&:hover": {
color: "rgb(0,101,67)",
},
},
disable: {
color: "rgb(148,148,148)",
cursor: "not-allowed",
"&:hover": {
color: "rgb(148,148,148)",
},
},
text: {
marginLeft: "3px",
fontWeight: 600,
},
});
function ToolbarButton({ tooltip, icon, text, disable = false, onClick, }) {
const classes = useStyles$q();
const handleClick = () => {
if (onClick !== undefined) {
if (disable !== true) {
onClick();
}
}
};
return tooltip !== undefined ? (jsxRuntime.jsx(core.Tooltip, Object.assign({ title: tooltip }, { children: jsxRuntime.jsxs("div", Object.assign({ className: clsx__default["default"](classes.button, disable ? classes.disable : ""), onClick: () => {
handleClick();
} }, { children: [jsxRuntime.jsx(reactFontawesome.FontAwesomeIcon, { icon: icon, style: { fontSize: 16 } }, void 0), " ", jsxRuntime.jsx("span", Object.assign({ className: classes.text }, { children: text }), void 0)] }), void 0) }), void 0)) : (jsxRuntime.jsxs("div", Object.assign({ className: clsx__default["default"](classes.button, disable ? classes.disable : ""), onClick: () => {
handleClick();
} }, { children: [jsxRuntime.jsx(reactFontawesome.FontAwesomeIcon, { icon: icon, style: { fontSize: 16 } }, void 0), jsxRuntime.jsx("span", Object.assign({ className: classes.text }, { children: text }), void 0)] }), void 0));
}
const baseUrl$5 = `${process.env.REACT_APP_API_HOSTNAME}`;
function getNormConfigs() {
return __awaiter(this, void 0, void 0, function* () {
const res = yield clientCore.axiosBuilder
.getInstance(baseUrl$5)
.get("api/v1/td/norm-configs");
return res.data;
});
}
// Upload norm configs
function uploadConfig(files) {
return __awaiter(this, void 0, void 0, function* () {
const formData = new FormData();
files.forEach((file) => formData.append("files", file));
const config = {
headers: {
"content-type": "multipart/form-data",
},
};
const res = yield clientCore.axiosBuilder
.getInstance(baseUrl$5)
.post(`api/v1/td/norm-configs/upload`, formData, config);
return res.data;
});
}
const normModService = { getNormConfigs, uploadConfig };
function getNorms(projectCode, type, versionCode = "working") {
return __awaiter(this, void 0, void 0, function* () {
const res = yield clientCore.axiosBuilder
.getInstance(baseUrl$5)
.get(`api/v1/td/projects/${projectCode}/norms/${type}?versionCode=${versionCode}`);
return res.data;
});
}
// Upload norm
function upload$1(projectCode, files) {
return __awaiter(this, void 0, void 0, function* () {
const formData = new FormData();
files.forEach((file) => formData.append("files", file));
const config = {
headers: {
"content-type": "multipart/form-data",
},
};
const res = yield clientCore.axiosBuilder
.getInstance(baseUrl$5)
.post(`api/v1/td/projects/${projectCode}/norms/upload`, formData, config);
return res.data;
});
}
const normService$1 = {
getNorms,
upload: upload$1,
};
const baseUrl$4 = `${process.env.REACT_APP_API_HOSTNAME}`;
function get(projectCode, versionCode = "working") {
return __awaiter(this, void 0, void 0, function* () {
const res = yield clientCore.axiosBuilder
.getInstance(baseUrl$4)
.get(`api/v1/td/projects/${projectCode}/mappings?versionCode=${versionCode}`);
return res.data;
});
}
// Upload components
function upload(projectCode, files) {
return __awaiter(this, void 0, void 0, function* () {
const formData = new FormData();
files.forEach((file) => formData.append("files", file));
formData.append("projectCode", projectCode);
const config = {
headers: {
"content-type": "multipart/form-data",
},
};
const res = yield clientCore.axiosBuilder
.getInstance(baseUrl$4)
.post(`api/v1/td/projects/${projectCode}/mappings/upload`, formData, config);
return res.data;
});
}
const mappingService = {
get,
upload,
};
function Upload({ type, projectCode, onFinish, }) {
const { setStatus, showAlert } = React__default["default"].useContext(clientCore.AppContext);
const [open, setOpen] = React__default["default"].useState(false);
const [typeName, setTypeName] = React__default["default"].useState("");
const [files, setFiles] = React__default["default"].useState([]);
const handleSubmit = () => __awaiter(this, void 0, void 0, function* () {
if (files) {
setStatus(true, "Đang upload...");
try {
switch (type) {
case "boq":
if (projectCode)
yield billService.upload(projectCode, files);
break;
case "shortcut":
if (projectCode)
yield service$1.upload(projectCode, files);
break;
case "component":
if (projectCode)
yield service$2.uploadComponent(projectCode, files);
break;
case "activity":
if (projectCode)
yield service$2.uploadActivity(projectCode, files);
break;
case "mapping":
if (projectCode)
yield mappingService.upload(projectCode, files);
break;
case "wbs":
if (projectCode)
yield elementService.upload(projectCode, files);
break;
case "option":
yield optionService$1.upload(files);
break;
case "norm-config":
yield normModService.uploadConfig(files);
break;
case "norms":
if (projectCode)
yield normService$1.upload(projectCode, files);
break;
default:
break;
}
showAlert("success", "Thành công!");
}
catch (error) {
showAlert("error", "Upload không thành công! Vui lòng thử lại sau");
}
finally {
setStatus(false, "");
setOpen(false);
setFiles([]);
if (onFinish)
onFinish();
}
}
});
React__default["default"].useEffect(() => {
if (type === "boq")
setTypeName("BOQ");
if (type === "shortcut")
setTypeName("ID Code");
if (type === "component")
setTypeName("cấu kiện");
if (type === "activity")
setTypeName("công tác");
if (type === "mapping")
setTypeName("mapping");
if (type === "wbs")
setTypeName("WBS");
if (type === "option")
setTypeName("option");
if (type === "norm-config")
setTypeName("cấu hình định mức");
if (type === "norms")
setTypeName("định mức");
}, []);
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(ToolbarButton, { icon: "cloud-upload-alt", onClick: () => setOpen(true), text: "Upload" }, void 0), jsxRuntime.jsx(clientSharedUi.FormDialog, Object.assign({ open: open, onClose: () => setOpen(false), onSubmit: handleSubmit }, { children: jsxRuntime.jsx(materialUiDropzone.DropzoneArea, { showPreviews: false, showFileNames: true, filesLimit: 10, maxFileSize: 25000000, useChipsForPreview: true, dropzoneText: `Upload dữ liệu ${typeName}`, onChange: (files) => {
setFiles(files);
} }, void 0) }), void 0)] }, void 0));
}
const useStyles$p = core.makeStyles({
root: {
display: "flex",
flexFlow: "row wrap",
width: "100%",
height: "100%",
paddingBottom: 16,
overflow: "hidden",
},
toolbar: {
width: "100%",
display: "flex",
height: "30px",
border: "1px solid rgb(204,204,204)",
borderBottom: 0,
backgroundColor: "rgb(240,240,240)",
flexDirection: "row",
},
data: {
display: "flex",
flexFlow: "row nowrap",
width: "100%",
height: "100%",