Browse Source

Merge branch 'master' of https://git.oslog.id/ordo/adw-frontend

pull/2/head
ardhi 2 years ago
parent
commit
93ec6130ab
  1. 2
      package.json
  2. 2
      src/const/ApiConst.js
  3. 75
      src/const/en.json
  4. 24
      src/const/i18n.js
  5. 75
      src/const/id.json
  6. 6
      src/utils/LangUtils.js
  7. 33
      src/views/Dashboard/DashboardBOD.js
  8. 45
      src/views/Master/MasterAbsensi/index.js
  9. 25
      src/views/Master/MasterMenu/DialogForm.js
  10. 28
      src/views/Master/MasterMenu/index.js
  11. 17
      src/views/Master/MasterRoles/DialogForm.js
  12. 10
      src/views/Master/MasterRoles/DialogMenuRoles.js
  13. 29
      src/views/Master/MasterRoles/index.js
  14. 10
      src/views/Master/ProjectPhase/DialogForm.js
  15. 112
      src/views/Master/ProjectPhase/index.js
  16. 17
      src/views/Master/RoleProject/DialogForm.js
  17. 28
      src/views/Master/RoleProject/index.js
  18. 44
      src/views/Report/k3/index.js
  19. 15
      src/views/SimproV2/ChecklistK3/DialogForm.js
  20. 34
      src/views/SimproV2/ChecklistK3/index.js
  21. 20
      src/views/SimproV2/CreatedProyek/DialogDocument.js
  22. 20
      src/views/SimproV2/CreatedProyek/index.js
  23. 21
      src/views/SimproV2/Divisi/DialogForm.js
  24. 111
      src/views/SimproV2/Divisi/index.js
  25. 8
      src/views/SimproV2/Presence/DialogFoto.js
  26. 47
      src/views/SimproV2/Presence/index.js
  27. 13
      src/views/SimproV2/ProjectType/DialogForm.js
  28. 26
      src/views/SimproV2/ProjectType/DialogInitialGantt.js
  29. 31
      src/views/SimproV2/ProjectType/index.js
  30. 53
      src/views/SimproV2/ResourceWorker/DialogForm.js
  31. 13
      src/views/SimproV2/Satuan/DialogForm.js
  32. 30
      src/views/SimproV2/Satuan/index.js

2
package.json

@ -46,6 +46,7 @@
"enzyme-adapter-react-16": "^1.14.0",
"flag-icon-css": "^3.3.0",
"font-awesome": "^4.7.0",
"i18next": "^22.4.9",
"interactjs": "^1.10.11",
"jspdf": "^2.5.1",
"jspdf-autotable": "^3.5.25",
@ -75,6 +76,7 @@
"react-dom": "^16.14.0",
"react-grid-layout": "^1.2.5",
"react-highlight-words": "^0.18.0",
"react-i18next": "^12.1.5",
"react-leaflet": "^3.2.0",
"react-leaflet-draw": "^0.19.8",
"react-loader-spinner": "^3.1.5",

2
src/const/ApiConst.js

@ -113,7 +113,7 @@ export const TOKEN_ADW = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiIxMjAyI
// export let BASE_OSPRO = "https://ospro-api.ospro.id";
export let BASE_OSPRO = "https://adw-api.ospro.id";
// export let BASE_OSPRO = "http://localhost:8444";
// export let BASE_OSPRO = "http://localhost:8444/adw-backend";
// export let BASE_OSPRO = "http://192.168.1.123:8444"; // local
// export let BASE_OSPRO = "http://103.73.125.81:8444"; // ip public adw
export let BASE_SIMPRO_LUMEN = `${BASE_OSPRO}/api`;

75
src/const/en.json

@ -0,0 +1,75 @@
{
"3days": "3 Days Ago",
"7days": "7 Days Ago",
"action": "Action",
"add": "Add",
"ChecklistK3Add": "Add Checklist K3",
"cancel": "Cancel",
"close": "Close",
"color": "Color",
"date": "Date",
"dateAbsent": "Absent Date",
"dateReport": "Report Date",
"delete": "Delete",
"deleteMsg": "Delete this data ?",
"deleteConfirm": "Are you sure ?",
"description": "Description",
"division": "Division",
"divisionAdd": "Add Division",
"edit": "Edit",
"export": "Export",
"exportExcel": "Export Excel",
"exportPdf": "Export Pdf",
"gearUse": "Gear Used",
"gearNotUse": "Gear Not used",
"hr": "Human Resource",
"icon": "Icon",
"inputIcon": "Input Code Icon",
"inputName": "Input Name",
"inputDescription": "Input Description",
"inputParentMenu": "Select Parent Menu",
"inputAliasMenu": "Input Menu Alias",
"inputOrder": "Input Order",
"inputUrl": "Input URL",
"image": "Image",
"imageCheck": "Selfie Presence",
"locIn": "Location In",
"locOut": "Location Out",
"menuRoles": "Roles Menu",
"menuAdd": "Add Menu",
"nik": "ID Card",
"name": "Name",
"nameHR": "Name Human Resource",
"nameRole": "Name Role",
"nameDivision": "Name Division",
"nameProjectType": "Project Type",
"nameProjectRole": "Project Role",
"noData": "Data not yet available",
"order": "Order",
"parentMenu": "Parent Menu",
"phase": "Project Phase",
"projectType": "Add Project Type",
"projectPhase": "Add Project Phase",
"presenceIn": "Presence In",
"presenceOut": "Presence Out",
"rolesAdd": "Add Roles",
"roles": "Roles",
"search": "Search",
"save": "Save",
"searchType": "Search Project Type",
"searchPhase": "Search Project Phase",
"searchDivision": "Search Division",
"searchUom": "Search UOM",
"searchChecklistK3": "Search checklist K3",
"searchRoles": "Search Roles",
"searchProjectRoles": "Search Project Roles",
"searchProject": "All / Select Projects",
"searchMenu": "Search Menu",
"searchHR": "Search Human Resource",
"today": "Today",
"uom": "UOM",
"uomAdd": "Add UOM",
"workDuration": "Work Duration",
"workAreaIn": "Work Area In",
"workAreaOut": "Work Area Out"
}

24
src/const/i18n.js

@ -0,0 +1,24 @@
import i18n from "i18next";
import { initReactI18next } from "react-i18next";
import en from "./en.json";
import id from "./id.json";
i18n
.use(initReactI18next)
.init({
debug: true,
fallbackLng: 'id',
interpolation: {
escapeValue: false, // not needed for react as it escapes by default
},
resources: {
en: {
translation: en,
},
id: {
translation: id,
}
},
lng: localStorage.getItem("lng") || "id",
});
export default i18n;

75
src/const/id.json

@ -0,0 +1,75 @@
{
"3days": "3 Hari Yang lalu",
"7days": "7 Hari Yang lalu",
"action": "Aksi",
"add": "Tambah",
"ChecklistK3Add": "Tambah Ceklis K3",
"cancel": "Batal",
"close": "Tutup",
"color": "Warna",
"date": "Tanggal",
"dateAbsent": "Tanggal Absen",
"dateReport": "Tanggal Lapor",
"delete": "Hapus",
"deleteMsg": "Hapus Data Ini ?",
"deleteConfirm": "Apakah Anda Yakin ?",
"description": "Deskripsi",
"division": "Divisi",
"divisionAdd": "Tambah Divisi",
"edit": "Ubah",
"export": "Ekspor",
"exportExcel": "Ekspor Excel",
"exportPdf": "Ekspor Pdf",
"gearUse": "Perlengkapan Dikenakan",
"gearNotUse": "Perlengkapan Tidak Dikenakan",
"hr": "Pegawai",
"icon": "Ikon",
"inputIcon": "Masukan Kode Ikon",
"inputName": "Masukan Nama",
"inputDescription": "Masukan Deskripsi",
"inputParentMenu": "Pilih Induk Menu",
"inputAliasMenu": "Masukan Alias Menu",
"inputOrder": "Masukan Urutan",
"inputUrl": "Masukan URL",
"image": "Gambar",
"imageCheck": "Lihat Selfie Presensi",
"locIn": "Lokasi Masuk",
"locOut": "Lokasi Pulang",
"menuRoles": "Menu Peran",
"menuAdd": "Tambah Menu",
"nik": "NIK",
"nameDivision": "Nama Divisi",
"name": "Nama",
"nameHR": "Nama Pegawai",
"nameRole": "Nama Peran",
"nameProjectType": "Tipe Proyek",
"nameProjectRole": "Peran Proyek",
"noData": "Data Belum tersedia",
"order": "Urutan",
"parentMenu": "Menu Induk",
"phase": "Fase Proyek",
"projectType": "Tambah Tipe Proyek",
"projectPhase": "Tambah Fase Proyek",
"presenceIn": "Waktu Masuk",
"presenceOut": "Waktu Pulang",
"rolesAdd": "Tambah Roles",
"roles": "Peran",
"save": "Simpan",
"search": "Cari",
"searchType": "Cari Tipe Proyek",
"searchPhase": "Cari Fase Proyek",
"searchDivision": "Cari Divisi",
"searchUom": "Cari Satuan",
"searchChecklistK3": "Cari Ceklis K3",
"searchRoles": "Cari Peran",
"searchProjectRoles": "Cari Peran Proyek",
"searchProject": "Semua / Pilih Proyek",
"searchMenu": "Cari Menu",
"searchHR": "Cari Nama Pegawai",
"today": "Hari Ini",
"uom": "Satuan",
"uomAdd": "Tambah Satuan",
"workDuration": "Durasi Kerja",
"workAreaIn": "Area Kerja In",
"workAreaOut": "Area Kerja Out"
}

6
src/utils/LangUtils.js

@ -0,0 +1,6 @@
import i18n from "../const/i18n";
export const handleChangeLng = (lng) => {
i18n.changeLanguage(lng);
localStorage.setItem("lng", lng);
};

33
src/views/Dashboard/DashboardBOD.js

@ -406,6 +406,15 @@ const DashboardBOD = () => {
<Bar
options={{
indexAxis: 'y',
scales: {
x: {
ticks: {
callback: function (value) {
return toRupiah(value, { useUnit: 'jt' });
}
}
}
},
elements: {
bar: {
borderWidth: 2,
@ -489,10 +498,10 @@ const DashboardBOD = () => {
label: "",
// data: [2, 4, 10],
data: [
PROJECT_BY_FINANCIAL_HEALTH && PROJECT_BY_FINANCIAL_HEALTH.overrun ? PROJECT_BY_FINANCIAL_HEALTH.overrun : 0,
PROJECT_BY_FINANCIAL_HEALTH && PROJECT_BY_FINANCIAL_HEALTH.warning ? PROJECT_BY_FINANCIAL_HEALTH.warning : 0,
PROJECT_BY_FINANCIAL_HEALTH && PROJECT_BY_FINANCIAL_HEALTH['on-budget'] ? PROJECT_BY_FINANCIAL_HEALTH['on-budget'] : 0
],
PROJECT_BY_FINANCIAL_HEALTH && PROJECT_BY_FINANCIAL_HEALTH.overrun ? PROJECT_BY_FINANCIAL_HEALTH.overrun : '',
PROJECT_BY_FINANCIAL_HEALTH && PROJECT_BY_FINANCIAL_HEALTH.warning ? PROJECT_BY_FINANCIAL_HEALTH.warning : '',
PROJECT_BY_FINANCIAL_HEALTH && PROJECT_BY_FINANCIAL_HEALTH['on-budget'] ? PROJECT_BY_FINANCIAL_HEALTH['on-budget'] : ''
].filter(value => value !== null),
borderColor: ["#E80053", "#FFD600", "#52AC0B",],
backgroundColor: ["#E80053", "#FFD600", "#52AC0B",],
borderWidth: 2,
@ -515,9 +524,9 @@ const DashboardBOD = () => {
label: "",
// data: [1, 3, 11],
data: [
PROJECT_BY_SCHEDULE_HEALTH && PROJECT_BY_SCHEDULE_HEALTH['behind-schedule'] ? PROJECT_BY_SCHEDULE_HEALTH['behind-schedule'] : 0,
PROJECT_BY_SCHEDULE_HEALTH && PROJECT_BY_SCHEDULE_HEALTH.warning ? PROJECT_BY_SCHEDULE_HEALTH.warning : 0,
PROJECT_BY_SCHEDULE_HEALTH && PROJECT_BY_SCHEDULE_HEALTH['on-schedule'] ? PROJECT_BY_SCHEDULE_HEALTH['on-schedule'] : 0
PROJECT_BY_SCHEDULE_HEALTH && PROJECT_BY_SCHEDULE_HEALTH['behind-schedule'] ? PROJECT_BY_SCHEDULE_HEALTH['behind-schedule'] : '',
PROJECT_BY_SCHEDULE_HEALTH && PROJECT_BY_SCHEDULE_HEALTH.warning ? PROJECT_BY_SCHEDULE_HEALTH.warning : '',
PROJECT_BY_SCHEDULE_HEALTH && PROJECT_BY_SCHEDULE_HEALTH['on-schedule'] ? PROJECT_BY_SCHEDULE_HEALTH['on-schedule'] : ''
],
borderColor: ["#E80053", "#FFD600", "#52AC0B"],
backgroundColor: ["#E80053", "#FFD600", "#52AC0B"],
@ -571,8 +580,8 @@ const DashboardBOD = () => {
label: "",
// data: [7, 2, 4, 3],
data: PROJECT_PER_DIVISION ? PROJECT_PER_DIVISION.map((item, idx) => item.total) : [],
borderColor: ["#023E8A", "#C851B7", "#FD7034", "#3A0CA3"],
backgroundColor: ["#023E8A", "#C851B7", "#FD7034", "#3A0CA3"],
borderColor: ["#023E8A", "#C851B7", "#FD7034", "#3A0CA3", "#A36A16"],
backgroundColor: ["#023E8A", "#C851B7", "#FD7034", "#3A0CA3", "#A36A16"],
borderWidth: 2,
borderSkipped: false
},
@ -622,9 +631,9 @@ const DashboardBOD = () => {
{
label: "",
// data: [50, 120, 72, 60],
data: PROJECT_VALUE_PER_DIVISION ? PROJECT_VALUE_PER_DIVISION.map((item, idx) => item.total) : [],
borderColor: ["#023E8A", "#C851B7", "#FD7034", "#3A0CA3"],
backgroundColor: ["#023E8A", "#C851B7", "#FD7034", "#3A0CA3"],
data: PROJECT_VALUE_PER_DIVISION ? PROJECT_VALUE_PER_DIVISION.map((item, idx) => item.total).filter(value => value !== 0) : [],
borderColor: ["#023E8A", "#C851B7", "#FD7034", "#3A0CA3", "#A36A16"],
backgroundColor: ["#023E8A", "#C851B7", "#FD7034", "#3A0CA3", "#A36A16"],
borderWidth: 2,
borderSkipped: false
},

45
src/views/Master/MasterAbsensi/index.js

@ -11,6 +11,7 @@ import { DatePicker,Select } from 'antd';
import * as XLSX from 'xlsx';
import { ABSENSI_SEARCH, ABSENSI_ADD, ABSENSI_DELETE, ABSENSI_EDIT, PROYEK_SEARCH, USERPROYEK_SEARCH } from '../../../const/ApiConst.js';
import MapConfig from '../../MapConfig/MapConfig';
import { withTranslation } from 'react-i18next';
const { RangePicker } = DatePicker;
const { Option } = Select
const token = window.localStorage.getItem('token');
@ -24,17 +25,9 @@ const config = {
const BASE_URL = "";
const column = [
{ name: "Nama Human Resource" },
{ name: "Deskripsi"},
{ name: "Tanggal Absensi"},
]
const LENGTH_DATA = 10
export default class index extends Component {
class index extends Component {
constructor(props) {
super(props)
this.state = {
@ -438,6 +431,7 @@ export default class index extends Component {
}
renderTable = () => {
const t = this.props;
const dataTable2 = this.state.dataTable || [];
return (
<tbody>
@ -461,7 +455,7 @@ export default class index extends Component {
</tr>
)
}) : <tr>
<td colSpan="4" align="center">No Data Available</td>
<td colSpan="4" align="center">{this.props.t('noData')}</td>
</tr>
}
</tbody>
@ -472,21 +466,18 @@ export default class index extends Component {
const val = e.target.value;
this.setState({ currentDay: val });
if (val === "today") {
console.log("test 1 test",val);
this.setState({
startDate: moment(moment().format("YYYY-M-D")),
endDate: moment(moment().format("YYYY-M-D")),
currentPage: 1
})
} else if (val === "3 day") {
console.log("test test",val);
this.setState({
startDate: moment(moment().subtract(3, "days").format("YYYY-M-D")),
endDate: moment(moment().format("YYYY-M-D")),
currentPage: 1
})
} else if (val === "7 day") {
console.log("test test",val);
this.setState({
startDate: moment(moment().subtract(7, "days").format("YYYY-M-D")),
endDate: moment(moment().format("YYYY-M-D")),
@ -503,6 +494,12 @@ export default class index extends Component {
}
render() {
const t = this.props;
const column = [
{ name: this.props.t('nameHR') },
{ name: this.props.t('description') },
{ name: this.props.t('dateAbsent') },
]
const { tooltipTambah, tooltipExport, dataTable, openDialog, currentPage, rowsPerPage, totalPage, search, tooltipEdit, tooltipDelete } = this.state
return (
<div>
@ -513,12 +510,12 @@ export default class index extends Component {
showCancel
confirmBtnText="Delete"
confirmBtnBsStyle="danger"
title="Are you sure?"
title={this.props.t('deleteConfirm')}
onConfirm={this.onConfirmDelete}
onCancel={() => this.setState({ alertDelete: false, idDelete: 0 })}
focusCancelBtn
>
Data Absensi karyawan akan terhapus!!
{this.props.t('deleteMsg')}
</SweetAlert>
<DialogForm
openDialog={openDialog}
@ -533,14 +530,9 @@ export default class index extends Component {
<CardHeader style={{ display: "flex", justifyContent: "space-between" }}>
<h4>{this.props.params.name}</h4>
<div>
{/* <Button id="TooltipTambah" color="success" onClick={() => this.handleOpenDialog('Save')}><i className="fa fa-plus"></i></Button> */}
<Tooltip title="Export Excel">
<Tooltip title={this.props.t('exportExcel')}>
<Button style={{ marginLeft: "5px" }} id="TooltipExport" color="primary" onClick={() => this.handleExportExcel()}><i className="fa fa-print"></i></Button>
</Tooltip>
{/* <Button color="primary" onClick={() => this.handleOpenDialog('Save')}>Tambah Divisi Karyawan</Button> */}
{/* <Tooltip placement="right" isOpen={tooltipTambah} target="TooltipTambah" toggle={() => this.toggle("tambah")}>
Tambah Absensi
</Tooltip> */}
</div>
</CardHeader>
<CardBody>
@ -548,17 +540,17 @@ export default class index extends Component {
<div style={{ width: "100%", display: "flex", alignItems: "center" }}>
<div style={{ width: "100%", marginRight: "10px", maxWidth: "200px" }}>
<Input type="select" onChange={(e) => this.handleChangeDay(e)} defaultValue={this.state.currentDay}>
<option value="today">Hari Ini</option>
<option value="3 day">3 Hari yang lalu</option>
<option value="7 day">7 Hari yang lalu</option>
<option value="today">{this.props.t('today')}</option>
<option value="3 day">{this.props.t('3days')}</option>
<option value="7 day">{this.props.t('7days')}</option>
</Input>
</div>
<div style={{ width: "50%", marginTop: "3px" }}>
<RangePicker size="default" allowClear={false} value={[this.state.startDate, this.state.endDate]} onChange={this.handleDatePicker} />{' '}
<Button color="primary" onClick={() => this.getDataAbsensi()}>Cari</Button>
<Button color="primary" onClick={() => this.getDataAbsensi()}>{this.props.t('search')}</Button>
</div>
</div>
<Input onChange={this.handleSearch} value={search} type="text" name="search" id="search" placeholder="Cari nama human resource" style={{ maxWidth: "200px", marginBottom: "20px" }} />
<Input onChange={this.handleSearch} value={search} type="text" name="search" id="search" placeholder={this.props.t('searchHR')} style={{ maxWidth: "200px", marginBottom: "20px" }} />
</div>
<Table responsive striped hover>
<thead>
@ -588,3 +580,4 @@ export default class index extends Component {
)
}
}
export default withTranslation()(index);

25
src/views/Master/MasterMenu/DialogForm.js

@ -4,6 +4,7 @@ import { Button, Form, FormGroup, Label, Input, Col, Row } from 'reactstrap';
import { Select } from 'antd';
import moment from 'moment';
import 'antd/dist/antd.css';
import { useTranslation } from 'react-i18next';
const { Option } = Select
@ -15,7 +16,7 @@ const DialogForm = ({openDialog, closeDialog, toggleDialog, typeDialog, dataEdit
const [icon, setIcon] = useState('')
const [sequence, setSequence] = useState(0)
const [parentId, setParentId] = useState(null)
const { t } = useTranslation()
useEffect(() => {
if (typeDialog === "Edit") {
@ -112,32 +113,32 @@ const DialogForm = ({openDialog, closeDialog, toggleDialog, typeDialog, dataEdit
<Row>
<Col>
<FormGroup>
<Label className="capitalize">Nama Menu</Label>
<Input type="text" value={name} onChange={(e)=> setName(e.target.value)} placeholder={`Menu..`}/>
<Label className="capitalize">{t('name')} Menu</Label>
<Input type="text" value={name} onChange={(e) => setName(e.target.value)} placeholder={t('inputName')} />
</FormGroup>
<FormGroup>
<Label className="capitalize">URL</Label>
<Input type="text" value={url} onChange={(e)=> setUrl(e.target.value)} placeholder={`Url..`} />
<Input type="text" value={url} onChange={(e) => setUrl(e.target.value)} placeholder={t('inputUrl')} />
</FormGroup>
<FormGroup>
<Label className="capitalize">Icon</Label>
<Input type="text" value={icon} onChange={(e)=> setIcon(e.target.value)} placeholder={`Ikon..`} />
<Label className="capitalize">{t('icon')} </Label>
<Input type="text" value={icon} onChange={(e) => setIcon(e.target.value)} placeholder={t('inputIcon')} />
</FormGroup>
</Col>
<Col>
<FormGroup>
<Label className="capitalize">Urutan</Label>
<Input type="number" value={sequence} onChange={(e)=> setSequence(e.target.value)} placeholder={`urutan..`} />
<Label className="capitalize">{t('order')}</Label>
<Input type="number" value={sequence} onChange={(e) => setSequence(e.target.value)} placeholder={t('inputOrder')} />
</FormGroup>
<FormGroup>
<Label className="capitalize">Parent</Label>
<Select showSearch defaultValue={parentId} onChange={onChangeParent} placeholder="Select Parent" style={{width:'100%'}}>
<Label className="capitalize">{t('parentMenu')}</Label>
<Select showSearch defaultValue={parentId} onChange={onChangeParent} placeholder={t('inputParentMenu')} style={{ width: '100%' }}>
{setupSelectParent()}
</Select>
</FormGroup>
<FormGroup>
<Label className="capitalize">Alias Menu</Label>
<Input type="text" value={aliasName} onChange={(e)=> setAliasName(e.target.value)} placeholder={`Alias..`} />
<Input type="text" value={aliasName} onChange={(e) => setAliasName(e.target.value)} placeholder={t('inputAliasMenu')} />
</FormGroup>
</Col>
</Row>
@ -155,7 +156,7 @@ const DialogForm = ({openDialog, closeDialog, toggleDialog, typeDialog, dataEdit
</ModalBody>
<ModalFooter>
<Button color="primary" onClick={() => handleSave()}>{typeDialog}</Button>{' '}
<Button className="capitalize" color="secondary" onClick={() => handleCancel()}>Batal</Button>
<Button className="capitalize" color="secondary" onClick={() => handleCancel()}>{t('cancel')}</Button>
</ModalFooter>
</Modal>
)

28
src/views/Master/MasterMenu/index.js

@ -8,7 +8,7 @@ import { Card, CardBody, CardHeader, Col, Row, Input } from 'reactstrap';
import { MENU_ADD, MENU_SEARCH, MENU_EDIT, MENU_DELETE } from '../../../const/ApiConst.js';
import { NotificationContainer, NotificationManager } from 'react-notifications';
import { Pagination, Tooltip, Table } from 'antd';
import { useTranslation } from 'react-i18next';
const token = window.localStorage.getItem('token');
const column = [
@ -38,7 +38,7 @@ const Index = ({params}) => {
const [tooltipTambah, setTooltipTambah] = useState(false)
const [totalPage, setTotalPage] = useState(0)
const [typeDialog, setTypeDialog] = useState('Save')
const { t } = useTranslation()
const pageName = params.name;
const config = {
@ -284,24 +284,24 @@ const Index = ({params}) => {
const renderTable = useMemo(() => {
const columns = [
{
title: 'Action',
title: t('action'),
dataIndex: '',
key: 'x',
render: (text, record) => <>
<Tooltip title="Delete">
<Tooltip title={t('delete')}>
<i id="TooltipDelete" className="fa fa-trash" style={{ color: 'red', marginRight: '10px', cursor: "pointer" }} onClick={() => handleDelete(text.id)}></i>
</Tooltip>
<Tooltip title="Edit">
<Tooltip title={t('edit')}>
<i id="TooltipEdit" className="fa fa-edit" style={{ color: 'green', cursor: "pointer" }} onClick={() => handleEdit(text)}></i>
</Tooltip>
</>,
},
{ title: 'Nama Menu', dataIndex: 'name', key: 'name' },
{ title: t('name'), dataIndex: 'name', key: 'name' },
{ title: 'Url', dataIndex: 'url', key: 'url' },
{ title: 'Ikon', dataIndex: 'icon', key: 'icon' },
{ title: t('icon'), dataIndex: 'icon', key: 'icon' },
{ title: 'Alias', dataIndex: 'alias_name', key: 'alias_name' },
{ title: 'Urutan', dataIndex: 'sequence', key: 'sequence' },
{ title: 'Parent Menu', dataIndex: 'join_first_name', key: 'join_first_name', render: (text, record) => (text ? text : "-") }
{ title: t('order'), dataIndex: 'sequence', key: 'sequence' },
{ title: t('parentMenu'), dataIndex: 'join_first_name', key: 'join_first_name', render: (text, record) => (text ? text : "-") }
];
return (
<Table
@ -323,12 +323,12 @@ const Index = ({params}) => {
showCancel
confirmBtnText="Delete"
confirmBtnBsStyle="danger"
title={`Apakah anda yakin?`}
title={t('deleteConfirm')}
onConfirm={onConfirmDelete}
onCancel={() => cancelDelete()}
focusCancelBtn
>
Data akan terhapus
{t('deleteMsg')}
</SweetAlert>
<DialogForm
openDialog={openDialog}
@ -344,13 +344,13 @@ const Index = ({params}) => {
<h4 className="capitalize">{pageName}</h4>
<Row>
<Col>
<Input onChange={handleSearch} value={search} type="text" name="search" id="search" placeholder={`Cari nama`} />
<Input onChange={handleSearch} value={search} type="text" name="search" id="search" placeholder={t('searchMenu')} />
</Col>
<Col>
<Tooltip title="Tambah Menu">
<Tooltip title={t('menuAdd')}>
<Button id="TooltipTambah" color="success" onClick={() => handleOpenDialog('Save')}><i className="fa fa-plus"></i></Button>
</Tooltip>
<Tooltip title="Export Excel">
<Tooltip title={t('exportExcel')}>
<Button style={{ marginLeft: "5px" }} id="TooltipExport" color="primary" onClick={() => handleExportExcel()}><i className="fa fa-print"></i></Button>
</Tooltip>
</Col>

17
src/views/Master/MasterRoles/DialogForm.js

@ -2,8 +2,9 @@ import React, { Component } from 'react'
import { Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap';
import { Button, Form, FormGroup, Label, Input } from 'reactstrap';
import 'antd/dist/antd.css';
import { withTranslation } from 'react-i18next';
export default class DialogForm extends Component {
class DialogForm extends Component {
constructor(props) {
super(props)
this.state = {
@ -78,15 +79,16 @@ export default class DialogForm extends Component {
}
renderForm = () => {
const { t } = this.props;
return (
<Form>
<FormGroup>
<Label>Nama</Label>
<Input type="text" value={this.state.name} onChange={(e)=>this.setState({ name:e.target.value })} placeholder="name roles.." />
<Label>{this.props.t('nameRole')}</Label>
<Input type="text" value={this.state.name} onChange={(e) => this.setState({ name: e.target.value })} placeholder={this.props.t('inputName')} />
</FormGroup>
<FormGroup>
<Label>Deskripsi</Label>
<Input type="text" value={this.state.description} onChange={(e)=>this.setState({ description:e.target.value })} placeholder="deskripsi.." />
<Label>{this.props.t('description')}</Label>
<Input type="text" value={this.state.description} onChange={(e) => this.setState({ description: e.target.value })} placeholder={this.props.t('inputDescription')} />
</FormGroup>
</Form>
)
@ -95,15 +97,16 @@ export default class DialogForm extends Component {
render() {
return (
<Modal isOpen={this.props.openDialog} toggle={this.props.toggleDialog}>
<ModalHeader toggle={this.props.closeDialog}>{this.props.typeDialog=="Save" ? "Tambah" : "Edit"} Roles</ModalHeader>
<ModalHeader toggle={this.props.closeDialog}>{this.props.typeDialog == "Save" ? "Tambah" : "Edit"} {this.props.t('roles')}</ModalHeader>
<ModalBody>
{this.renderForm()}
</ModalBody>
<ModalFooter>
<Button color="primary" onClick={() => this.handleSave()}>{this.props.typeDialog}</Button>{' '}
<Button color="secondary" onClick={() => this.handleCancel()}>Cancel</Button>
<Button color="secondary" onClick={() => this.handleCancel()}>{this.props.t('cancel')}</Button>
</ModalFooter>
</Modal>
)
}
}
export default withTranslation()(DialogForm);

10
src/views/Master/MasterRoles/DialogMenuRoles.js

@ -4,6 +4,7 @@ import { Button, Form, FormGroup, Label, Input } from 'reactstrap';
import 'antd/dist/antd.css';
import axios from 'axios';
import { MENU_SEARCH } from '../../../const/ApiConst.js';
import { withTranslation, WithTranslation } from 'react-i18next';
const BASE_URL = "http://siopas.co.id/custom-php/api/geohr/";
const token = window.localStorage.getItem('token');
@ -17,7 +18,7 @@ const config = {
}
};
export default class DialogMenuRoles extends Component {
class DialogMenuRoles extends Component {
constructor(props) {
super(props)
this.state = {
@ -200,7 +201,7 @@ export default class DialogMenuRoles extends Component {
render() {
return (
<Modal scrollable={true} isOpen={this.props.openDialog} toggle={this.props.toggleDialog}>
<ModalHeader toggle={this.props.closeDialog}>Roles Menu</ModalHeader>
<ModalHeader toggle={this.props.closeDialog}>{this.props.t('menuRoles')}</ModalHeader>
<ModalBody>
<Form>
<Table>
@ -223,10 +224,11 @@ export default class DialogMenuRoles extends Component {
</Form>
</ModalBody>
<ModalFooter>
<Button color="primary" onClick={() => this.handleSave()}>Save</Button>{' '}
<Button color="secondary" onClick={() => this.handleCancel()}>Cancel</Button>
<Button color="primary" onClick={() => this.handleSave()}>{this.props.t('save')}</Button>{' '}
<Button color="secondary" onClick={() => this.handleCancel()}>{this.props.t('cancel')}</Button>
</ModalFooter>
</Modal>
)
}
}
export default withTranslation()(DialogMenuRoles);

29
src/views/Master/MasterRoles/index.js

@ -9,6 +9,7 @@ import { Card, CardBody, CardHeader, Col, Row, Input } from 'reactstrap';
import { NotificationContainer, NotificationManager } from 'react-notifications';
import { Pagination, Tooltip, Table } from 'antd';
import { ROLE_ADD, ROLE_SEARCH, ROLE_EDIT, ROLE_DELETE, ROLEMENU_ADD, ROLEMENU_SEARCH, ROLEMENU_DELETE_ROLE } from '../../../const/ApiConst.js';
import { withTranslation } from 'react-i18next';
const token = window.localStorage.getItem('token');
@ -26,7 +27,7 @@ const momentFormat = 'HH:mm';
const LENGTH_DATA = 10
export default class index extends Component {
class index extends Component {
constructor(props) {
super(props)
this.state = {
@ -58,26 +59,26 @@ export default class index extends Component {
this.columns = [
{
title: 'Action',
title: this.props.t('action'),
dataIndex: '',
key: 'x',
className: 'nowrap',
render: (text, record) => <>
<Tooltip title="Roles Menu">
<Tooltip title={this.props.t('menuRoles')}>
<i className="cil-menu" style={{ color: 'green', marginRight: 10, cursor: "pointer" }} onClick={() => this.handleMenuRoles(text.id)}></i>
</Tooltip>
<Tooltip title="Hapus">
<Tooltip title={this.props.t('delete')}>
<i className="fa fa-trash" style={{ color: 'red', marginRight: 10, cursor: "pointer" }} onClick={() => this.handleDelete(text.id)}></i>
</Tooltip>
<Tooltip title="Edit">
<Tooltip title={this.props.t('edit')}>
<i className="fa fa-edit" style={{ color: 'green', cursor: "pointer" }} onClick={() => this.handleEdit(text)}></i>
</Tooltip>
</>,
},
{ title: 'Nama Role', dataIndex: 'name', key: 'name', className: "nowrap" },
{ title: 'Description', dataIndex: 'description', key: 'description' },
{ title: this.props.t('nameRole'), dataIndex: 'name', key: 'name', className: "nowrap" },
{ title: this.props.t('description'), dataIndex: 'description', key: 'description' },
]
}
@ -249,7 +250,7 @@ export default class index extends Component {
if (this.state.dataTable.length === 0) {
return (
<tr>
<td align="center" colSpan="3">Not Data Available</td>
<td align="center" colSpan="3">{this.props.t('noData')}</td>
</tr>
)
}
@ -361,6 +362,7 @@ export default class index extends Component {
}
render() {
const { t } = this.props;
const { tooltipTambah, tooltipExport, dialogMenuForm, dataTable, openDialog, currentPage, rowsPerPage, totalPage, search, tooltipEdit, tooltipDelete, tooltipMenu } = this.state
let noSeq = 0;
return (
@ -372,12 +374,12 @@ export default class index extends Component {
showCancel
confirmBtnText="Delete"
confirmBtnBsStyle="danger"
title="Are you sure?"
title={this.props.t('deleteConfirm')}
onConfirm={this.onConfirmDelete}
onCancel={() => this.setState({ alertDelete: false, idDelete: 0 })}
focusCancelBtn
>
Data tipe roles akan terhapus!!
{this.props.t('deleteMsg')}
</SweetAlert>
<SweetAlert
show={this.state.alertNotDelete}
@ -410,13 +412,13 @@ export default class index extends Component {
<h4>{this.props.params.name}</h4>
<Row>
<Col>
<Input onChange={this.handleSearch} value={search} type="text" name="search" id="search" placeholder="Cari Nama Roles" />
<Input onChange={this.handleSearch} value={search} type="text" name="search" id="search" placeholder={this.props.t('searchRoles')} />
</Col>
<Col>
<Tooltip title="Tambah Roles">
<Tooltip title={this.props.t('rolesAdd')}>
<Button id="TooltipTambah" color="success" onClick={() => this.handleOpenDialog('Save')}><i className="fa fa-plus"></i></Button>
</Tooltip>
<Tooltip title="Export Excel">
<Tooltip title={this.props.t('exportExcel')}>
<Button style={{ marginLeft: "5px" }} id="TooltipExport" color="primary" onClick={() => this.handleExportExcel()}><i className="fa fa-print"></i></Button>
</Tooltip>
</Col>
@ -447,3 +449,4 @@ export default class index extends Component {
)
}
}
export default withTranslation()(index);

10
src/views/Master/ProjectPhase/DialogForm.js

@ -7,12 +7,12 @@ import 'antd/dist/antd.css';
import InputColor from "./InputColor";
import "./styles.css";
import "rc-color-picker/assets/index.css";
import { useTranslation } from 'react-i18next';
const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdit }) => {
const [id, setId] = useState(0)
const [projectType, setProjectType] = useState('')
const [color, setColor] = useState('')
const { t } = useTranslation();
useEffect(() => {
if (typeDialog === "Edit") {
console.log("cel data Edit", dataEdit)
@ -56,13 +56,13 @@ const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdi
<Row>
<Col md={6}>
<FormGroup>
<Label className="capitalize">Phase</Label>
<Label className="capitalize">{t('phase')}</Label>
<Input type="text" value={projectType} onChange={(e) => setProjectType(e.target.value)} />
</FormGroup>
</Col>
<Col md={6}>
<FormGroup>
<Label className="capitalize">Warna</Label>
<Label className="capitalize">{t('color')}</Label>
<InputColor value={color} color={color} onChange={(e) => setColor(e.color)} />
</FormGroup>
</Col>
@ -80,7 +80,7 @@ const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdi
</ModalBody>
<ModalFooter>
<Button color="primary" onClick={() => handleSave()}>{typeDialog}</Button>{' '}
<Button className="capitalize" color="secondary" onClick={() => handleCancel()}>Batal</Button>
<Button className="capitalize" color="secondary" onClick={() => handleCancel()}>{t('cancel')}</Button>
</ModalFooter>
</Modal>
</>

112
src/views/Master/ProjectPhase/index.js

@ -6,9 +6,9 @@ import axios from "../../../const/interceptorApi"
import moment from 'moment'
import { Card, CardBody, CardHeader, Col, Row, Input } from 'reactstrap';
import { NotificationContainer, NotificationManager } from 'react-notifications';
import { PROJECT_PHASE_ADD, PROJECT_PHASE_EDIT, PROJECT_PHASE_DELETE, PROJECT_PHASE_SEARCH, BASE_OSPRO } from '../../../const/ApiConst';
import { PROJECT_PHASE_ADD, PROJECT_PHASE_EDIT, PROJECT_PHASE_DELETE, PROJECT_PHASE_SEARCH, PROJECT_PHASE_LIST, BASE_OSPRO } from '../../../const/ApiConst';
import { Pagination, Button, Tooltip, Table } from 'antd';
import { useTranslation } from 'react-i18next';
const token = window.localStorage.getItem('token');
const config = {
headers:
@ -40,6 +40,7 @@ const ProjectPhase = ({ params }) => {
const [clickOpenModal, setClickOpenModal] = useState(false)
const [currentPage, setCurrentPage] = useState(1)
const [dataEdit, setDataEdit] = useState([])
const [dataExport, setDataExport] = useState([])
const [dataTable, setDatatable] = useState([])
const [idDelete, setIdDelete] = useState(0)
const [idPhaseProject, setIdPhaseProject] = useState(0)
@ -49,22 +50,28 @@ const ProjectPhase = ({ params }) => {
const [search, setSearch] = useState('')
const [totalPage, setTotalPage] = useState(0)
const [typeDialog, setTypeDialog] = useState('Save')
const { t } = useTranslation()
useEffect(() => {
getDataProjectPhase()
}, [currentPage, rowsPerPage, search])
useEffect(() => {
const cekData = dataExport || []
if (cekData.length > 0) {
exportExcel()
}
}, [dataExport])
const getDataProjectPhase = async () => {
let start = 0;
if (currentPage !== 1 && currentPage > 1) {
start = (currentPage * rowsPerPage) - rowsPerPage
}
const payload = {
"columns": [
{
"name": "name",
"logic_operator": "like",
"logic_operator": "ilike",
"value": search,
"operator": "AND"
}
@ -80,18 +87,16 @@ const ProjectPhase = ({ params }) => {
"start": start
}
}
/*const result = await axios
.post(PROJECT_PHASE_SEARCH, payload, config)
.then(res => res)
.catch((error) => error.response);*/
//const result = await axios.post(PROJECT_PHASE_SEARCH, payload, HEADER).then(res => res).catch(err => err.response)
const URL = `${BASE_OSPRO}/api/project-phase/list`
const result = await axios.get(URL, HEADER).then(res => res).catch(err => err.response)
console.log(result)
// let url = `${BASE_OSPRO}/api/project-phase/list?start=${start}&length=${rowsPerPage}&orderby=id&asc=false&column=name&logic=ilike&value=${search}`
const result = await axios
.post(PROJECT_PHASE_SEARCH, payload, HEADER)
.then((res) => res)
.catch((err) => err.response);
if (result && result.data && result.data.code == 200) {
result.data.data.map((res) => {
res.key = res.id.toString()
});
setDatatable(result.data.data);
setTotalPage(result.data.totalRecord);
} else {
@ -104,7 +109,6 @@ const ProjectPhase = ({ params }) => {
setSearch(value);
setCurrentPage(1)
};
const handleOpenDialog = (type) => {
setOpenDialog(true)
setTypeDialog(type)
@ -113,19 +117,59 @@ const ProjectPhase = ({ params }) => {
const handleExportExcel = async () => {
let start = 0;
if (currentPage !== 1 && currentPage > 1) {
start = (currentPage * rowsPerPage) - rowsPerPage
}
const payload = {
"paging": { "start": start, "length": -1 },
"columns": [
{ "name": "name", "logic_operator": "ilike", "value": search, "operator": "AND" }
{
"name": "name",
"logic_operator": "like",
"value": search,
"operator": "AND"
}
],
"joins": [],
"orders": { "columns": ["id"], "ascending": false }
"orders": {
"ascending": true,
"columns": [
'id'
]
},
"paging": {
"length": rowsPerPage,
"start": start
}
}
const result = await axios
.post(PROJECT_PHASE_SEARCH, payload)
.post(PROJECT_PHASE_SEARCH, payload, HEADER)
.then(res => res)
.catch((error) => error.response);
if (result && result.data && result.data.code == 200) {
let resData = result.data.data;
const excelData = [];
resData.map((val, index) => {
let dataRow = {
"Nama": val.name,
"Color": val.color,
}
excelData.push(dataRow)
})
await setDataExport(excelData)
} else {
NotificationManager.error('Gagal Export Data!!', 'Failed');
}
}
const exportExcel = () => {
const dataExcel = dataExport || [];
const fileName = `Data ${pageName}.xlsx`;
const ws = XLSX.utils.json_to_sheet(dataExcel);
const wb = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(wb, ws, `Data ${pageName}`);
XLSX.writeFile(wb, fileName);
setDataExport([])
}
const handleEdit = (data) => {
@ -235,7 +279,7 @@ const ProjectPhase = ({ params }) => {
if (dataTable.length === 0) {
return (
<tr>
<td align="center" colSpan="3">Tidak ada data project phase</td>
<td align="center" colSpan="3">{t('noData')}</td>
</tr>
)
}
@ -244,22 +288,22 @@ const ProjectPhase = ({ params }) => {
const renderTable = useMemo(() => {
const columns = [
{
title: 'Action',
title: t('action'),
dataIndex: '',
key: 'x',
className: 'nowrap',
render: (text, record) => <>
<Tooltip title="Delete">
<Tooltip title={t('delete')}>
<i className="fa fa-trash" style={{ color: 'red', marginRight: '10px', cursor: "pointer" }} onClick={() => handleDelete(text.id)}></i>
</Tooltip>
<Tooltip title="Edit">
<Tooltip title={t('Edit')}>
<i className="fa fa-edit" style={{ color: 'green', cursor: "pointer" }} onClick={() => handleEdit(text)}></i>
</Tooltip>{" "}
</>,
},
{ title: 'Fase', dataIndex: 'name', key: 'name', className: "nowrap" },
{ title: t('phase'), dataIndex: 'name', key: 'name', className: "nowrap" },
{
title: 'Warna',
title: t('color'),
dataIndex: 'color',
key: 'color',
render: (text) => <>
@ -289,12 +333,12 @@ const ProjectPhase = ({ params }) => {
showCancel
confirmBtnText="Delete"
confirmBtnBsStyle="danger"
title={`Are you sure?`}
title={t('deleteConfirm')}
onConfirm={onConfirmDelete}
onCancel={() => cancelDelete()}
onCancel={cancelDelete}
focusCancelBtn
>
Delete this data
{t('deleteMsg')}
</SweetAlert>
<DialogForm
openDialog={openDialog}
@ -310,9 +354,15 @@ const ProjectPhase = ({ params }) => {
<h4 className="capitalize">{pageName}</h4>
<Row>
<Col>
<Tooltip title="Add new data">
<Input onChange={handleSearch} value={search} type="text" name="search" id="search" placeholder={t('searchPhase')} />
</Col>
<Col>
<Tooltip title={t('projectPhase')}>
<Button style={{ background: "#4caf50", color: "#fff" }} onClick={() => handleOpenDialog('Save')}><i className="fa fa-plus"></i></Button>
</Tooltip>
<Tooltip title={t('exportExcel')}>
<Button style={{ marginLeft: "5px" }} onClick={() => handleExportExcel()}><i className="fa fa-print"></i></Button>
</Tooltip>
</Col>
</Row>
</CardHeader>

17
src/views/Master/RoleProject/DialogForm.js

@ -2,8 +2,9 @@ import React, { Component } from 'react'
import { Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap';
import { Button, Form, FormGroup, Label, Input } from 'reactstrap';
import 'antd/dist/antd.css';
import { withTranslation } from 'react-i18next';
export default class DialogForm extends Component {
class DialogForm extends Component {
constructor(props) {
super(props)
this.state = {
@ -78,15 +79,16 @@ export default class DialogForm extends Component {
}
renderForm = () => {
const { t } = this.props;
return (
<Form>
<FormGroup>
<Label>Nama</Label>
<Input type="text" value={this.state.name} onChange={(e)=>this.setState({ name:e.target.value })} placeholder="name roles.." />
<Label>{this.props.t('name')}</Label>
<Input type="text" value={this.state.name} onChange={(e) => this.setState({ name: e.target.value })} placeholder={this.props.t('inputName')} />
</FormGroup>
<FormGroup>
<Label>Deskripsi</Label>
<Input type="text" value={this.state.description} onChange={(e)=>this.setState({ description:e.target.value })} placeholder="deskripsi.." />
<Label>{this.props.t('description')}</Label>
<Input type="text" value={this.state.description} onChange={(e) => this.setState({ description: e.target.value })} placeholder={this.props.t('inputDescription')} />
</FormGroup>
</Form>
)
@ -95,15 +97,16 @@ export default class DialogForm extends Component {
render() {
return (
<Modal isOpen={this.props.openDialog} toggle={this.props.toggleDialog}>
<ModalHeader toggle={this.props.closeDialog}>{this.props.typeDialog=="Save" ? "Tambah" : "Edit"} Project Role</ModalHeader>
<ModalHeader toggle={this.props.closeDialog}>{this.props.typeDialog == "Save" ? "Tambah" : "Edit"} {this.props.t('nameProjectRole')}</ModalHeader>
<ModalBody>
{this.renderForm()}
</ModalBody>
<ModalFooter>
<Button color="primary" onClick={() => this.handleSave()}>{this.props.typeDialog}</Button>{' '}
<Button color="secondary" onClick={() => this.handleCancel()}>Cancel</Button>
<Button color="secondary" onClick={() => this.handleCancel()}>{this.props.t('cancel')}</Button>
</ModalFooter>
</Modal>
)
}
}
export default withTranslation()(DialogForm);

28
src/views/Master/RoleProject/index.js

@ -8,7 +8,7 @@ import { Card, CardBody, CardHeader, Col, Row, Input } from 'reactstrap';
import { NotificationContainer, NotificationManager } from 'react-notifications';
import { PROJECT_ROLE_ADD, PROJECT_ROLE_SEARCH, PROJECT_ROLE_EDIT, PROJECT_ROLE_DELETE, ROLEMENU_ADD, ROLEMENU_SEARCH, ROLEMENU_DELETE_ROLE } from '../../../const/ApiConst.js';
import { Pagination, Tooltip, Table } from 'antd';
import { withTranslation } from 'react-i18next';
const token = window.localStorage.getItem('token');
const BASE_URL = "http://siopas.co.id/custom-php/api/geohr/";
@ -32,7 +32,7 @@ const column = [
const LENGTH_DATA = 10
export default class index extends Component {
class index extends Component {
constructor(props) {
super(props)
this.state = {
@ -63,23 +63,23 @@ export default class index extends Component {
}
this.columns = [
{
title: 'Action',
title: this.props.t('action'),
dataIndex: '',
key: 'x',
className: 'nowrap',
render: (text, record) => <>
<Tooltip title="Hapus">
<Tooltip title={this.props.t('delete')}>
<i className="fa fa-trash" style={{ color: 'red', marginRight: 10, cursor: "pointer" }} onClick={() => this.handleDelete(text.id)}></i>
</Tooltip>
<Tooltip title="Edit">
<Tooltip title={this.props.t('edit')}>
<i className="fa fa-edit" style={{ color: 'green', cursor: "pointer" }} onClick={() => this.handleEdit(text)}></i>
</Tooltip>
</>,
},
{ title: 'Nama Role', dataIndex: 'name', key: 'name', className: "nowrap" },
{ title: 'Description', dataIndex: 'description', key: 'description' },
{ title: this.props.t('name'), dataIndex: 'name', key: 'name', className: "nowrap" },
{ title: this.props.t('description'), dataIndex: 'description', key: 'description' },
];
}
@ -255,7 +255,7 @@ export default class index extends Component {
if (this.state.dataTable.length === 0) {
return (
<tr>
<td align="center" colSpan="3">Tidak ada data project role</td>
<td align="center" colSpan="3">{this.props.t('noData')}</td>
</tr>
)
}
@ -303,6 +303,7 @@ export default class index extends Component {
}
render() {
const { t } = this.props;
const { tooltipTambah, tooltipExport, dialogMenuForm, dataTable, openDialog, currentPage, rowsPerPage, totalPage, search, tooltipEdit, tooltipDelete, tooltipMenu } = this.state
let noSeq = 0;
return (
@ -314,12 +315,12 @@ export default class index extends Component {
showCancel
confirmBtnText="Delete"
confirmBtnBsStyle="danger"
title="Are you sure?"
title={this.props.t('deleteConfirm')}
onConfirm={this.onConfirmDelete}
onCancel={() => this.setState({ alertDelete: false, idDelete: 0 })}
focusCancelBtn
>
Data project role akan terhapus!!
{this.props.t('deleteMsg')}
</SweetAlert>
<SweetAlert
show={this.state.alertNotDelete}
@ -345,13 +346,13 @@ export default class index extends Component {
<h4>{this.props.params.name}</h4>
<Row>
<Col>
<Input onChange={this.handleSearch} value={search} type="text" name="search" id="search" placeholder="Cari Nama Project Role" />
<Input onChange={this.handleSearch} value={search} type="text" name="search" id="search" placeholder={this.props.t('searchProjectRoles')} />
</Col>
<Col>
<Tooltip title="Tambah Roles">
<Tooltip title={this.props.t('rolesAdd')}>
<Button id="TooltipTambah" color="success" onClick={() => this.handleOpenDialog('Save')}><i className="fa fa-plus"></i></Button>
</Tooltip>
<Tooltip title="Export Excel">
<Tooltip title={this.props.t('exportExcel')}>
<Button style={{ marginLeft: "5px" }} id="TooltipExport" color="primary" onClick={() => this.handleExportExcel()}><i className="fa fa-print"></i></Button>
</Tooltip>
</Col>
@ -382,3 +383,4 @@ export default class index extends Component {
)
}
}
export default withTranslation()(index);

44
src/views/Report/k3/index.js

@ -10,6 +10,7 @@ import { Pagination, Tooltip } from 'antd';
import { DatePicker, Select } from 'antd';
import * as XLSX from 'xlsx';
import { PRESENSI_SEARCH, PROYEK_SEARCH, USERPROYEK_SEARCH, K3_SEARCH, SIMPRO_BASE_IMAGE } from '../../../const/ApiConst.js';
import { withTranslation } from 'react-i18next';
const { RangePicker } = DatePicker;
const { Option } = Select
const token = localStorage.getItem('token');
@ -25,18 +26,11 @@ const BASE_URL = ""
const momentFormat = 'DD-MM-YY';
const column = [
{ name: "Nama Human Resource" },
{ name: "Tanggal Lapor"},
{ name: "Perlengkapan Dikenakan"},
{ name: "Perlengkapan Tidak Dikenakan"},
{ name: "Deskripsi" },
{ name: "Action" },
]
const LENGTH_DATA = 10
export default class index extends Component {
class index extends Component {
constructor(props) {
super(props)
this.state = {
@ -444,6 +438,7 @@ export default class index extends Component {
}
renderTable = () => {
const { t } = this.props;
const dataTable2 = this.state.dataTable || [];
return (
<tbody>
@ -451,7 +446,7 @@ export default class index extends Component {
return (
<tr key={n.id}>
<td>{n.join_first_name ? n.join_first_name : "-"}</td>
<td>{ n.report_date ? moment(n.report_date).format("DD-MM-YYYY HH:mm:ss") : "-" }</td>
<td>{n.report_date ? moment(n.report_date).format("DD-MM-YYYY") : "-"}</td>
<td>{n.k3_checked.length ? n.k3_checked.join() : "-"}</td>
<td>{n.k3_not_checked.length ? n.k3_not_checked.join() : "-"}</td>
<td>{n.description ? n.description : "-"}</td>
@ -517,6 +512,15 @@ export default class index extends Component {
delay = (ms) => new Promise(res => setTimeout(res, ms));
render() {
const column = [
{ name: this.props.t('nameHR') },
{ name: this.props.t('dateReport') },
{ name: this.props.t('gearUse') },
{ name: this.props.t('gearNotUse') },
{ name: this.props.t('description') },
{ name: this.props.t('action') },
]
const t = this.props;
const { tooltipExport, dataTable, openDialog, currentPage, rowsPerPage, totalPage, search, tooltipEdit, tooltipDelete } = this.state
return (
<div>
@ -527,12 +531,12 @@ export default class index extends Component {
showCancel
confirmBtnText="Delete"
confirmBtnBsStyle="danger"
title="Are you sure?"
title={this.props.t('deleteConfirm')}
onConfirm={this.onConfirmDelete}
onCancel={() => this.setState({ alertDelete: false, idDelete: 0 })}
focusCancelBtn
>
Data report k3 akan terhapus!!
{this.props.t('deleteMsg')}
</SweetAlert>
<DialogForm
openDialog={openDialog}
@ -545,33 +549,32 @@ export default class index extends Component {
<CardHeader style={{ display: "flex", justifyContent: "space-between" }}>
<h4>{this.props.params.name}</h4>
<div>
<Tooltip title="Export Excel">
<Tooltip title={this.props.t('exportExcel')}>
<Button id="TooltipExport" color="primary" onClick={() => this.handleExportExcel()}><i className="fa fa-print"></i></Button>
</Tooltip>
{/* <Button color="success" onClick={() => this.handleExportExcel()}>Export Excel</Button> */}
</div>
</CardHeader>
<CardBody>
<div style={{ display: "flex", justifyContent: "space-between" }}>
<div style={{ width: "100%", display: "flex", alignItems: "center" }}>
<div style={{ width: "100%", marginRight: "10px", maxWidth: "200px" }}>
<Select showSearch defaultValue={this.state.currentProyek} onChange={this.onChangeProyek} placeholder="Semua / Pilih Proyek >" style={{width:'100%'}} disabled={this.state.disableProyek} allowClear={true}>
<Select showSearch defaultValue={this.state.currentProyek} onChange={this.onChangeProyek} placeholder={this.props.t('searchProject')} style={{ width: '100%' }} disabled={this.state.disableProyek} allowClear={true}>
{this.setupSelectProyek()}
</Select>
</div>
<div style={{ width: "100%", marginRight: "10px", maxWidth: "200px" }}>
<Input type="select" onChange={(e) => this.handleChangeDay(e)} defaultValue={this.state.currentDay}>
<option value="today">Hari Ini</option>
<option value="3 day">3 Hari yang lalu</option>
<option value="7 day">7 Hari yang lalu</option>
<option value="today">{this.props.t('today')}</option>
<option value="3 day">{this.props.t('3days')}</option>
<option value="7 day">{this.props.t('7days')}</option>
</Input>
</div>
<div style={{ width: "50%", marginTop: "3px" }}>
<RangePicker size="default" allowClear={false} value={[this.state.startDate, this.state.endDate]} onChange={this.handleDatePicker} />{' '}
<Button color="primary" onClick={() => this.getDataLaporanK3()}>Cari</Button>
<Button color="primary" onClick={() => this.getDataLaporanK3()}>{this.props.t('search')}</Button>
</div>
</div>
<Input onChange={this.handleSearch} value={search} type="text" name="search" id="search" placeholder="Cari nama human resource" style={{ maxWidth: "200px", marginBottom: "20px" }} />
<Input onChange={this.handleSearch} value={search} type="text" name="search" id="search" placeholder={this.props.t('searchHR')} style={{ maxWidth: "200px", marginBottom: "20px" }} />
</div>
<Table responsive striped hover>
<thead>
@ -601,3 +604,4 @@ export default class index extends Component {
)
}
}
export default withTranslation()(index);

15
src/views/SimproV2/ChecklistK3/DialogForm.js

@ -4,13 +4,14 @@ import {
Button, Form, FormGroup, Label, Input, Col, Row
} from 'reactstrap';
import 'antd/dist/antd.css';
import { useTranslation } from 'react-i18next';
const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdit }) => {
const [id, setId] = useState(0)
const [name, setName] = useState('')
const [description, setDescription] = useState('')
const { t } = useTranslation()
useEffect(() => {
@ -62,14 +63,14 @@ const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdi
<Row>
<Col md={6}>
<FormGroup>
<Label className="capitalize">Name</Label>
<Input type="text" value={name} onChange={(e) => setName(e.target.value)} placeholder={`Input name...`} />
<Label className="capitalize">{t('name')}</Label>
<Input type="text" value={name} onChange={(e) => setName(e.target.value)} placeholder={t('inputName')} />
</FormGroup>
</Col>
<Col md={6}>
<FormGroup>
<Label className="capitalize">Description</Label>
<Input row="4" type="textarea" value={description} onChange={(e) => setDescription(e.target.value)} placeholder={`Description ...`} />
<Label className="capitalize">{t('description')}</Label>
<Input row="4" type="textarea" value={description} onChange={(e) => setDescription(e.target.value)} placeholder={t('inputDescription')} />
</FormGroup>
</Col>
</Row>
@ -81,13 +82,13 @@ const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdi
return (
<>
<Modal size="lg" isOpen={openDialog} toggle={toggleDialog}>
<ModalHeader className="capitalize" toggle={closeDialog}>{typeDialog == "Save" ? `Add` : "Edit"} Resource</ModalHeader>
<ModalHeader className="capitalize" toggle={closeDialog}>{typeDialog == "Save" ? `Add` : "Edit"} Checlist K3</ModalHeader>
<ModalBody>
{renderForm()}
</ModalBody>
<ModalFooter>
<Button color="primary" onClick={() => handleSave()}>{typeDialog}</Button>{' '}
<Button className="capitalize" color="secondary" onClick={() => handleCancel()}>Batal</Button>
<Button className="capitalize" color="secondary" onClick={() => handleCancel()}>{t('cancel')}</Button>
</ModalFooter>
</Modal>
</>

34
src/views/SimproV2/ChecklistK3/index.js

@ -9,6 +9,7 @@ import { Pagination, Button, Tooltip } from 'antd';
import {
CHECKLIST_K3_ADD, CHECKLIST_K3_EDIT, CHECKLIST_K3_DELETE, CHECKLIST_K3_SEARCH
} from '../../../const/ApiConst';
import { useTranslation } from 'react-i18next';
const token = window.localStorage.getItem('token');
const config = {
@ -18,10 +19,7 @@ const config = {
"Content-type": `application/json`
}
};
const column = [
{ name: "Nama" },
{ name: "Deskripsi" },
]
const ChecklistK3 = ({ params }) => {
const token = localStorage.getItem("token")
const HEADER = {
@ -45,7 +43,11 @@ const ChecklistK3 = ({ params }) => {
const [search, setSearch] = useState('')
const [totalPage, setTotalPage] = useState(0)
const [typeDialog, setTypeDialog] = useState('Save')
const { t } = useTranslation()
const column = [
{ name: t('name') },
{ name: t('description') },
]
useEffect(() => {
getDataChecklistK3()
}, [currentPage, rowsPerPage, search])
@ -240,7 +242,7 @@ const ChecklistK3 = ({ params }) => {
if (dataTable.length === 0) {
return (
<tr>
<td align="center" colSpan="3">Tidak ada data project type</td>
<td align="center" colSpan="3">{t('noData')}</td>
</tr>
)
}
@ -255,12 +257,12 @@ const ChecklistK3 = ({ params }) => {
showCancel
confirmBtnText="Delete"
confirmBtnBsStyle="danger"
title={`Are you sure?`}
title={t('deleteConfirm')}
onConfirm={onConfirmDelete}
onCancel={() => cancelDelete()}
focusCancelBtn
>
Delete this data
{t('deleteMsg')}
</SweetAlert>
<DialogForm
openDialog={openDialog}
@ -276,13 +278,13 @@ const ChecklistK3 = ({ params }) => {
<h4 className="capitalize">{pageName}</h4>
<Row>
<Col>
<Input onChange={handleSearch} value={search} type="text" name="search" id="search" placeholder={`Search checklist K3...`} />
<Input onChange={handleSearch} value={search} type="text" name="search" id="search" placeholder={t('searchChecklistK3')} />
</Col>
<Col>
<Tooltip title="Add Checklist K3">
<Tooltip title={t('ChecklistK3Add')}>
<Button style={{ background: "#4caf50", color: "#fff" }} onClick={() => handleOpenDialog('Save')}><i className="fa fa-plus"></i></Button>
</Tooltip>
<Tooltip title="Export Excel">
<Tooltip title={t('exportExcel')}>
<Button style={{ marginLeft: "5px" }} color="primary" onClick={() => handleExportExcel()}><i className="fa fa-print"></i></Button>
</Tooltip>
</Col>
@ -292,7 +294,7 @@ const ChecklistK3 = ({ params }) => {
<Table responsive striped hover>
<thead>
<tr>
<th>Aksi</th>
<th>{t('action')}</th>
{column.map((i, index) => {
return (
<th key={index} scope="row">{i.name}</th>
@ -306,11 +308,11 @@ const ChecklistK3 = ({ params }) => {
return (
<tr key={n.id}>
<td className='nowrap'>
<Tooltip title="Hapus">
<i id="TooltipDelete" className="cil-trash fa-lg" style={{ color: 'red', marginRight: 10, cursor: "pointer" }} onClick={() => handleDelete(n.id)}></i>
<Tooltip title={t('delete')}>
<i id="TooltipDelete" className="fa fa-trash" style={{ color: 'red', marginRight: 10, cursor: "pointer" }} onClick={() => handleDelete(n.id)}></i>
</Tooltip>
<Tooltip title="Edit">
<i id="TooltipEdit" className="cil-pencil fa-lg" style={{ color: 'green', cursor: "pointer" }} onClick={() => handleEdit(n)}></i>
<Tooltip title={t('edit')}>
<i id="TooltipEdit" className="fa fa-edit" style={{ color: 'green', cursor: "pointer" }} onClick={() => handleEdit(n)}></i>
</Tooltip>
</td>
<td>{n.name}</td>

20
src/views/SimproV2/CreatedProyek/DialogDocument.js

@ -82,8 +82,24 @@ const DialogDocument = ({ openDialog, closeDialog, toggleDialog, idTask, proyekN
}
const handleDownload = (id) => {
const urlDownload = DOCUMENT_DOWNLOAD(id);
window.open(urlDownload);
fetch(DOCUMENT_DOWNLOAD(id), {
headers: new Headers({
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
})
})
.then(response => {
response.blob().then(blob => {
let url = window.URL.createObjectURL(blob);
let a = document.createElement('a');
a.href = url;
a.download = 'Project Documents';
a.click();
});
//window.location.href = response.url;
});
// const urlDownload = DOCUMENT_DOWNLOAD(id);
// window.open(urlDownload);
}
const handleShow = (file) => {

20
src/views/SimproV2/CreatedProyek/index.js

@ -791,13 +791,25 @@ const CreatedProyek = ({ params, ...props }) => {
}
};
const handleExportPdf = () => {
const handleExportPdf = async () => {
const doc = new jsPDF();
const headers = [
["Project Name", "Budget", "Project Type", "PM", "Time Project"],
];
const data = dataTable.map((elt) => [
const payload = {
paging: { start: 0, length: -1 },
joins: [],
orders: { columns: ["id"], ascending: false },
};
const result = await axios
.post(PROYEK_SEARCH, payload, HEADER)
.then((res) => res)
.catch((error) => error.response);
if (result && result.data && result.data.code == 200) {
let resData = result.data.data;
const data = resData.map((elt) => [
elt.nama,
`Rp. ${formatThousand(elt.rencana_biaya)}`,
elt.join_second_name,
@ -816,8 +828,8 @@ const CreatedProyek = ({ params, ...props }) => {
head: headers,
body: data,
});
doc.save("table.pdf");
}
doc.save("Project.pdf");
// const unit = "pt";
// const size = "A4"; // Use A1, A2, A3 or A4
// const orientation = "portrait"; // portrait or landscape

21
src/views/SimproV2/Divisi/DialogForm.js

@ -3,17 +3,16 @@ import {
Modal, ModalHeader, ModalBody, ModalFooter,
Button, Form, FormGroup, Label, Input, Col, Row
} from 'reactstrap';
import { DatePicker, Tooltip, Select } from 'antd';
import { formatRupiah, formatNumber } from '../../../const/CustomFunc'
import moment from 'moment';
import { Select } from 'antd';
import 'antd/dist/antd.css';
import { useTranslation } from 'react-i18next';
const { Option } = Select
const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdit, dataDivisions }) => {
const [id, setId] = useState(0)
const [name, setName] = useState('')
const [parent, setParent] = useState(null)
const [description, setDescription] = useState('')
const { t } = useTranslation()
const onChangeParent = (val) => {
setParent(val)
@ -63,15 +62,15 @@ const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdi
<Row>
<Col md={6}>
<FormGroup>
<Label className="capitalize">Name</Label>
<Input type="text" value={name} onChange={(e) => setName(e.target.value)}/>
<Label className="capitalize">{t('name')}</Label>
<Input type="text" value={name} onChange={(e) => setName(e.target.value)} placeholder={t('inputName')} />
</FormGroup>
</Col>
</Row>
<Row>
<Col md={6}>
<FormGroup>
<Label className="capitalize">Parent</Label>
<Label className="capitalize">{t('nameDivision')}</Label>
<Select showSearch
value={parent}
onChange={onChangeParent}
@ -88,8 +87,8 @@ const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdi
<Row>
<Col md={6}>
<FormGroup>
<Label className="capitalize">Description</Label>
<Input row="4" type="textarea" value={description} onChange={(e) => setDescription(e.target.value)}/>
<Label className="capitalize">{t('description')}</Label>
<Input row="4" type="textarea" value={description} onChange={(e) => setDescription(e.target.value)} placeholder={t('inputDescription')} />
</FormGroup>
</Col>
</Row>
@ -101,13 +100,13 @@ const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdi
return (
<>
<Modal size="lg" isOpen={openDialog} toggle={toggleDialog}>
<ModalHeader className="capitalize" toggle={closeDialog}>{typeDialog == "Save" ? `Add` : "Edit"} Resource</ModalHeader>
<ModalHeader className="capitalize" toggle={closeDialog}>{typeDialog == "Save" ? `Add` : "Edit"} {t('division')}</ModalHeader>
<ModalBody>
{renderForm()}
</ModalBody>
<ModalFooter>
<Button color="primary" onClick={() => handleSave()}>{typeDialog}</Button>{' '}
<Button className="capitalize" color="secondary" onClick={() => handleCancel()}>Batal</Button>
<Button className="capitalize" color="secondary" onClick={() => handleCancel()}>{t('cancel')}</Button>
</ModalFooter>
</Modal>
</>

111
src/views/SimproV2/Divisi/index.js

@ -1,15 +1,13 @@
import * as XLSX from 'xlsx';
import DialogForm from './DialogForm';
import React, { useState, useEffect, useMemo } from 'react';
import React, { useState, useEffect } from 'react';
import SweetAlert from 'react-bootstrap-sweetalert';
import axios from "../../../const/interceptorApi"
import moment from 'moment'
import { Card, CardBody, CardHeader, Col, Row, Input, Table } from 'reactstrap';
import { DIVISI_LIST, DIVISI_ADD, DIVISI_EDIT, DIVISI_DELETE, DIVISI_SEARCH } from '../../../const/ApiConst';
import { DownloadOutlined } from '@ant-design/icons';
import { NotificationContainer, NotificationManager } from 'react-notifications';
import { Pagination, Button, Tooltip } from 'antd';
import { formatRupiah, formatNumber } from '../../../const/CustomFunc'
import { useTranslation } from 'react-i18next';
const url = "";
const proyek_id = localStorage.getItem('proyek_id');
@ -53,15 +51,24 @@ const ProjectType = ({ params }) => {
const [totalPage, setTotalPage] = useState(0)
const [typeDialog, setTypeDialog] = useState('Save')
const [dataDivisions, setDataDivisions] = useState([])
const { t } = useTranslation()
useEffect(() => {
getListDivision()
}, [])
useEffect(() => {
getDataProjectType()
}, [currentPage, rowsPerPage, search])
const getDataProjectType = async () => {
let start = 0;
useEffect(() => {
const cekData = dataExport || []
if (cekData.length > 0) {
exportExcel()
}
}, [dataExport])
const getListDivision = async () => {
const listDivions = await axios
.get(DIVISI_LIST, HEADER)
.then(res => res)
@ -76,11 +83,12 @@ const ProjectType = ({ params }) => {
} else {
NotificationManager.error('Gagal Mengambil Data!!', 'Failed');
}
}
const getDataProjectType = async () => {
let start = 0;
if (currentPage !== 1 && currentPage > 1) {
start = (currentPage * rowsPerPage) - rowsPerPage
}
const payload = {
"columns": [
{
@ -101,19 +109,78 @@ const ProjectType = ({ params }) => {
"start": start
}
}
const result = await axios
.post(DIVISI_SEARCH, payload, config)
.post(DIVISI_SEARCH, payload, HEADER)
.then(res => res)
.catch((error) => error.response);
if (result && result.data && result.data.code == 200) {
result.data.data.map((res) => {
res.key = res.id.toString()
});
setDatatable(result.data.data);
setTotalPage(result.data.totalRecord);
} else {
NotificationManager.error('Gagal Mengambil Data!!', 'Failed');
}
}
const handleExportExcel = async () => {
let start = 0;
if (currentPage !== 1 && currentPage > 1) {
start = (currentPage * rowsPerPage) - rowsPerPage
}
const payload = {
"columns": [
{
"name": "name",
"logic_operator": "like",
"value": search,
"operator": "AND"
}
],
"orders": {
"ascending": true,
"columns": [
'id'
]
},
"paging": {
"length": rowsPerPage,
"start": start
}
}
const result = await axios
.post(DIVISI_SEARCH, payload, HEADER)
.then(res => res)
.catch((error) => error.response);
if (result && result.data && result.data.code == 200) {
let resData = result.data.data;
const excelData = [];
resData.map((val, index) => {
let dataRow = {
"Nama Divisi": val.name,
"Deskripsi": val.description,
}
excelData.push(dataRow)
})
await setDataExport(excelData)
} else {
NotificationManager.error('Gagal Export Data!!', 'Failed');
}
}
const exportExcel = () => {
const dataExcel = dataExport || [];
const fileName = `Data ${pageName}.xlsx`;
const ws = XLSX.utils.json_to_sheet(dataExcel);
const wb = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(wb, ws, `Data ${pageName}`);
XLSX.writeFile(wb, fileName);
setDataExport([])
}
const handleSearch = e => {
const value = e.target.value
@ -212,7 +279,7 @@ const ProjectType = ({ params }) => {
if (dataTable.length === 0) {
return (
<tr>
<td align="center" colSpan="3">Belum ada data.</td>
<td align="center" colSpan="3">{t('noData')}</td>
</tr>
)
}
@ -227,12 +294,12 @@ const ProjectType = ({ params }) => {
showCancel
confirmBtnText="Delete"
confirmBtnBsStyle="danger"
title={`Are you sure?`}
title={t('deleteConfirm')}
onConfirm={onConfirmDelete}
onCancel={() => cancelDelete()}
onCancel={cancelDelete}
focusCancelBtn
>
Delete this data
{t('deleteMsg')}
</SweetAlert>
<DialogForm
openDialog={openDialog}
@ -249,9 +316,15 @@ const ProjectType = ({ params }) => {
<h4 className="capitalize">{pageName}</h4>
<Row>
<Col>
<Tooltip title="Add Data">
<Input onChange={handleSearch} value={search} type="text" name="search" id="search" placeholder={t('searchDivision')} />
</Col>
<Col>
<Tooltip title={t('divisionAdd')}>
<Button style={{ background: "#4caf50", color: "#fff" }} onClick={() => handleOpenDialog('Save')}><i className="fa fa-plus"></i></Button>
</Tooltip>
<Tooltip title={t('exportExcel')}>
<Button style={{ marginLeft: "5px" }} onClick={() => handleExportExcel()}><i className="fa fa-print"></i></Button>
</Tooltip>
</Col>
</Row>
</CardHeader>
@ -273,14 +346,14 @@ const ProjectType = ({ params }) => {
return (
<tr key={n.id}>
<td className='nowrap'>
<Tooltip title="Hapus">
<Tooltip title={t('delete')}>
<i id="TooltipDelete" className="fa fa-trash" style={{ color: 'red', marginRight: 10, cursor: "pointer" }} onClick={() => handleDelete(n.id)}></i>
</Tooltip>
<Tooltip title="Edit">
<Tooltip title={t('edit')}>
<i id="TooltipEdit" className="fa fa-edit" style={{ color: 'green', cursor: "pointer" }} onClick={() => handleEdit(n)}></i>
</Tooltip>
</td>
<td>{n.displayName}</td>
<td>{n.name}</td>
<td>{n.description}</td>
</tr>
)

8
src/views/SimproV2/Presence/DialogFoto.js

@ -4,6 +4,7 @@ import { Button } from 'reactstrap';
import { Image } from 'antd'
import { BASE_SIMPRO_LUMEN_IMAGE } from '../../../const/ApiConst';
import 'antd/dist/antd.css';
import { useTranslation } from 'react-i18next';
const DialogFoto = ({ openDialog, closeDialog, toggleDialog, dataImage }) => {
@ -11,7 +12,7 @@ const DialogFoto = ({ openDialog, closeDialog, toggleDialog, dataImage }) => {
const [urlImage, setUrlImage] = useState("")
const [dataReady, setDataReady] = useState(false)
const [hrName, setHrName] = useState(false)
const { t } = useTranslation()
useEffect(() => {
if (dataImage && dataImage != null) {
setUrlImage(dataImage.url);
@ -31,7 +32,6 @@ const DialogFoto = ({ openDialog, closeDialog, toggleDialog, dataImage }) => {
const renderModalBody = () => {
return (
<div style={{ width: '100%', display: 'flex', justifyContent: 'center', flexDirection: 'column', alignItems: 'flex-start' }}>
<h6>Foto Selfie :</h6>
<div style={{ width: '100%', display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
<Image
width={200}
@ -44,12 +44,12 @@ const DialogFoto = ({ openDialog, closeDialog, toggleDialog, dataImage }) => {
return (
<Modal isOpen={openDialog} toggle={toggleDialog}>
<ModalHeader className="capitalize" toggle={closeDialog}>Lihat Selfie Presensi | Nama Human Resource {hrName}</ModalHeader>
<ModalHeader className="capitalize" toggle={closeDialog}>{t('imageCheck')} | {t('nameHR')} {hrName}</ModalHeader>
<ModalBody>
{dataReady ? renderModalBody() : null}
</ModalBody>
<ModalFooter>
<Button className="capitalize" color="secondary" onClick={closeDialog}>Close</Button>
<Button className="capitalize" color="secondary" onClick={closeDialog}>{t('close')}</Button>
</ModalFooter>
</Modal>
)

47
src/views/SimproV2/Presence/index.js

@ -8,6 +8,7 @@ import { Pagination, Tooltip, Table, DatePicker } from 'antd';
import moment from 'moment';
import { PRESENCE_SEARCH, IMAGE_GET_BY_ID } from '../../../const/ApiConst.js';
import DialogFoto from './DialogFoto';
import { useTranslation } from 'react-i18next';
const { RangePicker } = DatePicker;
const token = window.localStorage.getItem('token');
@ -24,6 +25,7 @@ const Index = ({ params }) => {
const [currentDay, setCurrentDay] = useState("today")
const [dataImage, setDataImage] = useState(null)
const [openImage, setOpenImage] = useState(false)
const { t } = useTranslation()
const pageName = params.name;
const config = {
@ -196,12 +198,13 @@ const Index = ({ params }) => {
let dataRow = {
"NIK/ID Card": val.join_first_ktp_number ? val.join_first_ktp_number : '-',
"Nama Human Resource": val.join_first_name ? val.join_first_name : '',
"Tanggal Kehadiran": val.date_presence ? moment(val.date_presence).format("D-M-YYYY") : '-',
"Jam Masuk": val.clock_in ? moment(val.clock_in).format("D-M-YYYY HH:mm:ss") : '-',
"Jam Keluar": val.clock_out ? moment(val.clock_out).format("D-M-YYYY HH:mm:ss") : '-',
"Durasi Kerja": renderDurasiKerja(val.clock_in, val.clock_out),
"Clock-in Location": val.clock_in_loc && val.clock_in_loc !== '' ? val.clock_in_loc : '-',
"Clock-out Location": val.clock_out_loc && val.clock_out_loc !== '' ? val.clock_out_loc : '-'
"Lokasi Masuk": val.clock_in_loc && val.clock_in_loc !== '' ? val.clock_in_loc : '-',
"Lokasi Pulang": val.clock_out_loc && val.clock_out_loc !== '' ? val.clock_out_loc : '-',
"Area Kerja In": val.clock_in_boundary ? "Sesuai" : "Tidak Sesuai",
"Area Kerja Out": val.clock_out_boundary == null ? "-" : val.clock_out_boundary ? "Sesuai" : "Tidak Sesuai",
}
excelData.push(dataRow)
})
@ -229,26 +232,20 @@ const Index = ({ params }) => {
dataIndex: '',
key: 'x',
render: (text, record) => <>
{/* <Tooltip title="Delete">
<i id="TooltipDelete" className="fa fa-trash" style={{ color: 'red', marginRight: '10px', cursor: "pointer" }} onClick={() => handleDelete(text.id)}></i>
</Tooltip>
<Tooltip title="Edit">
<i id="TooltipEdit" className="fa fa-edit" style={{ color: 'green', cursor: "pointer" }} onClick={() => handleEdit(text)}></i>
</Tooltip> */}
<Tooltip title="Image">
<Tooltip title={t('image')}>
<i id="TooltipEdit" className="fa fa-image" style={{ color: 'green', cursor: "pointer" }} onClick={() => handleImage(text.id, text.join_first_name)}></i>
</Tooltip>
</>,
},
{ title: 'NIK/ID Card', dataIndex: 'join_first_ktp_number', key: 'join_first_ktp_number' },
{ title: 'Nama HR', dataIndex: 'join_first_name', key: 'join_first_name' },
{ title: 'Waktu Masuk', dataIndex: 'clock_in', key: 'clock_in', render: (text, record) => (<div style={{ whiteSpace: "nowrap" }}>{text ? moment(text).format("D-M-YYYY HH:mm:ss") : "-"}</div>) },
{ title: 'Waktu Keluar', dataIndex: 'clock_out', key: 'clock_out', render: (text, record) => (<div style={{ whiteSpace: "nowrap" }}>{text ? moment(text).format("D-M-YYYY HH:mm:ss") : "-"}</div>) },
{ title: 'Durasi Kerja', render: (text, record) => (<div style={{ whiteSpace: "nowrap" }}>{renderDurasiKerja(record.clock_in, record.clock_out)}</div>) },
{ title: 'Lokasi Masuk', dataIndex: 'clock_in_loc', key: 'clock_in_loc', render: (text, record) => <>{text && text !== '' ? text : '-'}</> },
{ title: 'Lokasi Pulang', dataIndex: 'clock_out_loc', key: 'clock_out_loc', render: (text, record) => <>{text && text !== '' ? text : '-'}</> },
{ title: 'Area Kerja In', dataIndex: 'clock_out_loc', key: 'clock_out_loc', render: (text, record) => (<div style={{ whiteSpace: "nowrap", textAlign: "center" }}>{record.clock_in_boundary ? <i className="fa fa-check-circle fa-lg" style={{ color: 'green' }}></i> : <i className="fa fa-times-circle fa-lg" style={{ color: 'red' }}></i>}</div>) },
{ title: 'Area Kerja Out', dataIndex: 'clock_out_loc', key: 'clock_out_loc', render: (text, record) => (<div style={{ whiteSpace: "nowrap", textAlign: "center" }}>{record.clock_out_boundary == null ? <i class="fa fa-window-minimize fa-lg" style={{ color: 'orange' }}></i> : record.clock_out_boundary ? <i className="fa fa-check-circle fa-lg" style={{ color: 'green' }}></i> : <i className="fa fa-times-circle fa-lg" style={{ color: 'red' }}></i>}</div>) },
{ title: t('nik'), dataIndex: 'join_first_ktp_number', key: 'join_first_ktp_number' },
{ title: t('nameHR'), dataIndex: 'join_first_name', key: 'join_first_name' },
{ title: t('presenceIn'), dataIndex: 'clock_in', key: 'clock_in', render: (text, record) => (<div style={{ whiteSpace: "nowrap" }}>{text ? moment(text).format("D-M-YYYY HH:mm:ss") : "-"}</div>) },
{ title: t('presenceOut'), dataIndex: 'clock_out', key: 'clock_out', render: (text, record) => (<div style={{ whiteSpace: "nowrap" }}>{text ? moment(text).format("D-M-YYYY HH:mm:ss") : "-"}</div>) },
{ title: t('workDuration'), render: (text, record) => (<div style={{ whiteSpace: "nowrap" }}>{renderDurasiKerja(record.clock_in, record.clock_out)}</div>) },
{ title: t('locIn'), dataIndex: 'clock_in_loc', key: 'clock_in_loc', render: (text, record) => <>{text && text !== '' ? text : '-'}</> },
{ title: t('locOut'), dataIndex: 'clock_out_loc', key: 'clock_out_loc', render: (text, record) => <>{text && text !== '' ? text : '-'}</> },
{ title: t('workAreaIn'), dataIndex: 'clock_out_loc', key: 'clock_out_loc', render: (text, record) => (<div style={{ whiteSpace: "nowrap", textAlign: "center" }}>{record.clock_in_boundary ? <i className="fa fa-check-circle fa-lg" style={{ color: 'green' }}></i> : <i className="fa fa-times-circle fa-lg" style={{ color: 'red' }}></i>}</div>) },
{ title: t('workAreaOut'), dataIndex: 'clock_out_loc', key: 'clock_out_loc', render: (text, record) => (<div style={{ whiteSpace: "nowrap", textAlign: "center" }}>{record.clock_out_boundary == null ? <i class="fa fa-window-minimize fa-lg" style={{ color: 'orange' }}></i> : record.clock_out_boundary ? <i className="fa fa-check-circle fa-lg" style={{ color: 'green' }}></i> : <i className="fa fa-times-circle fa-lg" style={{ color: 'red' }}></i>}</div>) },
];
return (
<Table
@ -302,7 +299,7 @@ const Index = ({ params }) => {
<h4 className="capitalize">{pageName}</h4>
<Row>
<Col>
<Tooltip title="Export Excel">
<Tooltip title={t('exportExcel')}>
<Button style={{ marginLeft: "5px" }} id="TooltipExport" color="primary" onClick={() => handleExportExcel()}><i className="fa fa-print"></i></Button>
</Tooltip>
</Col>
@ -313,17 +310,17 @@ const Index = ({ params }) => {
<div style={{ width: "100%", display: "flex", alignItems: "center" }}>
<div style={{ width: "100%", marginRight: "10px", maxWidth: "200px" }}>
<Input type="select" onChange={(e) => handleChangeDay(e)} defaultValue={currentDay}>
<option value="today">Hari Ini</option>
<option value="3 day">3 Hari yang lalu</option>
<option value="7 day">7 Hari yang lalu</option>
<option value="today">{t('today')}</option>
<option value="3 day">{t('3days')}</option>
<option value="7 day">{t('7days')}</option>
</Input>
</div>
<div style={{ width: "50%", marginTop: "3px" }}>
<RangePicker size="default" allowClear={false} value={[startDate, endDate]} onChange={handleDatePicker} />{' '}
<Button color="primary" onClick={() => getDataPresence()}>Cari</Button>
<Button color="primary" onClick={() => getDataPresence()}>{t('search')}</Button>
</div>
</div>
<Input onChange={handleSearch} value={search} type="text" name="search" id="search" placeholder="Cari nama human resource" style={{ maxWidth: "200px", marginBottom: "20px" }} />
<Input onChange={handleSearch} value={search} type="text" name="search" id="search" placeholder={t('searchHR')} style={{ maxWidth: "200px", marginBottom: "20px" }} />
</div>
{renderTable}
<Pagination

13
src/views/SimproV2/ProjectType/DialogForm.js

@ -7,6 +7,7 @@ import { DatePicker, Tooltip, Select } from 'antd';
import { formatRupiah, formatNumber } from '../../../const/CustomFunc'
import moment from 'moment';
import 'antd/dist/antd.css';
import { useTranslation } from 'react-i18next';
const { Option } = Select
const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdit }) => {
@ -15,7 +16,7 @@ const DialogForm = ({openDialog, closeDialog, toggleDialog, typeDialog, dataEdit
const [uom, setUom] = useState('')
const [description, setDescription] = useState('')
const [unitPrice, setUnitPrice] = useState()
const { t } = useTranslation();
@ -74,14 +75,14 @@ const DialogForm = ({openDialog, closeDialog, toggleDialog, typeDialog, dataEdit
<Row>
<Col md={6}>
<FormGroup>
<Label className="capitalize">Project Type</Label>
<Input type="text" value={projectType} onChange={(e)=> setProjectType(e.target.value)} placeholder={`Input material name...`}/>
<Label className="capitalize">{t('nameProjectType')}</Label>
<Input type="text" value={projectType} onChange={(e) => setProjectType(e.target.value)} placeholder={t('inputName')} />
</FormGroup>
</Col>
<Col md={6}>
<FormGroup>
<Label className="capitalize">Description</Label>
<Input row="4" type="textarea" value={description} onChange={(e)=> setDescription(e.target.value)} placeholder={`Description ...`} />
<Label className="capitalize">{t('description')}</Label>
<Input row="4" type="textarea" value={description} onChange={(e) => setDescription(e.target.value)} placeholder={t('inputDescription')} />
</FormGroup>
</Col>
</Row>
@ -99,7 +100,7 @@ const DialogForm = ({openDialog, closeDialog, toggleDialog, typeDialog, dataEdit
</ModalBody>
<ModalFooter>
<Button color="primary" onClick={() => handleSave()}>{typeDialog}</Button>{' '}
<Button className="capitalize" color="secondary" onClick={() => handleCancel()}>Batal</Button>
<Button className="capitalize" color="secondary" onClick={() => handleCancel()}>{t('cancel')}</Button>
</ModalFooter>
</Modal>

26
src/views/SimproV2/ProjectType/DialogInitialGantt.js

@ -8,6 +8,7 @@ import SweetAlert from 'react-bootstrap-sweetalert';
import { TEMPLATE_GANTT_ADD, TEMPLATE_GANTT_DELETE, TEMPLATE_GANTT_EDIT, TEMPLATE_GANTT_TREE } from '../../../const/ApiConst';
import axios from "../../../const/interceptorApi"
import DialogForm from './DialogFormInitial';
import { useTranslation } from 'react-i18next';
const DialogInitialGantt = ({ openDialog, closeDialog, toggleDialog, idTypeProject }) => {
const token = window.localStorage.getItem('token');
@ -26,7 +27,7 @@ const DialogInitialGantt = ({ openDialog, closeDialog, toggleDialog, idTypeProje
const [openDialogForm, setOpenDialogForm] = useState(false)
const [typeDialog, setTypeDialog] = useState("add")
const [dataEdit, setDataEdit] = useState([])
const { t } = useTranslation();
useEffect(() => {
if (idTypeProject && idTypeProject > 0) {
getDataInitial();
@ -149,12 +150,12 @@ const DialogInitialGantt = ({ openDialog, closeDialog, toggleDialog, idTypeProje
className: "nowrap",
render: (text, record) =>
<>
<Tooltip title="Delete Activity">
<Button size="small" size={"sm"} color='danger' onClick={() => handleDelete(text.id)}><i className="fa fa-trash"></i></Button>
</Tooltip>{" "}<Tooltip title="Add Activity">
<Button size="small" size={"sm"} color='primary' onClick={() => handleAddWithParent(text.id)}><i className="fa fa-plus"></i></Button>
</Tooltip>{" "}<Tooltip title="Edit Activity">
<Button size="small" size={"sm"} color='warning' onClick={() => handleEdit(text)}><i className="fa fa-edit"></i></Button>
<Tooltip title={t("delete")}>
<Button size="small" color='danger' onClick={() => handleDelete(text.id)}><i className="fa fa-trash"></i></Button>
</Tooltip>{" "}<Tooltip title={t("add")}>
<Button size="small" color='primary' onClick={() => handleAddWithParent(text.id)}><i className="fa fa-plus"></i></Button>
</Tooltip>{" "}<Tooltip title={t("edit")}>
<Button size="small" color='warning' onClick={() => handleEdit(text)}><i className="fa fa-edit"></i></Button>
</Tooltip>
</>
,
@ -181,12 +182,12 @@ const DialogInitialGantt = ({ openDialog, closeDialog, toggleDialog, idTypeProje
showCancel
confirmBtnText="Delete"
confirmBtnBsStyle="danger"
title={`Are you sure?`}
title={t('deleteConfirm')}
onConfirm={onConfirmDelete}
onCancel={cancelDelete}
focusCancelBtn
>
Delete this data
{t('deleteMsg')}
</SweetAlert>
<DialogForm
openDialog={openDialogForm}
@ -200,13 +201,16 @@ const DialogInitialGantt = ({ openDialog, closeDialog, toggleDialog, idTypeProje
<Modal size="lg" isOpen={openDialog} toggle={toggleDialog}>
{/* <ModalHeader className="capitalize" toggle={closeDialog}>Initial Gantt</ModalHeader> */}
<ModalHeader className="capitalize withBtn" toggle={closeDialog} style={{ width: "100%" }}>
<div>Template Gantt</div> <Button onClick={handleAdd} size='sm' color="primary"><i className='fa fa-plus'></i></Button>
<div>Template Gantt</div>
<Tooltip title={t("add")}>
<Button onClick={handleAdd} size='sm' color="primary"><i className='fa fa-plus'></i></Button>
</Tooltip>
</ModalHeader>
<ModalBody>
{renderTable}
</ModalBody>
<ModalFooter>
<Button className="capitalize" color="secondary" onClick={closeDialog}>Close</Button>
<Button className="capitalize" color="secondary" onClick={closeDialog}>{t('close')}</Button>
</ModalFooter>
</Modal>
</>

31
src/views/SimproV2/ProjectType/index.js

@ -10,7 +10,8 @@ import { DownloadOutlined } from '@ant-design/icons';
import { NotificationContainer, NotificationManager } from 'react-notifications';
import { PROJECT_TYPE_ADD, PROJECT_TYPE_EDIT, PROJECT_TYPE_DELETE, PROJECT_TYPE_SEARCH } from '../../../const/ApiConst';
import { Pagination, Button, Tooltip, Table } from 'antd';
import { useTranslation } from 'react-i18next';
import { handleChangeLng } from '../../../utils/LangUtils';
const url = "";
const proyek_id = localStorage.getItem('proyek_id');
const role_id = localStorage.getItem('role_id');
@ -54,7 +55,7 @@ const ProjectType = ({ params }) => {
const [search, setSearch] = useState('')
const [totalPage, setTotalPage] = useState(0)
const [typeDialog, setTypeDialog] = useState('Save')
const { t } = useTranslation();
useEffect(() => {
getDataProjectType()
}, [currentPage, rowsPerPage, search])
@ -286,7 +287,7 @@ const ProjectType = ({ params }) => {
if (dataTable.length === 0) {
return (
<tr>
<td align="center" colSpan="3">Tidak ada data project type</td>
<td align="center" colSpan="3">{t('noData')}</td>
</tr>
)
}
@ -295,15 +296,15 @@ const ProjectType = ({ params }) => {
const renderTable = useMemo(() => {
const columns = [
{
title: 'Action',
title: t('action'),
dataIndex: '',
key: 'x',
className: 'nowrap',
render: (text, record) => <>
<Tooltip title="Delete">
<Tooltip title={t('delete')}>
<i className="fa fa-trash" style={{ color: 'red', marginRight: '10px', cursor: "pointer" }} onClick={() => handleDelete(text.id)}></i>
</Tooltip>
<Tooltip title="Edit">
<Tooltip title={t('edit')}>
<i className="fa fa-edit" style={{ color: 'green', cursor: "pointer" }} onClick={() => handleEdit(text)}></i>
</Tooltip>{" "}
<Tooltip title="Template Gantt">
@ -311,8 +312,8 @@ const ProjectType = ({ params }) => {
</Tooltip>
</>,
},
{ title: 'Nama Role', dataIndex: 'name', key: 'name', className: "nowrap" },
{ title: 'Description', dataIndex: 'description', key: 'description' },
{ title: t('nameProjectType'), dataIndex: 'name', key: 'name', className: "nowrap" },
{ title: t('description'), dataIndex: 'description', key: 'description' },
];
return (
<Table
@ -334,12 +335,12 @@ const ProjectType = ({ params }) => {
showCancel
confirmBtnText="Delete"
confirmBtnBsStyle="danger"
title={`Are you sure?`}
title={t('deleteConfirm')}
onConfirm={onConfirmDelete}
onCancel={() => cancelDelete()}
focusCancelBtn
>
Delete this data
{t('deleteMsg')}
</SweetAlert>
<DialogForm
openDialog={openDialog}
@ -361,13 +362,17 @@ const ProjectType = ({ params }) => {
<h4 className="capitalize">{pageName}</h4>
<Row>
<Col>
<Input onChange={handleSearch} value={search} type="text" name="search" id="search" placeholder={`Search project type...`} />
<button onClick={() => handleChangeLng("en")}>EN</button>
<button onClick={() => handleChangeLng("id")}>ID</button>
</Col>
<Col>
<Input onChange={handleSearch} value={search} type="text" name="search" id="search" placeholder={t('searchType')} />
</Col>
<Col>
<Tooltip title="Add Material Resource">
<Tooltip title={t('projectType')}>
<Button style={{ background: "#4caf50", color: "#fff" }} onClick={() => handleOpenDialog('Save')}><i className="fa fa-plus"></i></Button>
</Tooltip>
<Tooltip title="Export Excel">
<Tooltip title={t('exportExcel')}>
<Button style={{ marginLeft: "5px" }} onClick={() => handleExportExcel()}><i className="fa fa-print"></i></Button>
</Tooltip>
</Col>

53
src/views/SimproV2/ResourceWorker/DialogForm.js

@ -40,7 +40,7 @@ const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdi
const [address, setAddress] = useState('')
const [divisionId, setDivisionId] = useState('')
const [statusResource, setStatusResource] = useState('active')
const [statusRestriction, setStatusRestriction] = useState(false)
useEffect(() => {
if (typeDialog === "Edit" || typeDialog === "Set") {
console.log("cel data Edit", dataEdit)
@ -112,8 +112,10 @@ const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdi
role_id: roleId,
divisi_id: divisionId,
address,
status_resource: statusResource
status_resource: statusResource,
status_boundary: statusRestriction
}
console.log(data)
if (birthDate && birthDate != "") {
data['birth_date'] = birthDate;
@ -154,7 +156,8 @@ const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdi
role_id: roleId,
divisi_id: divisionId,
address,
status_resource: statusResource
status_resource: statusResource,
status_boundary: statusRestriction
}
if (birthDate && birthDate != "") {
@ -197,41 +200,29 @@ const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdi
return (
<Form>
<Row>
<Col md={6}>
<FormGroup>
<Label className="capitalize">NIK (KTP / ID Card) *</Label>
{/* <Input type="text" value={ktpNumber} onChange={(e) => setKtpNumber(e.target.value.replace(/[^0-9]/g, ''))} placeholder={`Input NIK (KTP)...`} maxLength="16" /> */}
<Input type="text" value={ktpNumber} onChange={(e) => setKtpNumber(e.target.value)} placeholder={`Input NIK (KTP)...`} maxLength="16" />
</FormGroup>
</Col>
<Col md={6}>
<FormGroup>
<Label className="capitalize">Resource Name *</Label>
<Input type="text" value={resourceName} onChange={(e) => setResourceName(e.target.value)} placeholder={`Input resource name...`} />
</FormGroup>
<Col md={12}>
<span style={{ color: "red" }}>*</span> Wajib diisi.
</Col>
</Row>
{/* {typeDialog === 'Save' &&
<Row>
<Col md={6}>
<FormGroup>
<Label className="capitalize">Password</Label>
<Input type="password" value={password} onChange={(e)=> setPassword(e.target.value)} placeholder={`Password...`} />
<Label className="capitalize">NIK (KTP / ID Card) <span style={{ color: "red" }}>*</span></Label>
{/* <Input type="text" value={ktpNumber} onChange={(e) => setKtpNumber(e.target.value.replace(/[^0-9]/g, ''))} placeholder={`Input NIK (KTP)...`} maxLength="16" /> */}
<Input type="text" value={ktpNumber} onChange={(e) => setKtpNumber(e.target.value)} placeholder={`Input NIK (KTP)...`} maxLength="16" />
</FormGroup>
</Col>
<Col md={6}>
<FormGroup>
<Label className="capitalize">Retry Password</Label>
<Input type="password" value={retryPassword} onChange={(e)=> setRetryPassword(e.target.value)} placeholder={`Retry password...`} />
<Label className="capitalize">Resource Name <span style={{ color: "red" }}>*</span></Label>
<Input type="text" value={resourceName} onChange={(e) => setResourceName(e.target.value)} placeholder={`Input resource name...`} />
</FormGroup>
</Col>
</Row>
} */}
<Row>
<Col md={6}>
<FormGroup>
<Label className="capitalize">Employee Type *</Label>
<Label className="capitalize">Employee Type <span style={{ color: "red" }}>*</span></Label>
<Select showSearch value={employeeType} defaultValue={employeeType} onChange={(val) => setEmployeeType(val)} placeholder="Select Employee Type" style={{ width: '100%' }}>
<Option value={'employee'}>Employee</Option>
<Option value={'subcon'}>Subcon</Option>
@ -282,7 +273,7 @@ const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdi
<Row>
<Col md={6}>
<FormGroup>
<Label className="capitalize">Role *</Label>
<Label className="capitalize">Role <span style={{ color: "red" }}>*</span></Label>
<Select showSearch defaultValue={roleId} onChange={(val) => setRoleId(val)} placeholder="Select Role" style={{ width: '100%' }}>
{setupSelectRole()}
</Select>
@ -290,11 +281,7 @@ const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdi
</Col>
<Col md={6}>
<FormGroup>
<Label className="capitalize">Division *</Label>
{/* <Select style={{ width: "100%" }} defaultValue={statusResource} onChange={(e) => setStatusResource(e)}>
<Option value={'active'}>Active</Option>
<Option value={'inactive'}>Inactive</Option>
</Select> */}
<Label className="capitalize">Division <span style={{ color: "red" }}>*</span></Label>
<Select showSearch defaultValue={divisionId} onChange={(val) => setDivisionId(val)} placeholder="Select Division" style={{ width: '100%' }}>
{setupSelectDivisi()}
</Select>
@ -310,12 +297,20 @@ const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdi
<Option value={'inactive'}>Inactive</Option>
</Select>
</Col>
<Col md={6}>
<Label className="capitalize">Pembatasan wilayah kerja</Label>
<Select style={{ width: "100%" }} defaultValue={statusRestriction} onChange={(e) => setStatusRestriction(e)}>
<Option value={true}>Ya</Option>
<Option value={false}>Tidak</Option>
</Select>
</Col>
<Col md={6}>
<FormGroup>
<Label className="capitalize">Address</Label>
<Input type="textarea" value={address} onChange={(e) => setAddress(e.target.value)} placeholder="Input address..." />
</FormGroup>
</Col>
</Row>
</Form>
)

13
src/views/SimproV2/Satuan/DialogForm.js

@ -4,13 +4,14 @@ import {
Button, Form, FormGroup, Label, Input, Col, Row
} from 'reactstrap';
import 'antd/dist/antd.css';
import { useTranslation } from 'react-i18next';
const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdit }) => {
const [id, setId] = useState(0)
const [name, setName] = useState('')
const [description, setDescription] = useState('')
const { t } = useTranslation()
useEffect(() => {
@ -60,14 +61,14 @@ const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdi
<Row>
<Col md={6}>
<FormGroup>
<Label className="capitalize">Name</Label>
<Input type="text" value={name} onChange={(e) => setName(e.target.value)} placeholder={`Input name...`} />
<Label className="capitalize">{t('name')}</Label>
<Input type="text" value={name} onChange={(e) => setName(e.target.value)} placeholder={t('inputName')} />
</FormGroup>
</Col>
<Col md={6}>
<FormGroup>
<Label className="capitalize">Description</Label>
<Input row="4" type="textarea" value={description} onChange={(e) => setDescription(e.target.value)} placeholder={`Description ...`} />
<Input row="4" type="textarea" value={description} onChange={(e) => setDescription(e.target.value)} placeholder={t('inputDescription')} />
</FormGroup>
</Col>
</Row>
@ -79,13 +80,13 @@ const DialogForm = ({ openDialog, closeDialog, toggleDialog, typeDialog, dataEdi
return (
<>
<Modal size="lg" isOpen={openDialog} toggle={toggleDialog}>
<ModalHeader className="capitalize" toggle={closeDialog}>{typeDialog == "Save" ? `Add` : "Edit"} Resource</ModalHeader>
<ModalHeader className="capitalize" toggle={closeDialog}>{typeDialog == "Save" ? `Add` : "Edit"} {'uom'}</ModalHeader>
<ModalBody>
{renderForm()}
</ModalBody>
<ModalFooter>
<Button color="primary" onClick={() => handleSave()}>{typeDialog}</Button>{' '}
<Button className="capitalize" color="secondary" onClick={() => handleCancel()}>Batal</Button>
<Button className="capitalize" color="secondary" onClick={() => handleCancel()}>{t('cancel')}</Button>
</ModalFooter>
</Modal>
</>

30
src/views/SimproV2/Satuan/index.js

@ -7,6 +7,7 @@ import { Card, CardBody, CardHeader, Col, Row, Input, Table } from 'reactstrap';
import { NotificationContainer, NotificationManager } from 'react-notifications';
import { Pagination, Button, Tooltip } from 'antd';
import { SATUAN_ADD, SATUAN_EDIT, SATUAN_DELETE, SATUAN_SEARCH } from '../../../const/ApiConst';
import { useTranslation } from 'react-i18next';
const token = window.localStorage.getItem('token');
const config = {
@ -17,11 +18,6 @@ const config = {
}
};
const column = [
{ name: "Nama" },
{ name: "Deskripsi" },
]
const Satuan = ({ params }) => {
const token = localStorage.getItem("token")
const HEADER = {
@ -45,7 +41,7 @@ const Satuan = ({ params }) => {
const [search, setSearch] = useState('')
const [totalPage, setTotalPage] = useState(0)
const [typeDialog, setTypeDialog] = useState('Save')
const { t } = useTranslation()
useEffect(() => {
getDataSatuan()
}, [currentPage, rowsPerPage, search])
@ -57,6 +53,10 @@ const Satuan = ({ params }) => {
}
}, [dataExport])
const column = [
{ name: t('name') },
{ name: t('description') },
]
const getDataSatuan = async () => {
let start = 0;
@ -243,7 +243,7 @@ const Satuan = ({ params }) => {
if (dataTable.length === 0) {
return (
<tr>
<td align="center" colSpan="3">Tidak ada data project type</td>
<td align="center" colSpan="3">{t('noData')}</td>
</tr>
)
}
@ -258,12 +258,12 @@ const Satuan = ({ params }) => {
showCancel
confirmBtnText="Delete"
confirmBtnBsStyle="danger"
title={`Are you sure?`}
title={t('deleteConfirm')}
onConfirm={onConfirmDelete}
onCancel={() => cancelDelete()}
focusCancelBtn
>
Delete this data
{t('deleteMsg')}
</SweetAlert>
<DialogForm
openDialog={openDialog}
@ -279,13 +279,13 @@ const Satuan = ({ params }) => {
<h4 className="capitalize">{pageName}</h4>
<Row>
<Col>
<Input onChange={handleSearch} value={search} type="text" name="search" id="search" placeholder={`Pencarian`} />
<Input onChange={handleSearch} value={search} type="text" name="search" id="search" placeholder={t('searchUom')} />
</Col>
<Col>
<Tooltip title="Add UOM">
<Tooltip title={t('uomAdd')}>
<Button style={{ background: "#4caf50", color: "#fff" }} onClick={() => handleOpenDialog('Save')}><i className="fa fa-plus"></i></Button>
</Tooltip>
<Tooltip title="Export Excel">
<Tooltip title={t('exportExcel')}>
<Button style={{ marginLeft: "5px" }} color="primary" onClick={() => handleExportExcel()}><i className="fa fa-print"></i></Button>
</Tooltip>
</Col>
@ -295,7 +295,7 @@ const Satuan = ({ params }) => {
<Table responsive striped hover>
<thead>
<tr>
<th>Aksi</th>
<th>{t('action')}</th>
{column.map((i, index) => {
return (
<th key={index} scope="row">{i.name}</th>
@ -310,11 +310,11 @@ const Satuan = ({ params }) => {
<tr key={n.id}>
<td className='nowrap'>
<Tooltip title="Hapus">
<Tooltip title={t('delete')}>
<i id="TooltipDelete" className="fa fa-trash" style={{ color: 'red', marginRight: 10, cursor: "pointer" }} onClick={() => handleDelete(n.id)}></i>
</Tooltip>
<Tooltip title="Edit">
<Tooltip title={t('ubah')}>
<i id="TooltipEdit" className="fa fa-edit" style={{ color: 'green', cursor: "pointer" }} onClick={() => handleEdit(n)}></i>
</Tooltip>
</td>

Loading…
Cancel
Save