Before Width: | Height: | Size: 77 KiB |
Before Width: | Height: | Size: 65 KiB |
Before Width: | Height: | Size: 9.0 KiB |
Before Width: | Height: | Size: 37 KiB |
Before Width: | Height: | Size: 41 KiB |
Before Width: | Height: | Size: 96 KiB |
Before Width: | Height: | Size: 162 KiB |
Before Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 5.8 KiB |
Before Width: | Height: | Size: 173 KiB |
Before Width: | Height: | Size: 328 KiB |
@ -1,101 +0,0 @@ |
|||||||
{ |
|
||||||
"type": "FeatureCollection", |
|
||||||
"totalFeatures": "unknown", |
|
||||||
"features": [ |
|
||||||
{ |
|
||||||
"type": "Feature", |
|
||||||
"id": "paxel_area_code_20210426.5083", |
|
||||||
"geometry": { |
|
||||||
"type": "MultiPolygon", |
|
||||||
"coordinates": [ |
|
||||||
[ |
|
||||||
[ |
|
||||||
[ |
|
||||||
106.522270001261, |
|
||||||
-6.66321000044036 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.536260000699, |
|
||||||
-6.66382999935416 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.556582195013, |
|
||||||
-6.68497003983464 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.541310000657, |
|
||||||
-6.71486999865072 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.542630000375, |
|
||||||
-6.74058999942815 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.550740756582, |
|
||||||
-6.7473471734325 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.533284161136, |
|
||||||
-6.75148465469226 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.524773753407, |
|
||||||
-6.76232523192311 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.498398062322, |
|
||||||
-6.75218427058684 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.46682763259, |
|
||||||
-6.75104031405846 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.459021692598, |
|
||||||
-6.73381922767441 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.481760000125, |
|
||||||
-6.72494999944212 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.504030000085, |
|
||||||
-6.70412999979885 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.51431934866, |
|
||||||
-6.65951255475977 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.522270001261, |
|
||||||
-6.66321000044036 |
|
||||||
] |
|
||||||
] |
|
||||||
] |
|
||||||
] |
|
||||||
}, |
|
||||||
"geometry_name": "the_geom", |
|
||||||
"properties": { |
|
||||||
"fid": 37287, |
|
||||||
"desa": "MALASARI", |
|
||||||
"provinsi": "JAWA BARAT", |
|
||||||
"kabkot": "BOGOR", |
|
||||||
"kecamatan": "NANGGUNG", |
|
||||||
"post_code": null, |
|
||||||
"city_code": "", |
|
||||||
"ph_code": "", |
|
||||||
"locker_cod": "", |
|
||||||
"area_code": "", |
|
||||||
"id": 37287, |
|
||||||
"cluster_area_code": "", |
|
||||||
"service_ty": null |
|
||||||
} |
|
||||||
} |
|
||||||
], |
|
||||||
"crs": { |
|
||||||
"type": "name", |
|
||||||
"properties": { |
|
||||||
"name": "urn:ogc:def:crs:EPSG::4326" |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,7 +0,0 @@ |
|||||||
{ |
|
||||||
"routes": [ |
|
||||||
{ |
|
||||||
"geometry": "hldhx@lnau`BCG_EaC??cFjAwDjF??uBlKMd@}@z@??aC^yk@z_@se@b[wFdE??wFfE}NfIoGxB_I\\gG}@eHoCyTmPqGaBaHOoD\\??yVrGotA|N??o[N_STiwAtEmHGeHcAkiA}^aMyBiHOkFNoI`CcVvM??gG^gF_@iJwC??eCcA]OoL}DwFyCaCgCcCwDcGwHsSoX??wI_EkUFmq@hBiOqBgTwS??iYse@gYq\\cp@ce@{vA}s@csJqaE}{@iRaqE{lBeRoIwd@_T{]_Ngn@{PmhEwaA{SeF_u@kQuyAw]wQeEgtAsZ}LiCarAkVwI}D??_}RcjEinPspDwSqCgs@sPua@_OkXaMeT_Nwk@ob@gV}TiYs[uTwXoNmT{Uyb@wNg]{Nqa@oDgNeJu_@_G}YsFw]kDuZyDmm@i_@uyIJe~@jCg|@nGiv@zUi_BfNqaAvIow@dEed@dCcf@r@qz@Egs@{Acu@mCum@yIey@gGig@cK_m@aSku@qRil@we@{mAeTej@}Tkz@cLgr@aHko@qOmcEaJw~C{w@kai@qBchBq@kmBS{kDnBscBnFu_Dbc@_~QHeU`IuyDrC_}@bByp@fCyoA?qMbD}{AIkeAgBk_A_A{UsDke@gFej@qH{o@qGgb@qH{`@mMgm@uQus@kL{_@yOmd@ymBgwE}x@ouBwtA__DuhEgaKuWct@gp@cnBii@mlBa_@}|Asj@qrCg^eaC}L{dAaJ_aAiOyjByH{nAuYu`GsAwXyn@ywMyOyqD{_@cfIcDe}@y@aeBJmwA`CkiAbFkhBlTgdDdPyiB`W}xDnSa}DbJyhCrXitAhT}x@bE}Z_@qW_Kwv@qKaaAiBgXvIm}A~JovAxCqW~WanB`XewBbK{_A`K}fBvAmi@xBycBeCauBoF}}@qJioAww@gjHaPopA_NurAyJku@uGmi@cDs[eRaiBkQstAsQkcByNmaCsK_uBcJgbEw@gkB_@ypEqDoqSm@eZcDwjBoGw`BoMegBaU_`Ce_@_uBqb@ytBwkFqiT_fAqfEwe@mfCka@_eC_UmlB}MmaBeWkkDeHwqAoX}~DcBsZmLcxBqOwqE_DkyAuJmrJ\\o~CfIewG|YibQxBssB?es@qGciA}RorAoVajA_nAodD{[y`AgPqp@mKwr@ms@umEaW{dAmb@umAw|@ojBwzDaaJsmBwbEgdCsrFqhAihDquAi`Fux@}_Dui@_eB_u@guCuyAuiHukA_lKszAu|OmaA{wKm}@clHs_A_rEahCssKo\\sgBsSglAqk@yvDcS_wAyTwpBmPc|BwZknFoFscB_GsaDiZmyMyLgtHgQonHqT{hKaPg}Dqq@m~Hym@c`EuiBudIabB{hF{pWifx@snAw`GkFyVqf@y~BkoAi}Lel@wtc@}`@oaXi_C}pZsi@eqGsSuqJ|Lqeb@e]kgPcaAu}SkDwzGhn@gjYh\\qlNZovJieBqja@ed@siO{[ol\\kCmjMe\\isHorCmec@uLebB}EqiBaCg}@m@qwHrT_vFps@kkI`uAszIrpHuzYxx@e{Crw@kpDhN{wBtQarDy@knFgP_yCu\\wyCwyA{kHo~@omEoYmoDaEcPiuAosDagD}rO{{AsyEihCayFilLaiUqm@_bAumFo}DgqA_uByi@swC~AkzDlhA}xEvcBa}Cxk@ql@`rAo|@~bBq{@``Bye@djDww@z_C_cAtn@ye@nfC_eC|gGahH~s@w}@``Fi~FpnAooC|u@wlEaEedRlYkrPvKerBfYs}Arg@m}AtrCkzElw@gjBbh@woBhR{gCwGkgCc[wtCuOapAcFoh@uBy[yBgr@c@iq@o@wvEv@sp@`FajBfCaq@fIipAdy@ewJlUc`ExGuaBdEmbBpBssArAuqBBg}@s@g{AkB{bBif@_bYmC}r@kDgm@sPq_BuJ_s@{X_{AsK_d@eM{d@wVgx@oWcu@??aDmOkNia@wFoSmDyMyCkPiBePwAob@XcQ|@oNdCoSfFwXhEmOnLi\\lbAulB`X_d@|k@au@bc@oc@bqC}{BhwDgcD`l@ed@??bL{G|a@eTje@oS~]cLr~Bgh@|b@}Jv}EieAlv@sPluD{z@nzA_]`|KchCtd@sPvb@wSb{@ko@f`RooQ~e[upZbuIolI|gFafFzu@iq@nMmJ|OeJn^{Qjh@yQhc@uJ~j@iGdd@kAp~BkBxO{@|QsAfYgEtYiGd]}Jpd@wRhVoNzNeK`j@ce@vgK}cJnSoSzQkVvUm^rSgc@`Uql@xIq\\vIgg@~kDyq[nIir@jNoq@xNwc@fYik@tk@su@neB}uBhqEesFjoGeyHtCoD|D}Ed|@ctAbIuOzqB_}D~NgY`\\um@v[gm@v{Cw`G`w@o{AdjAwzBh{C}`Gpp@ypAxn@}mAfz@{bBbNia@??jIab@`CuOlC}YnAcV`@_^m@aeB}@yk@YuTuBg^uCkZiGk\\yGeY}Lu_@oOsZiTe[uWi[sl@mo@soAauAsrBgzBqgAglAyd@ig@asAcyAklA}qAwHkGi{@s~@goAmsAyDeEirB_{B}IsJuEeFymAssAkdAmhAyTcVkFeEoKiH}l@kp@wg@sj@ku@ey@uh@kj@}EsFmG}Jk^_r@_f@m~@ym@yjA??a@cFd@kBrCgDbAUnAcBhAyAdk@et@??kF}D??OL" |
|
||||||
} |
|
||||||
] |
|
||||||
} |
|
@ -1,257 +0,0 @@ |
|||||||
{ |
|
||||||
"geocoded_waypoints": [ |
|
||||||
{ |
|
||||||
"geocoder_status": "OK", |
|
||||||
"place_id": "ChIJT2zELKHxaS4RR5fpIKhtekA", |
|
||||||
"types": [ |
|
||||||
"street_address" |
|
||||||
] |
|
||||||
}, |
|
||||||
{ |
|
||||||
"geocoder_status": "OK", |
|
||||||
"place_id": "ChIJdbdzpG7xaS4RUCaaEC6NIOo", |
|
||||||
"types": [ |
|
||||||
"street_address" |
|
||||||
] |
|
||||||
} |
|
||||||
], |
|
||||||
"routes": [ |
|
||||||
{ |
|
||||||
"bounds": { |
|
||||||
"northeast": { |
|
||||||
"lat": -6.245234399999999, |
|
||||||
"lng": 106.8006477 |
|
||||||
}, |
|
||||||
"southwest": { |
|
||||||
"lat": -6.2623544, |
|
||||||
"lng": 106.7885345 |
|
||||||
} |
|
||||||
}, |
|
||||||
"copyrights": "Map data ©2021", |
|
||||||
"legs": [ |
|
||||||
{ |
|
||||||
"distance": { |
|
||||||
"text": "3.0 km", |
|
||||||
"value": 2992 |
|
||||||
}, |
|
||||||
"duration": { |
|
||||||
"text": "9 mins", |
|
||||||
"value": 552 |
|
||||||
}, |
|
||||||
"end_address": "Jl. Melawai 5 No.172, RT.3/RW.1, Melawai, Kec. Kby. Baru, Kota Jakarta Selatan, Daerah Khusus Ibukota Jakarta 12160, Indonesia", |
|
||||||
"end_location": { |
|
||||||
"lat": -6.245234399999999, |
|
||||||
"lng": 106.8006477 |
|
||||||
}, |
|
||||||
"start_address": "Jl. Bri Radio Dalam No.34/4, RT.2/RW.15, Gandaria Utara, Kec. Kby. Baru, Kota Jakarta Selatan, Daerah Khusus Ibukota Jakarta 12140, Indonesia", |
|
||||||
"start_location": { |
|
||||||
"lat": -6.2623544, |
|
||||||
"lng": 106.7885345 |
|
||||||
}, |
|
||||||
"steps": [ |
|
||||||
{ |
|
||||||
"distance": { |
|
||||||
"text": "1.5 km", |
|
||||||
"value": 1495 |
|
||||||
}, |
|
||||||
"duration": { |
|
||||||
"text": "4 mins", |
|
||||||
"value": 221 |
|
||||||
}, |
|
||||||
"end_location": { |
|
||||||
"lat": -6.2493628, |
|
||||||
"lng": 106.7918222 |
|
||||||
}, |
|
||||||
"html_instructions": "Head <b>north</b> on <b>Jl. Radio Dalam Raya</b> toward <b>Jl. Dwijaya Raya</b><div style=\"font-size:0.9em\">Pass by Alfamart Radio Dalam 4 (on the right)</div>", |
|
||||||
"polyline": { |
|
||||||
"points": "tbfe@icxjSOEs@M}@K}C]m@KUKg@G[EKAQCaAO_@GGAoB[SEaCa@e@Ga@GuB]yA[{Ba@iAYkA[a@KqAi@w@WaA[KCgAYQCMAw@I}AKUCeAOQCoAUMCoAQyAQc@EcBKe@C}@IC?g@E_AG" |
|
||||||
}, |
|
||||||
"start_location": { |
|
||||||
"lat": -6.2623544, |
|
||||||
"lng": 106.7885345 |
|
||||||
}, |
|
||||||
"travel_mode": "DRIVING" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"distance": { |
|
||||||
"text": "0.5 km", |
|
||||||
"value": 532 |
|
||||||
}, |
|
||||||
"duration": { |
|
||||||
"text": "2 mins", |
|
||||||
"value": 99 |
|
||||||
}, |
|
||||||
"end_location": { |
|
||||||
"lat": -6.2491213, |
|
||||||
"lng": 106.7959681 |
|
||||||
}, |
|
||||||
"html_instructions": "Turn <b>right</b> onto <b>Jl. Kramat Pela</b>", |
|
||||||
"maneuver": "turn-right", |
|
||||||
"polyline": { |
|
||||||
"points": "nqce@{wxjSMA\\sBJm@JOBQFa@h@cC@EN_@Le@Hc@?QBQBIDQ@Q@O?UASCSAMCGEGU]QSWWQUq@q@MGQEGAKA" |
|
||||||
}, |
|
||||||
"start_location": { |
|
||||||
"lat": -6.2493628, |
|
||||||
"lng": 106.7918222 |
|
||||||
}, |
|
||||||
"travel_mode": "DRIVING" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"distance": { |
|
||||||
"text": "25 m", |
|
||||||
"value": 25 |
|
||||||
}, |
|
||||||
"duration": { |
|
||||||
"text": "1 min", |
|
||||||
"value": 4 |
|
||||||
}, |
|
||||||
"end_location": { |
|
||||||
"lat": -6.249124, |
|
||||||
"lng": 106.7961904 |
|
||||||
}, |
|
||||||
"html_instructions": "Turn <b>right</b> toward <b>Jl. Barito II</b>", |
|
||||||
"maneuver": "turn-right", |
|
||||||
"polyline": { |
|
||||||
"points": "~oce@yqyjSAK@_@" |
|
||||||
}, |
|
||||||
"start_location": { |
|
||||||
"lat": -6.2491213, |
|
||||||
"lng": 106.7959681 |
|
||||||
}, |
|
||||||
"travel_mode": "DRIVING" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"distance": { |
|
||||||
"text": "0.2 km", |
|
||||||
"value": 154 |
|
||||||
}, |
|
||||||
"duration": { |
|
||||||
"text": "1 min", |
|
||||||
"value": 36 |
|
||||||
}, |
|
||||||
"end_location": { |
|
||||||
"lat": -6.249612600000001, |
|
||||||
"lng": 106.7974484 |
|
||||||
}, |
|
||||||
"html_instructions": "Turn <b>right</b> onto <b>Jl. Barito II</b>", |
|
||||||
"maneuver": "turn-right", |
|
||||||
"polyline": { |
|
||||||
"points": "~oce@esyjS`@_@P[JSJ]DM@KH}@Bu@" |
|
||||||
}, |
|
||||||
"start_location": { |
|
||||||
"lat": -6.249124, |
|
||||||
"lng": 106.7961904 |
|
||||||
}, |
|
||||||
"travel_mode": "DRIVING" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"distance": { |
|
||||||
"text": "0.4 km", |
|
||||||
"value": 414 |
|
||||||
}, |
|
||||||
"duration": { |
|
||||||
"text": "1 min", |
|
||||||
"value": 77 |
|
||||||
}, |
|
||||||
"end_location": { |
|
||||||
"lat": -6.2459198, |
|
||||||
"lng": 106.7979545 |
|
||||||
}, |
|
||||||
"html_instructions": "Turn <b>left</b> onto <b>Jl. Panglima Polim</b> (signs for <b>Senayan</b>/<wbr/><b>Semanggi</b>)<div style=\"font-size:0.9em\">Pass by ATM Bank UOB (on the left)</div>", |
|
||||||
"maneuver": "turn-left", |
|
||||||
"polyline": { |
|
||||||
"points": "`sce@a{yjSmBMgDUyBQGAyDW[CgAIk@E" |
|
||||||
}, |
|
||||||
"start_location": { |
|
||||||
"lat": -6.249612600000001, |
|
||||||
"lng": 106.7974484 |
|
||||||
}, |
|
||||||
"travel_mode": "DRIVING" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"distance": { |
|
||||||
"text": "0.2 km", |
|
||||||
"value": 220 |
|
||||||
}, |
|
||||||
"duration": { |
|
||||||
"text": "1 min", |
|
||||||
"value": 48 |
|
||||||
}, |
|
||||||
"end_location": { |
|
||||||
"lat": -6.245905899999999, |
|
||||||
"lng": 106.7999397 |
|
||||||
}, |
|
||||||
"html_instructions": "Turn <b>right</b> onto <b>Jl. Melawai Raya</b><div style=\"font-size:0.9em\">Pass by MM Juice Melawai (on the right)</div>", |
|
||||||
"maneuver": "turn-right", |
|
||||||
"polyline": { |
|
||||||
"points": "~{be@e~yjS?SAq@?S?A?]Cg@AKD_F" |
|
||||||
}, |
|
||||||
"start_location": { |
|
||||||
"lat": -6.2459198, |
|
||||||
"lng": 106.7979545 |
|
||||||
}, |
|
||||||
"travel_mode": "DRIVING" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"distance": { |
|
||||||
"text": "74 m", |
|
||||||
"value": 74 |
|
||||||
}, |
|
||||||
"duration": { |
|
||||||
"text": "1 min", |
|
||||||
"value": 33 |
|
||||||
}, |
|
||||||
"end_location": { |
|
||||||
"lat": -6.2452361, |
|
||||||
"lng": 106.7999455 |
|
||||||
}, |
|
||||||
"html_instructions": "Turn <b>left</b> after HAZEL Brew Coffee (on the right)", |
|
||||||
"maneuver": "turn-left", |
|
||||||
"polyline": { |
|
||||||
"points": "|{be@sjzjSO?C?_@?qAA" |
|
||||||
}, |
|
||||||
"start_location": { |
|
||||||
"lat": -6.245905899999999, |
|
||||||
"lng": 106.7999397 |
|
||||||
}, |
|
||||||
"travel_mode": "DRIVING" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"distance": { |
|
||||||
"text": "78 m", |
|
||||||
"value": 78 |
|
||||||
}, |
|
||||||
"duration": { |
|
||||||
"text": "1 min", |
|
||||||
"value": 34 |
|
||||||
}, |
|
||||||
"end_location": { |
|
||||||
"lat": -6.245234399999999, |
|
||||||
"lng": 106.8006477 |
|
||||||
}, |
|
||||||
"html_instructions": "Turn <b>right</b> onto <b>Jl. Melawai 9</b><div style=\"font-size:0.9em\">Destination will be on the left</div>", |
|
||||||
"maneuver": "turn-right", |
|
||||||
"polyline": { |
|
||||||
"points": "vwbe@ujzjSAkC" |
|
||||||
}, |
|
||||||
"start_location": { |
|
||||||
"lat": -6.2452361, |
|
||||||
"lng": 106.7999455 |
|
||||||
}, |
|
||||||
"travel_mode": "DRIVING" |
|
||||||
} |
|
||||||
], |
|
||||||
"traffic_speed_entry": [], |
|
||||||
"via_waypoint": [] |
|
||||||
} |
|
||||||
], |
|
||||||
"overview_polyline": { |
|
||||||
"points": "tbfe@icxjScAS{Ei@m@KUKcAM_C]mGeAgAOoEy@eE{@mBg@iCaAmA_@yA]eAKsBOwAS}AYiDc@kF_@yBOh@aDJOBQFa@h@cCPe@ViABc@H[Ba@Ai@Ea@IOg@q@i@m@q@q@MGYGKAAK@_@`@_@\\o@Pk@JiABu@mBMaHg@eHg@k@E?SAeAEsAD_FO?c@?qAAAkC" |
|
||||||
}, |
|
||||||
"summary": "Jl. Radio Dalam Raya", |
|
||||||
"warnings": [], |
|
||||||
"waypoint_order": [] |
|
||||||
} |
|
||||||
], |
|
||||||
"status": "OK" |
|
||||||
} |
|
@ -1,259 +0,0 @@ |
|||||||
{ |
|
||||||
"type": "FeatureCollection", |
|
||||||
"features": [ |
|
||||||
{ |
|
||||||
"id": "sales.1", |
|
||||||
"geometry_name": "the_geom", |
|
||||||
"type": "Feature", |
|
||||||
"properties": { |
|
||||||
"id": "sales.1", |
|
||||||
"name": "Sales 1" |
|
||||||
}, |
|
||||||
"geometry": { |
|
||||||
"type": "LineString", |
|
||||||
"coordinates": [ |
|
||||||
[ |
|
||||||
106.78853, |
|
||||||
-6.26235 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.78863, |
|
||||||
-6.26201 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.78884, |
|
||||||
-6.26091 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.7889, |
|
||||||
-6.26068 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.78896, |
|
||||||
-6.26057 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.78903, |
|
||||||
-6.26023 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.78918, |
|
||||||
-6.25959 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.78953, |
|
||||||
-6.25824 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.78961, |
|
||||||
-6.25788 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.7899, |
|
||||||
-6.25684 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.7902, |
|
||||||
-6.25585 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.7904, |
|
||||||
-6.2553 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.79073, |
|
||||||
-6.25461 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.79089, |
|
||||||
-6.25422 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.79104, |
|
||||||
-6.25377 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.7911, |
|
||||||
-6.25342 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.79118, |
|
||||||
-6.25284 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.79128, |
|
||||||
-6.2524 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.79141, |
|
||||||
-6.25193 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.79159, |
|
||||||
-6.25108 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.79175, |
|
||||||
-6.2499 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.79183, |
|
||||||
-6.24929 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.79264, |
|
||||||
-6.2495 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.79272, |
|
||||||
-6.24956 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.79281, |
|
||||||
-6.24958 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.79298, |
|
||||||
-6.24962 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.79364, |
|
||||||
-6.24983 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.79383, |
|
||||||
-6.24992 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.7942, |
|
||||||
-6.25004 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.79438, |
|
||||||
-6.25006 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.79452, |
|
||||||
-6.25011 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.79469, |
|
||||||
-6.25013 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.7949, |
|
||||||
-6.25012 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.79507, |
|
||||||
-6.25009 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.79515, |
|
||||||
-6.25004 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.7954, |
|
||||||
-6.24984 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.79563, |
|
||||||
-6.24963 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.79588, |
|
||||||
-6.24938 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.79592, |
|
||||||
-6.24931 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.79596, |
|
||||||
-6.24918 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.79597, |
|
||||||
-6.24912 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.79603, |
|
||||||
-6.24911 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.79619, |
|
||||||
-6.24912 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.79635, |
|
||||||
-6.24929 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.79659, |
|
||||||
-6.24944 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.79681, |
|
||||||
-6.24953 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.79718, |
|
||||||
-6.24959 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.79745, |
|
||||||
-6.24961 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.79752, |
|
||||||
-6.24906 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.79772, |
|
||||||
-6.24761 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.79792, |
|
||||||
-6.24614 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.79795, |
|
||||||
-6.24592 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.79805, |
|
||||||
-6.24592 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.7984, |
|
||||||
-6.24591 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.79882, |
|
||||||
-6.24588 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.79994, |
|
||||||
-6.24591 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.79994, |
|
||||||
-6.24583 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.79994, |
|
||||||
-6.24565 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.79995, |
|
||||||
-6.24524 |
|
||||||
], |
|
||||||
[ |
|
||||||
106.80065, |
|
||||||
-6.24523 |
|
||||||
] |
|
||||||
] |
|
||||||
} |
|
||||||
} |
|
||||||
] |
|
||||||
} |
|
@ -1,85 +0,0 @@ |
|||||||
{ |
|
||||||
"type": "FeatureCollection", |
|
||||||
"features": [ |
|
||||||
{ |
|
||||||
"id": "sales.1", |
|
||||||
"geometry_name": "the_geom", |
|
||||||
"type": "Feature", |
|
||||||
"properties": { |
|
||||||
"id": "sales.1", |
|
||||||
"name": "Sales 1" |
|
||||||
}, |
|
||||||
"geometry": { |
|
||||||
"type": "Point", |
|
||||||
"coordinates": [ |
|
||||||
106.79569244384766, |
|
||||||
-6.2395378839383016 |
|
||||||
] |
|
||||||
} |
|
||||||
}, |
|
||||||
{ |
|
||||||
"id": "sales.2", |
|
||||||
"geometry_name": "the_geom", |
|
||||||
"type": "Feature", |
|
||||||
"properties": { |
|
||||||
"id": "sales.2", |
|
||||||
"name": "Sales 2" |
|
||||||
}, |
|
||||||
"geometry": { |
|
||||||
"type": "Point", |
|
||||||
"coordinates": [ |
|
||||||
106.78788185119627, |
|
||||||
-6.2620624718682665 |
|
||||||
] |
|
||||||
} |
|
||||||
}, |
|
||||||
{ |
|
||||||
"id": "sales.3", |
|
||||||
"geometry_name": "the_geom", |
|
||||||
"type": "Feature", |
|
||||||
"properties": { |
|
||||||
"id": "sales.3", |
|
||||||
"name": "Sales 3" |
|
||||||
}, |
|
||||||
"geometry": { |
|
||||||
"type": "Point", |
|
||||||
"coordinates": [ |
|
||||||
106.81011199951172, |
|
||||||
-6.249349850172153 |
|
||||||
] |
|
||||||
} |
|
||||||
}, |
|
||||||
{ |
|
||||||
"id": "sales.4", |
|
||||||
"geometry_name": "the_geom", |
|
||||||
"type": "Feature", |
|
||||||
"properties": { |
|
||||||
"id": "sales.4", |
|
||||||
"name": "Sales 4" |
|
||||||
}, |
|
||||||
"geometry": { |
|
||||||
"type": "Point", |
|
||||||
"coordinates": [ |
|
||||||
106.81543350219727, |
|
||||||
-6.215817763782759 |
|
||||||
] |
|
||||||
} |
|
||||||
}, |
|
||||||
{ |
|
||||||
"id": "sales.5", |
|
||||||
"geometry_name": "the_geom", |
|
||||||
"type": "Feature", |
|
||||||
"properties": { |
|
||||||
"id": "sales.5", |
|
||||||
"name": "Sales 5" |
|
||||||
}, |
|
||||||
"geometry": { |
|
||||||
"type": "Point", |
|
||||||
"coordinates": [ |
|
||||||
106.80745124816895, |
|
||||||
-6.2746041510497355 |
|
||||||
] |
|
||||||
} |
|
||||||
} |
|
||||||
] |
|
||||||
} |
|
@ -1,37 +0,0 @@ |
|||||||
import React from 'react'; |
|
||||||
const ChatDashboard = (props) => { |
|
||||||
const { dataParams } = props; |
|
||||||
|
|
||||||
const renderComment = (items) => { |
|
||||||
return items.map((item, idx) => { |
|
||||||
return ( |
|
||||||
<div className="chat-content" key={idx}> |
|
||||||
<div className='chat-body'> |
|
||||||
<div className='chat-header'> |
|
||||||
{item.comment_by} |
|
||||||
</div> |
|
||||||
<div className='chat-body-content'> |
|
||||||
{item.comment} |
|
||||||
</div> |
|
||||||
<div className='chat-footer'> |
|
||||||
{item.comment_created} |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
) |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
return ( |
|
||||||
<div style={{ margin: '0 5px' }} className="box-header-dashboard-project"> |
|
||||||
<div style={{ display: 'flex', justifyContent: 'center' }}> |
|
||||||
<div style={{ marginBottom: '5px', fontSize: '0.8rem', fontWeight: '500' }}>COMMUNICATION</div> |
|
||||||
</div> |
|
||||||
<div className='chat'> |
|
||||||
{renderComment(dataParams)} |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
); |
|
||||||
} |
|
||||||
export default ChatDashboard; |
|
@ -1,34 +0,0 @@ |
|||||||
import React, { useEffect, useMemo, useState } from 'react'; |
|
||||||
import Timeline from 'react-calendar-timeline' |
|
||||||
// make sure you include the timeline stylesheet or the timeline will not be styled
|
|
||||||
import 'react-calendar-timeline/lib/Timeline.css' |
|
||||||
import { useParams } from 'react-router-dom'; |
|
||||||
// import moment from 'moment';
|
|
||||||
// import { USER_VERSION_GANTT_SEARCH, BASE_SIMPRO_LUMEN } from '../../../const/ApiConst';
|
|
||||||
// import axios from "../../../const/interceptorApi"
|
|
||||||
const token = localStorage.getItem("token") |
|
||||||
|
|
||||||
const Gantt = (props) => { |
|
||||||
const { ID } = useParams(); |
|
||||||
const { GANTTID } = useParams(); |
|
||||||
const url = `https://konstruksi-gantt.ospro.id/view-mode/index.html?base_url=${BASE_OSPRO}/api&gantt_id=${GANTT_ID}&proyek_id=${PROJECT_ID}&token=${token}&ro=1` |
|
||||||
|
|
||||||
const RenderGantt = () => ( |
|
||||||
<iframe |
|
||||||
id="frame-gantt" |
|
||||||
src={url} |
|
||||||
style={{ |
|
||||||
width: '100%', |
|
||||||
height: '50vh', |
|
||||||
}} |
|
||||||
scrolling="no" |
|
||||||
frameBorder="0" |
|
||||||
></iframe> |
|
||||||
) |
|
||||||
return ( |
|
||||||
<div> |
|
||||||
<RenderGantt /> |
|
||||||
</div> |
|
||||||
); |
|
||||||
} |
|
||||||
export default Gantt; |
|
@ -1,275 +0,0 @@ |
|||||||
import React, { useEffect, useState } from 'react'; |
|
||||||
import { Row, Col, Select, Divider } from 'antd'; |
|
||||||
import moment from 'moment' |
|
||||||
import Gantt from './ganttDashboard'; |
|
||||||
import ChatDashboard from './chatDashboard'; |
|
||||||
import axios from 'axios' |
|
||||||
import { NotificationContainer, NotificationManager } from 'react-notifications'; |
|
||||||
import { useParams } from 'react-router-dom'; |
|
||||||
import { Badge } from 'reactstrap'; |
|
||||||
import { BASE_OSPRO, BASE_INTEGRATION_V1, TOKEN_ADW } from '../../const/ApiConst'; |
|
||||||
import {formatRibuanDecimal} from "../../const/CustomFunc"; |
|
||||||
import ProgressBar from "./progressBar"; |
|
||||||
import numeral from 'numeral'; |
|
||||||
|
|
||||||
function BoxDashboard({ value, title, secondaryTitle, icon, bgColor }) { |
|
||||||
return ( |
|
||||||
<div style={{ backgroundColor: bgColor }} className='box-header-dashboard-project'> |
|
||||||
<div style={{ display: 'flex', justifyContent: 'space-between' }}> |
|
||||||
<div style={{ fontSize: '0.8rem', fontWeight: 500, color: '#fff', textTransform: 'uppercase' }}>{title}</div> |
|
||||||
<div>{icon}</div> |
|
||||||
</div> |
|
||||||
<div style={{ fontSize: '1rem', fontWeight: 500, color: '#fff' }}>{value}</div> |
|
||||||
</div> |
|
||||||
) |
|
||||||
} |
|
||||||
|
|
||||||
function RenderHealthProject({params}){ |
|
||||||
if (params == "on-budget") { |
|
||||||
return (<Badge style = {{fontSize:"18px"}} color="success">On Budget</Badge>) |
|
||||||
} else if (params == "warning") { |
|
||||||
return (<Badge style = {{fontSize:"18px"}} color="warning">Warning</Badge>) |
|
||||||
} else { |
|
||||||
return (<Badge style = {{fontSize:"18px"}} color="danger">Danger</Badge>) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
const DashboardProject = () => { |
|
||||||
|
|
||||||
const { ID } = useParams(); |
|
||||||
const [STATUSPROJECT, SET_STATUSPROJECT] = useState([]) |
|
||||||
const [PROJECTMGR, SET_PROJECTMGR] = useState([]) |
|
||||||
const [RO, SET_RO] = useState([]) |
|
||||||
// Schedule
|
|
||||||
const [STARTDATE, SET_STARTDATE] = useState([]) |
|
||||||
const [BASELINEFINISHDATE, SET_BASELINEFINISHDATE] = useState([]) |
|
||||||
const [ESTFINISHDATE, SET_ESTFINISHDATE] = useState([]) |
|
||||||
// Financials
|
|
||||||
const [BCWP, SET_BCWP] = useState([]) |
|
||||||
const [ACWP, SET_ACWP] = useState([]) |
|
||||||
const [VARIANCE, SET_VARIANCE] = useState([]) |
|
||||||
const [PROGRESS, SET_PROGRESS] = useState([]) |
|
||||||
const [BUDGET, SET_BUDGET] = useState([]) |
|
||||||
const [PROJECTNAME, SET_PROJECTNAME] = useState([]) |
|
||||||
const [CURRENCYSYMBOL, SET_CURRENCYSYMBOL] = useState([]) |
|
||||||
const [BUDGETHEALTH, SET_BUDGETHEALTH] = useState([]) |
|
||||||
const [COMMENT, SET_COMMENT] = useState([]) |
|
||||||
const [MANPOWER, SET_MANPOWER] = useState([0]) |
|
||||||
|
|
||||||
const token = localStorage.getItem("token") |
|
||||||
const HEADER = { |
|
||||||
headers: { |
|
||||||
"Content-Type": "application/json", |
|
||||||
"Authorization": `Bearer ${token}` |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
const HEADER_INTEGRASI = { |
|
||||||
headers: { |
|
||||||
"Content-Type": "application/json", |
|
||||||
"Authorization": `${TOKEN_ADW}` |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
const getProjectDetail = async () => { |
|
||||||
const URL = `${BASE_OSPRO}/api/project/dashboard/${ID}` |
|
||||||
const result = await axios.get(URL, HEADER).then(res => res).catch(err => err.response) |
|
||||||
|
|
||||||
if (result.data.code !== 200) { |
|
||||||
NotificationManager.error(result.data.message, 'Failed'); |
|
||||||
} |
|
||||||
|
|
||||||
if(result.data.code == 200) { |
|
||||||
let resData = result.data.data; |
|
||||||
SET_BUDGET(resData.rencana_biaya) |
|
||||||
SET_PROJECTMGR(resData.pm) |
|
||||||
SET_RO(resData.company) |
|
||||||
SET_PROJECTNAME(resData.name_project) |
|
||||||
SET_STARTDATE(resData.start) |
|
||||||
SET_BASELINEFINISHDATE(resData.finish) |
|
||||||
SET_CURRENCYSYMBOL(resData.currency_symbol) |
|
||||||
SET_BUDGETHEALTH(resData.budget_health) |
|
||||||
SET_ACWP(resData.actual_cost) |
|
||||||
SET_PROGRESS(resData.progress) |
|
||||||
SET_COMMENT(resData.comment) |
|
||||||
SET_MANPOWER(resData.man_power) |
|
||||||
getDataCostActual(resData.kode_sortname); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
const getDataCostActual = async (kode_project) => { |
|
||||||
const URL = `${BASE_INTEGRATION_V1}/api/project_cost?project_no=${kode_project}` |
|
||||||
const result = await axios.get(URL, HEADER_INTEGRASI).then(res => res).catch(err => err.response) |
|
||||||
if (!result.data.data) { |
|
||||||
NotificationManager.error('Integrasi Cost Actual Failed', 'Failed'); |
|
||||||
}else { |
|
||||||
SET_ACWP(result.data.data.total_cost) |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
useEffect(() => { |
|
||||||
getProjectDetail(); |
|
||||||
}, []) |
|
||||||
|
|
||||||
|
|
||||||
return ( |
|
||||||
<div style={{ margin: "10px" }}> |
|
||||||
<Row> |
|
||||||
<Col span={9}> |
|
||||||
<div style={{ display: 'flex', justifyContent: 'space-between', margin: '0 5px' }} className="box-header-dashboard-project"> |
|
||||||
<div><i style={{ color: 'teal' }} class="zmdi zmdi-assignment zmdi-hc-lg"></i></div> |
|
||||||
<div style={{ textTransform: 'uppercase' }}>Project </div> |
|
||||||
<div style={{ fontWeight: 500, color: '#404040', textTransform: 'uppercase' }}> {PROJECTNAME}</div> |
|
||||||
</div> |
|
||||||
</Col> |
|
||||||
<Col span={4}> |
|
||||||
<div style={{ display: 'flex', justifyContent: 'space-between', margin: '0 5px' }} className="box-header-dashboard-project"> |
|
||||||
<div><i style={{ color: '#0284c7' }} class="zmdi zmdi-account zmdi-hc-lg"></i></div> |
|
||||||
<div style={{ textTransform: 'uppercase' }}>PM</div> |
|
||||||
<div style={{ fontWeight: 500, color: '#404040', textTransform: 'uppercase' }}>{PROJECTMGR}</div> |
|
||||||
</div> |
|
||||||
</Col> |
|
||||||
<Col span={7}> |
|
||||||
<div style={{ display: 'flex', justifyContent: 'space-between', margin: '0 5px' }} className="box-header-dashboard-project"> |
|
||||||
<div><i style={{ color: '#b91c1c' }} class="zmdi zmdi-home zmdi-hc-lg"></i></div> |
|
||||||
<div style={{ textTransform: 'uppercase' }}>Customer</div> |
|
||||||
<div style={{ fontWeight: 500, color: '#404040', textTransform: 'uppercase' }}>{RO}</div> |
|
||||||
</div> |
|
||||||
</Col> |
|
||||||
<Col span={4}> |
|
||||||
<div style={{ display: 'flex', justifyContent: 'space-between', margin: '0 5px' }} className="box-header-dashboard-project"> |
|
||||||
<div><i style={{ color: '#e68a00' }} class="zmdi zmdi-calendar-alt zmdi-hc-lg"></i></div> |
|
||||||
<div style={{ textTransform: 'uppercase' }}>Date</div> |
|
||||||
<div style={{ fontWeight: 500, color: '#404040' }}>{moment().format("DD-MM-YYYY")}</div> |
|
||||||
</div> |
|
||||||
</Col> |
|
||||||
</Row> |
|
||||||
<div style={{ paddingTop: 20 }}> |
|
||||||
<Row> |
|
||||||
<Col span={9}> |
|
||||||
<div style={{ margin: '0 5px' }} className="box-header-dashboard-project"> |
|
||||||
<div style={{ margin: '5px 0' }}><h6>SCHEDULE</h6></div> |
|
||||||
<div style={{ padding: '5px 0' }}> |
|
||||||
<Row> |
|
||||||
<Col span={2}><i style={{ color: 'teal' }} class="zmdi zmdi-calendar-alt zmdi-hc-lg"></i></Col> |
|
||||||
<Col span={22}> |
|
||||||
<div style={{ textTransform: 'uppercase', display: 'flex', justifyContent: 'space-between' }}> |
|
||||||
<div>Start Date</div> |
|
||||||
<div style={{ fontWeight: 500, color: '#8c8c8c' }}>{moment(STARTDATE).format("LL")}</div> |
|
||||||
</div> |
|
||||||
</Col> |
|
||||||
</Row> |
|
||||||
</div> |
|
||||||
<div style={{ padding: '5px 0' }}> |
|
||||||
<Row> |
|
||||||
<Col span={2}><i style={{ color: 'teal' }} class="zmdi zmdi-calendar-alt zmdi-hc-lg"></i></Col> |
|
||||||
<Col span={22}> |
|
||||||
<div style={{ textTransform: 'uppercase', display: 'flex', justifyContent: 'space-between' }}> |
|
||||||
<div>Baseline Finish Date</div> |
|
||||||
<div style={{ fontWeight: 500, color: '#8c8c8c' }}>{moment(BASELINEFINISHDATE).format("LL")}</div> |
|
||||||
</div> |
|
||||||
</Col> |
|
||||||
</Row> |
|
||||||
</div> |
|
||||||
<div style={{ padding: '5px 0' }}> |
|
||||||
<Row> |
|
||||||
<Col span={2}><i style={{ color: 'teal' }} class="zmdi zmdi-calendar-alt zmdi-hc-lg"></i></Col> |
|
||||||
<Col span={22}> |
|
||||||
<div style={{ textTransform: 'uppercase', display: 'flex', justifyContent: 'space-between' }}> |
|
||||||
<div>Estimated Finish Date</div> |
|
||||||
<div style={{ fontWeight: 500, color: '#8c8c8c' }}>{moment(ESTFINISHDATE).format("LL")}</div> |
|
||||||
</div> |
|
||||||
</Col> |
|
||||||
</Row> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
</Col> |
|
||||||
<Col span={10}> |
|
||||||
<div style={{ margin: '0 5px' }} className="box-header-dashboard-project"> |
|
||||||
<div style={{ margin: '5px 0' }}><h6>FINANCIALS</h6></div> |
|
||||||
<div style={{ padding: '5px 0' }}> |
|
||||||
<Row> |
|
||||||
<Col span={2}><i style={{ color: '#059669' }} class="zmdi zmdi-money zmdi-hc-lg"></i></Col> |
|
||||||
<Col span={22}> |
|
||||||
<div style={{ textTransform: 'uppercase', display: 'flex', justifyContent: 'space-between' }}> |
|
||||||
<div>Budget Proyek</div> |
|
||||||
<div style={{ fontWeight: 500, color: '#8c8c8c' }}>{`${formatRibuanDecimal(BUDGET)}`}</div> |
|
||||||
</div> |
|
||||||
</Col> |
|
||||||
</Row> |
|
||||||
</div> |
|
||||||
<div style={{ padding: '5px 0' }}> |
|
||||||
<Row> |
|
||||||
<Col span={2}><i style={{ color: '#059669' }} class="zmdi zmdi-money zmdi-hc-lg"></i></Col> |
|
||||||
<Col span={22}> |
|
||||||
<div style={{ textTransform: 'uppercase', display: 'flex', justifyContent: 'space-between' }}> |
|
||||||
<div>Actual Cost</div> |
|
||||||
<div style={{ fontWeight: 500, color: '#8c8c8c' }}>{`${formatRibuanDecimal(ACWP)}`}</div> |
|
||||||
</div> |
|
||||||
</Col> |
|
||||||
</Row> |
|
||||||
</div> |
|
||||||
<div style={{ padding: '5px 0' }}> |
|
||||||
<Row> |
|
||||||
<Col span={2}><i style={{ color: '#059669' }} class="zmdi zmdi-money zmdi-hc-lg"></i></Col> |
|
||||||
<Col span={22}> |
|
||||||
<div style={{ textTransform: 'uppercase', display: 'flex', justifyContent: 'space-between' }}> |
|
||||||
<div>Variance</div> |
|
||||||
<div style={{ fontWeight: 500, color: '#8c8c8c' }}>{`${formatRibuanDecimal(BUDGET - ACWP)}`}</div> |
|
||||||
</div> |
|
||||||
</Col> |
|
||||||
</Row> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
|
|
||||||
</Col> |
|
||||||
<Col span={5}> |
|
||||||
<div style={{ backgroundColor: "#059669" }} className='box-header-dashboard-project'> |
|
||||||
<div style={{ display: 'flex', justifyContent: 'center' }}> |
|
||||||
<div style={{ fontSize: '0.8rem', fontWeight: 500, color: '#fff', textTransform: 'uppercase' }}>Progress</div> |
|
||||||
</div> |
|
||||||
<ProgressBar bgcolor="#ffc355" completed={PROGRESS} /> |
|
||||||
</div> |
|
||||||
<Row> |
|
||||||
<Col span={12}> |
|
||||||
<div style={{ margin: '5px 0' }} className="box-header-dashboard-project"> |
|
||||||
<div style={{ display: 'flex', justifyContent: 'center' }}> |
|
||||||
<div style={{ marginBottom: '5px', fontSize: '0.7rem', fontWeight: '500' }}>HEALTH PROJECT</div> |
|
||||||
</div> |
|
||||||
<div style={{ display: 'flex', justifyContent: 'space-evenly', }}> |
|
||||||
<RenderHealthProject params = {`${BUDGETHEALTH}`}/> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
</Col> |
|
||||||
<Col span={12}> |
|
||||||
<div style={{ margin: '5px 0' }} className="box-header-dashboard-project"> |
|
||||||
<div style={{ display: 'flex', justifyContent: 'center' }}> |
|
||||||
<div style={{ marginBottom: '5px', fontSize: '0.7rem', fontWeight: '500' }}>MANPOWER</div> |
|
||||||
</div> |
|
||||||
<div style={{ display: 'flex', justifyContent: 'space-evenly', }}> |
|
||||||
<div style={{ fontWeight: 500, color: '#404040', fontSize: '18px', textTransform: 'uppercase' }}>{MANPOWER}</div> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
</Col> |
|
||||||
</Row> |
|
||||||
{/* </div> */} |
|
||||||
|
|
||||||
</Col> |
|
||||||
</Row> |
|
||||||
</div> |
|
||||||
<div style={{ paddingTop: 20 }}> |
|
||||||
<Row> |
|
||||||
<Col span={19}> |
|
||||||
</Col> |
|
||||||
<Col span={5}> |
|
||||||
<ChatDashboard |
|
||||||
dataParams = {COMMENT}/> |
|
||||||
</Col> |
|
||||||
</Row> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
); |
|
||||||
} |
|
||||||
|
|
||||||
export default DashboardProject; |
|
@ -1,37 +0,0 @@ |
|||||||
import React from "react"; |
|
||||||
|
|
||||||
const ProgressBar = (props) => { |
|
||||||
const { bgcolor, completed } = props; |
|
||||||
|
|
||||||
const containerStyles = { |
|
||||||
height: 25, |
|
||||||
width: '100%', |
|
||||||
backgroundColor: "#e0e0de", |
|
||||||
borderRadius: 50, |
|
||||||
margin: 0 |
|
||||||
} |
|
||||||
|
|
||||||
const fillerStyles = { |
|
||||||
height: '100%', |
|
||||||
width: `${completed}%`, |
|
||||||
backgroundColor: bgcolor, |
|
||||||
borderRadius: 'inherit', |
|
||||||
textAlign: 'right' |
|
||||||
} |
|
||||||
|
|
||||||
const labelStyles = { |
|
||||||
padding: 5, |
|
||||||
color: 'white', |
|
||||||
fontWeight: 'bold' |
|
||||||
} |
|
||||||
|
|
||||||
return ( |
|
||||||
<div style={containerStyles}> |
|
||||||
<div style={fillerStyles}> |
|
||||||
<span style={labelStyles}>{`${completed}%`}</span> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
); |
|
||||||
}; |
|
||||||
|
|
||||||
export default ProgressBar; |
|
@ -1,72 +0,0 @@ |
|||||||
import React from 'react'; |
|
||||||
import { Table, Tag, Space } from 'antd'; |
|
||||||
const columns = [ |
|
||||||
{ |
|
||||||
title: 'No', |
|
||||||
dataIndex: 'carNo', |
|
||||||
key: 'carNo', |
|
||||||
fixed: 'left', |
|
||||||
}, |
|
||||||
{ |
|
||||||
title: 'Description', |
|
||||||
dataIndex: 'description', |
|
||||||
key: 'description', |
|
||||||
width: 350 |
|
||||||
}, |
|
||||||
{ |
|
||||||
title: 'Severity', |
|
||||||
dataIndex: 'severity', |
|
||||||
key: 'severity', |
|
||||||
render: text => { |
|
||||||
return text == 'low' ? <div className="badge" style={{ backgroundColor: '#e6e600' }}>LOW</div> : |
|
||||||
text == 'medium' ? <div className="badge badge-orange" style={{ backgroundColor: 'orange' }}>MEDIUM</div> : |
|
||||||
<div className="badge badge-danger">HIGH</div> |
|
||||||
}, |
|
||||||
}, |
|
||||||
{ |
|
||||||
title: 'Status', |
|
||||||
dataIndex: 'status', |
|
||||||
key: 'status', |
|
||||||
render: text => { |
|
||||||
return text == 'open' ? <div className="badge badge-primary">OPEN</div> : |
|
||||||
text == 'on-progress' ? <div className="badge badge-warning">ON PROGRESS</div> : |
|
||||||
<div className="badge badge-success">DONE</div> |
|
||||||
}, |
|
||||||
}, |
|
||||||
{ |
|
||||||
title: 'Assigned', |
|
||||||
dataIndex: 'assigned', |
|
||||||
key: 'assigned', |
|
||||||
}, |
|
||||||
{ |
|
||||||
title: 'Due', |
|
||||||
dataIndex: 'due', |
|
||||||
key: 'due', |
|
||||||
} |
|
||||||
]; |
|
||||||
const data = [ |
|
||||||
{ |
|
||||||
key: '1', |
|
||||||
carNo: 'RIS001', |
|
||||||
description: 'Test Analyst on unplanned leave, risk to project if leave extends pas 5/20', |
|
||||||
severity: 'medium', |
|
||||||
status: 'on-progress', |
|
||||||
due: '05/04/2022', |
|
||||||
assigned: 'John Lennon' |
|
||||||
}, |
|
||||||
{ |
|
||||||
key: '2', |
|
||||||
carNo: 'RIS002', |
|
||||||
description: 'Coffee machine broken, result in extra long breaks to find coffee', |
|
||||||
severity: 'low', |
|
||||||
status: 'open', |
|
||||||
due: '14/011/2022', |
|
||||||
assigned: 'Robert William' |
|
||||||
}, |
|
||||||
]; |
|
||||||
const TableDashboard = () => { |
|
||||||
return ( |
|
||||||
<Table size="small" columns={columns} dataSource={data} scroll={{ y: 300 }} /> |
|
||||||
); |
|
||||||
} |
|
||||||
export default TableDashboard; |
|
@ -1,51 +0,0 @@ |
|||||||
import React, { Component } from 'react' |
|
||||||
import DataTable from '../../../components/DataTable' |
|
||||||
import {API_LIST_DATA_COUNTRY, API_INSERT_DATA_COUNTRY, API_UPDATE_DATA_COUNTRY, API_DELETE_DATA_COUNTRY } from '../../../const/ApiConst.js' |
|
||||||
|
|
||||||
|
|
||||||
const columns = [{ |
|
||||||
dataField: 'id', |
|
||||||
alias: "Id", |
|
||||||
showInput: false, |
|
||||||
type: "number", |
|
||||||
state: 0 |
|
||||||
}, { |
|
||||||
dataField: 'country_name', |
|
||||||
alias: "Country Name", |
|
||||||
showInput: true, |
|
||||||
type: "text", |
|
||||||
state: "" |
|
||||||
}, { |
|
||||||
dataField: 'last_updated', |
|
||||||
alias: "Last Updated", |
|
||||||
showInput: false, |
|
||||||
type: "text", |
|
||||||
state: "" |
|
||||||
}]; |
|
||||||
|
|
||||||
class MasterCountry extends Component { |
|
||||||
constructor(props) { |
|
||||||
super(props) |
|
||||||
this.state = {} |
|
||||||
} |
|
||||||
|
|
||||||
componentDidMount() {} |
|
||||||
|
|
||||||
render() { |
|
||||||
|
|
||||||
return ( |
|
||||||
<div> |
|
||||||
<DataTable |
|
||||||
title="Country" |
|
||||||
columns={columns} |
|
||||||
urlParamGet={API_LIST_DATA_COUNTRY} |
|
||||||
urlParamInsert={API_INSERT_DATA_COUNTRY} |
|
||||||
urlParamUpdate={API_UPDATE_DATA_COUNTRY} |
|
||||||
urlParamDelete={API_DELETE_DATA_COUNTRY} |
|
||||||
/> |
|
||||||
</div> |
|
||||||
) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
export default MasterCountry; |
|
@ -1,6 +0,0 @@ |
|||||||
{ |
|
||||||
"name": "MasterCountry", |
|
||||||
"version": "0.0.0", |
|
||||||
"private": true, |
|
||||||
"main": "./MasterCountry.js" |
|
||||||
} |
|
@ -1,156 +0,0 @@ |
|||||||
import React, { Component } from 'react' |
|
||||||
import { Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap'; |
|
||||||
import { Col, Row, Button, Form, FormGroup, Label, Input } from 'reactstrap'; |
|
||||||
import { NotificationContainer, NotificationManager } from 'react-notifications'; |
|
||||||
import axios from 'axios' |
|
||||||
|
|
||||||
|
|
||||||
const BASE_URL = "https://oslog.id/geohr-api/"; |
|
||||||
const formState = { |
|
||||||
dataTable: [], |
|
||||||
openDialog: false, |
|
||||||
name: '', |
|
||||||
description: '', |
|
||||||
id: 0, |
|
||||||
idData: 0, |
|
||||||
nameMessage: "", |
|
||||||
} |
|
||||||
|
|
||||||
const ERROR_NAME = "name cannot be empty" |
|
||||||
export default class DialogForm extends Component { |
|
||||||
state = { |
|
||||||
...formState |
|
||||||
} |
|
||||||
|
|
||||||
componentDidUpdate(prevProps, prevState) { |
|
||||||
const { dataEdit, methodAct } = this.props |
|
||||||
if ((prevProps.dataEdit !== dataEdit) && (methodAct == "Edit" || methodAct == "View")) { |
|
||||||
this.setState({ |
|
||||||
idData: dataEdit.id, |
|
||||||
name: dataEdit.name, |
|
||||||
description: dataEdit.description, |
|
||||||
}) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
handleSave = async () => { |
|
||||||
const err = this.handleValidation(); |
|
||||||
let url = BASE_URL + "group-sales/add" |
|
||||||
const { name, description, idData } = this.state |
|
||||||
const { methodAct } = this.props |
|
||||||
console.log(`methodAct`, methodAct) |
|
||||||
if (methodAct === "Add") { |
|
||||||
if (!err) { |
|
||||||
|
|
||||||
const payload = { |
|
||||||
name, |
|
||||||
description, |
|
||||||
} |
|
||||||
const result = await axios.post(url, payload) |
|
||||||
.then(res => res) |
|
||||||
.catch((error) => error.response); |
|
||||||
console.log(`result`, result) |
|
||||||
if (result.data.message === "OK") { |
|
||||||
this.props.closeDialog() |
|
||||||
this.setState({ |
|
||||||
...formState, |
|
||||||
}) |
|
||||||
NotificationManager.success('Data group sales berhasil ditambahkan!!', 'Success!!'); |
|
||||||
} else { |
|
||||||
NotificationManager.error(result.data.message); |
|
||||||
} |
|
||||||
} |
|
||||||
} else if (methodAct === "Edit") { |
|
||||||
if (!err) { |
|
||||||
let urlEdit = BASE_URL + `group-sales/${idData}/edit`; |
|
||||||
const payload = { |
|
||||||
name, |
|
||||||
description, |
|
||||||
} |
|
||||||
|
|
||||||
const result = await axios.put(urlEdit, payload) |
|
||||||
.then(res => res) |
|
||||||
.catch((error) => error.response); |
|
||||||
console.log(`result edit`, result) |
|
||||||
|
|
||||||
if (result.data.message === "OK") { |
|
||||||
this.props.closeDialog() |
|
||||||
this.setState({ |
|
||||||
...formState, |
|
||||||
}) |
|
||||||
NotificationManager.success('Data group sales berhasil diedit!!', 'Success!!'); |
|
||||||
} else { |
|
||||||
NotificationManager.error(result.data.message); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
handleCancel = () => { |
|
||||||
this.props.closeDialog() |
|
||||||
this.setState({ |
|
||||||
...formState |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
handleValidation = () => { |
|
||||||
const { name } = this.state |
|
||||||
let isError = false; |
|
||||||
const errors = { |
|
||||||
nameMessage: "", |
|
||||||
} |
|
||||||
if (name === "") { |
|
||||||
isError = true |
|
||||||
errors.nameMessage = ERROR_NAME |
|
||||||
} |
|
||||||
this.setState({ |
|
||||||
nameMessage: "", |
|
||||||
...errors, |
|
||||||
}); |
|
||||||
|
|
||||||
return isError; |
|
||||||
} |
|
||||||
|
|
||||||
renderForm = () => { |
|
||||||
const { name, description, nameMessage } = this.state |
|
||||||
return ( |
|
||||||
<Row form> |
|
||||||
<Col md={12}> |
|
||||||
<FormGroup> |
|
||||||
<Label for="exampleEmail">Name</Label> |
|
||||||
<Input type="text" value={name} onChange={ |
|
||||||
(e) => this.setState({ |
|
||||||
name: e.target.value, |
|
||||||
nameMessage: e.target.value !== "" ? "" : ERROR_NAME |
|
||||||
})} placeholder="name" invalid={nameMessage} /> |
|
||||||
</FormGroup> |
|
||||||
</Col> |
|
||||||
<Col md={12}> |
|
||||||
<FormGroup> |
|
||||||
<Label>Description</Label> |
|
||||||
<Input type="text" value={description} onChange={(e) => this.setState({ description: e.target.value })} placeholder="description " /> |
|
||||||
</FormGroup> |
|
||||||
</Col> |
|
||||||
</Row> |
|
||||||
) |
|
||||||
} |
|
||||||
|
|
||||||
render() { |
|
||||||
const { openDialog, closeDialog, methodAct } = this.props |
|
||||||
return ( |
|
||||||
<Modal isOpen={openDialog} toggle={openDialog} size="md"> |
|
||||||
<ModalHeader toggle={closeDialog}>{methodAct} Group Sales</ModalHeader> |
|
||||||
<ModalBody> |
|
||||||
<Form> |
|
||||||
{this.renderForm()} |
|
||||||
</Form> |
|
||||||
</ModalBody> |
|
||||||
<ModalFooter> |
|
||||||
<Button color="primary" onClick={this.handleSave}>{methodAct}</Button>{' '} |
|
||||||
<Button color="secondary" onClick={this.handleCancel}>Cancel</Button> |
|
||||||
</ModalFooter> |
|
||||||
</Modal> |
|
||||||
) |
|
||||||
} |
|
||||||
} |
|
@ -1,291 +0,0 @@ |
|||||||
import React, { Component } from 'react'; |
|
||||||
import { Card, CardBody, CardHeader, Col, Row, Table, Input, InputGroupButtonDropdown, DropdownToggle, DropdownItem, DropdownMenu, InputGroup } from 'reactstrap'; |
|
||||||
import BootstrapTable from 'react-bootstrap-table-next'; |
|
||||||
import { Button } from 'reactstrap'; |
|
||||||
import axios from 'axios'; |
|
||||||
import SweetAlert from 'react-bootstrap-sweetalert'; |
|
||||||
import DialogForm from './DialogForm'; |
|
||||||
import paginationFactory from 'react-bootstrap-table2-paginator'; |
|
||||||
import { NotificationContainer, NotificationManager } from 'react-notifications'; |
|
||||||
import ToolkitProvider, { Search } from 'react-bootstrap-table2-toolkit'; |
|
||||||
import { Pagination } from 'antd'; |
|
||||||
import { Tooltip } from 'reactstrap'; |
|
||||||
|
|
||||||
const BASE_URL = "https://oslog.id/geohr-api/"; |
|
||||||
|
|
||||||
const { SearchBar } = Search; |
|
||||||
|
|
||||||
const NoDataIndication = () => ( |
|
||||||
<div className="spinner"> |
|
||||||
<div className="rect1" /> |
|
||||||
<div className="rect2" /> |
|
||||||
<div className="rect3" /> |
|
||||||
</div> |
|
||||||
); |
|
||||||
|
|
||||||
const column = [ |
|
||||||
{ name: "Name" }, |
|
||||||
{ name: "Description" }, |
|
||||||
] |
|
||||||
|
|
||||||
const LENGTH_DATA = 10 |
|
||||||
export default class index extends Component { |
|
||||||
constructor(props) { |
|
||||||
super(props) |
|
||||||
this.state = { |
|
||||||
data: [], |
|
||||||
openDialog: false, |
|
||||||
typeDialog: 'Save', |
|
||||||
dataEdit: null, |
|
||||||
alertDelete: false, |
|
||||||
idDelete: 0, |
|
||||||
search: "", |
|
||||||
alert: false, |
|
||||||
methodAct: "Add", |
|
||||||
page: 0, |
|
||||||
totalPage: 0, |
|
||||||
rowsPerPage: LENGTH_DATA, |
|
||||||
currentPage: 1, |
|
||||||
splitButtonOpen: false, |
|
||||||
searchDetail: "All", |
|
||||||
searchDetailField: "name", |
|
||||||
tooltipDelete: false, |
|
||||||
tooltipEdit: false |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
async componentDidMount() { |
|
||||||
const { page, rowsPerPage } = this.state |
|
||||||
this.getDataGroupSales(page, rowsPerPage); |
|
||||||
} |
|
||||||
async componentDidUpdate(prevProps, prevState) { |
|
||||||
const { search, rowsPerPage, page } = this.state |
|
||||||
|
|
||||||
if (page !== prevState.page) { |
|
||||||
this.getDataGroupSales(page, rowsPerPage) |
|
||||||
} |
|
||||||
|
|
||||||
if (rowsPerPage !== prevState.rowsPerPage) { |
|
||||||
this.getDataGroupSales(0, rowsPerPage) |
|
||||||
this.setState({ page: 0 }) |
|
||||||
} |
|
||||||
|
|
||||||
if (search !== prevState.search) { |
|
||||||
this.getDataGroupSales(0, rowsPerPage) |
|
||||||
this.setState({ page: 0 }) |
|
||||||
} |
|
||||||
}; |
|
||||||
|
|
||||||
handleSearch = e => { |
|
||||||
const value = e.target.value |
|
||||||
this.setState({ search: value, page: 0 }) |
|
||||||
}; |
|
||||||
|
|
||||||
|
|
||||||
getDataGroupSales = async (start, length) => { |
|
||||||
const { search, rowsPerPage, searchDetail, searchDetailField } = this.state |
|
||||||
let url = BASE_URL + "group-sales/search"; |
|
||||||
const obj = { |
|
||||||
"paging": { "start": start, "length": length }, |
|
||||||
...searchDetail === "All" && |
|
||||||
{ |
|
||||||
"filter_columns": [ |
|
||||||
{ "name": "name", "value": search.toString() }, |
|
||||||
{ "name": "description", "value": search.toString() }, |
|
||||||
], |
|
||||||
}, |
|
||||||
...searchDetail !== "All" && |
|
||||||
{ |
|
||||||
"columns": [ |
|
||||||
{ "name": searchDetailField, "logic_operator": "ilike", "operator": "and", "value": search.toString() } |
|
||||||
] |
|
||||||
}, |
|
||||||
"orders": { "columns": ["created_date"], "ascending": false } |
|
||||||
} |
|
||||||
|
|
||||||
const result = await axios |
|
||||||
.post(url, obj) |
|
||||||
.then(res => res) |
|
||||||
.catch((error) => error.response); |
|
||||||
if (result.data.message == "OK") { |
|
||||||
console.log(`result data`, result.data.data) |
|
||||||
this.setState({ data: result.data.data, totalPage: result.data.totalRecord }); |
|
||||||
} else { |
|
||||||
NotificationManager.error('Failed retreiving data!!', 'Failed'); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
handleOpenDialog = () => { |
|
||||||
this.setState({ openDialog: true, methodAct: "Add" }) |
|
||||||
} |
|
||||||
|
|
||||||
handleCloseDialog = () => { |
|
||||||
this.setState({ openDialog: false }) |
|
||||||
this.getDataGroupSales() |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
handleEditData = (data) => { |
|
||||||
this.setState({ dataEdit: data, openDialog: true, methodAct: "Edit" }) |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
onDelete = (id) => { |
|
||||||
this.setState({ |
|
||||||
alertDelete: true, |
|
||||||
idDelete: id |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
handleDeleted = async (param) => { |
|
||||||
const { idDelete } = this.state |
|
||||||
|
|
||||||
if (param === "delete") { |
|
||||||
const result = await axios.delete(`${BASE_URL}/group-sales/${idDelete}/delete`) |
|
||||||
.then((response) => response) |
|
||||||
.catch((error) => error.response) |
|
||||||
this.setState({ |
|
||||||
alertDelete: false, |
|
||||||
alert: true |
|
||||||
}) |
|
||||||
await this.getDataGroupSales() |
|
||||||
} else { |
|
||||||
this.setState({ |
|
||||||
alertDelete: false |
|
||||||
}) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
onShowSizeChange = (current, pageSize) => { |
|
||||||
this.setState({ rowsPerPage: pageSize }) |
|
||||||
} |
|
||||||
|
|
||||||
onPagination = (current, pageSize) => { |
|
||||||
this.setState({ currentPage: current, page: (current - 1) * pageSize }) |
|
||||||
} |
|
||||||
|
|
||||||
toggleDropDown = () => { |
|
||||||
this.setState(prevState => ({ splitButtonOpen: !prevState.splitButtonOpen })) |
|
||||||
} |
|
||||||
|
|
||||||
toggle = (param) => { |
|
||||||
if (param === "edit") { |
|
||||||
this.setState(prevState => ({ tooltipEdit: !prevState.tooltipEdit })) |
|
||||||
} else if (param === "delete") { |
|
||||||
this.setState(prevState => ({ tooltipDelete: !prevState.tooltipDelete })) |
|
||||||
} |
|
||||||
} |
|
||||||
render() { |
|
||||||
const { openDialog, data, search, alert, page, totalPage, rowsPerPage, currentPage, searchDetail, searchDetailField, splitButtonOpen, tooltipEdit, tooltipDelete } = this.state |
|
||||||
let noSeq = 0; |
|
||||||
return ( |
|
||||||
<div> |
|
||||||
<NotificationContainer /> |
|
||||||
<SweetAlert show={alert} success title="deleted successfully!" onConfirm={() => this.setState({ alert: false })} onCancel={() => this.setState({ alert: false })}> |
|
||||||
You clicked the button! |
|
||||||
</SweetAlert> |
|
||||||
<SweetAlert |
|
||||||
show={this.state.alertDelete} |
|
||||||
warning |
|
||||||
showCancel |
|
||||||
confirmBtnText="Delete" |
|
||||||
confirmBtnBsStyle="danger" |
|
||||||
title="Are you sure?" |
|
||||||
onConfirm={() => this.handleDeleted("delete")} |
|
||||||
onCancel={() => this.handleDeleted("cancel")} |
|
||||||
focusCancelBtn |
|
||||||
> |
|
||||||
Data group sales akan terhapus!! |
|
||||||
</SweetAlert> |
|
||||||
<DialogForm |
|
||||||
openDialog={openDialog} |
|
||||||
closeDialog={this.handleCloseDialog} |
|
||||||
dataEdit={this.state.dataEdit} |
|
||||||
methodAct={this.state.methodAct} |
|
||||||
/> |
|
||||||
<Card> |
|
||||||
<CardHeader style={{ display: "flex", justifyContent: "space-between" }}> |
|
||||||
<h4>Group Sales</h4> |
|
||||||
<Button color="primary" onClick={() => this.handleOpenDialog('Save')}>Add Group Sales</Button> |
|
||||||
</CardHeader> |
|
||||||
<CardBody> |
|
||||||
<InputGroup style={{ maxWidth: "200px", marginBottom: "20px" }}> |
|
||||||
<Input onChange={this.handleSearch} value={search} type="text" name="search" id="search" placeholder={`Search ${searchDetail}`} /> |
|
||||||
<InputGroupButtonDropdown addonType="prepend" |
|
||||||
isOpen={splitButtonOpen} |
|
||||||
toggle={this.toggleDropDown} |
|
||||||
> |
|
||||||
<DropdownToggle split outline /> |
|
||||||
<DropdownMenu> |
|
||||||
<DropdownItem onClick={ |
|
||||||
() => this.setState({ |
|
||||||
searchDetail: "All", |
|
||||||
searchDetailField: "name" |
|
||||||
})}>All</DropdownItem> |
|
||||||
<DropdownItem onClick={ |
|
||||||
() => this.setState({ |
|
||||||
searchDetail: "Name", |
|
||||||
searchDetailField: "name" |
|
||||||
})}>Name</DropdownItem> |
|
||||||
<DropdownItem onClick={ |
|
||||||
() => this.setState({ |
|
||||||
searchDetail: "Description", |
|
||||||
searchDetailField: "description" |
|
||||||
})}>Description</DropdownItem> |
|
||||||
</DropdownMenu> |
|
||||||
</InputGroupButtonDropdown> |
|
||||||
</InputGroup> |
|
||||||
<Table responsive striped hover> |
|
||||||
<thead> |
|
||||||
<tr> |
|
||||||
<th>Actions</th> |
|
||||||
{column.map((i) => { |
|
||||||
return ( |
|
||||||
<th scope="row">{i.name}</th> |
|
||||||
) |
|
||||||
})} |
|
||||||
</tr> |
|
||||||
</thead> |
|
||||||
<tbody> |
|
||||||
{data.map((n) => { |
|
||||||
return ( |
|
||||||
<tr key={n.id}> |
|
||||||
<td> |
|
||||||
{/* delete */} |
|
||||||
<i id="TooltipDelete" class="cil-trash fa-lg" style={{ color: 'red', marginRight: '10px', cursor: "pointer" }} onClick={() => this.onDelete(n.id)}></i> |
|
||||||
<Tooltip placement="right" isOpen={tooltipDelete} target="TooltipDelete" toggle={() => this.toggle("delete")}> |
|
||||||
Delete |
|
||||||
</Tooltip> |
|
||||||
|
|
||||||
{/* edit */} |
|
||||||
<i id="TooltipEdit" class="cil-pencil fa-lg" style={{ color: 'green', cursor: "pointer", marginRight: '10px', }} onClick={() => this.handleEditData(n)}></i> |
|
||||||
<Tooltip placement="right" isOpen={tooltipEdit} target="TooltipEdit" toggle={() => this.toggle("edit")}> |
|
||||||
Edit |
|
||||||
</Tooltip> |
|
||||||
{/* <i class="cil-search fa-lg" style={{ color: 'blue', cursor: "pointer" }} onClick={() => this.handleDetail(n)}></i> */} |
|
||||||
</td> |
|
||||||
<td>{n.name}</td> |
|
||||||
<td>{n.description}</td> |
|
||||||
</tr> |
|
||||||
) |
|
||||||
})} |
|
||||||
</tbody> |
|
||||||
</Table> |
|
||||||
<Pagination |
|
||||||
showSizeChanger |
|
||||||
onShowSizeChange={this.onShowSizeChange} |
|
||||||
onChange={this.onPagination} |
|
||||||
defaultCurrent={currentPage} |
|
||||||
pageSize={rowsPerPage} |
|
||||||
total={totalPage} |
|
||||||
pageSizeOptions={["10", "15", "20", "25", "30", "35", "40"]} |
|
||||||
/> |
|
||||||
</CardBody> |
|
||||||
</Card> |
|
||||||
</div> |
|
||||||
) |
|
||||||
} |
|
||||||
} |
|
@ -1,581 +0,0 @@ |
|||||||
import React, { Component } from 'react' |
|
||||||
import { Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap'; |
|
||||||
import { Col, Row, Button, Form, FormGroup, Label, Input, FormText } from 'reactstrap'; |
|
||||||
import Select from 'react-select' |
|
||||||
import axios from 'axios'; |
|
||||||
import moment from 'moment'; |
|
||||||
import { DatePicker } from 'antd'; |
|
||||||
import 'antd/dist/antd.css'; |
|
||||||
import { BASE_URL_GEOHR_API2 } from '../../../const/ApiConst' |
|
||||||
import '../MasterDataStyles.css' |
|
||||||
import SweetAlert from 'react-bootstrap-sweetalert'; |
|
||||||
import { NotificationContainer, NotificationManager } from 'react-notifications'; |
|
||||||
|
|
||||||
|
|
||||||
const format = 'YYYY-MM-DD'; |
|
||||||
let countError = 0; |
|
||||||
const listGender = [ |
|
||||||
{ |
|
||||||
"value": "L", |
|
||||||
"label": "Laki-laki" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"value": "P", |
|
||||||
"label": "Perempuan" |
|
||||||
}] |
|
||||||
|
|
||||||
const listBlood = [ |
|
||||||
{ |
|
||||||
"value": "A", |
|
||||||
"label": "A" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"value": "AB", |
|
||||||
"label": "AB" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"value": "B", |
|
||||||
"label": "B" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"value": "O", |
|
||||||
"label": "O" |
|
||||||
}] |
|
||||||
|
|
||||||
const API = `https://oslog.id/geohr-api` |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export default class DialogForm extends Component { |
|
||||||
constructor(props) { |
|
||||||
super(props) |
|
||||||
this.state = { |
|
||||||
id: 0, |
|
||||||
idDivision:0, |
|
||||||
idRoles:0, |
|
||||||
name:"", |
|
||||||
email:"", |
|
||||||
phoneNumber:"", |
|
||||||
username:"", |
|
||||||
password:"", |
|
||||||
address:"", |
|
||||||
birthPlace: "", |
|
||||||
birthDate: null, |
|
||||||
currentSelectGender: null,
|
|
||||||
hobby: "", |
|
||||||
openDialog: false, |
|
||||||
isParentClick: false, |
|
||||||
currentSelectVal: null, |
|
||||||
dataDivision:[], |
|
||||||
listDivisionSelect:[], |
|
||||||
selectDisable: false, |
|
||||||
dataRoles:[], |
|
||||||
listRolesSelect:[], |
|
||||||
selectDisableRoles: false, |
|
||||||
currentSelectRoles: null, |
|
||||||
currentSelectBlood: null, |
|
||||||
selectDisableBlood: false, |
|
||||||
nik: "", |
|
||||||
files: [], |
|
||||||
showImg: false, |
|
||||||
getUrl: "", |
|
||||||
namePhoto: "", |
|
||||||
alertDelete: false, |
|
||||||
idDelete: 0 , |
|
||||||
dataPhoto: null |
|
||||||
|
|
||||||
|
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
fileSelectedHandler = (e) => { |
|
||||||
this.setState({ files: [...this.state.files, ...e.target.files] }, () => { |
|
||||||
console.log('test data foto', this.state.files) |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
async componentDidMount(){ |
|
||||||
this.getDataRoles() |
|
||||||
this.props.showDialog(this.showDialog); |
|
||||||
} |
|
||||||
|
|
||||||
async componentDidUpdate (prevProps, prevState){ |
|
||||||
const { dataEdit } = this.props |
|
||||||
|
|
||||||
if(this.state.isParentClick===true){ |
|
||||||
if(this.props.typeDialog==="Edit" || this.props.typeDialog==="View"){ |
|
||||||
|
|
||||||
if(dataEdit.role_id!=="" && dataEdit.role_id!==null && dataEdit.role_id!==undefined){ |
|
||||||
this.searchRoles(dataEdit.role_id); |
|
||||||
}
|
|
||||||
|
|
||||||
this.getUrlImagery(dataEdit.id) |
|
||||||
|
|
||||||
this.setState({
|
|
||||||
id:dataEdit.id, |
|
||||||
idRoles: dataEdit.role_id, |
|
||||||
idDivision:dataEdit.employee_division_id, |
|
||||||
username:dataEdit.username || "", |
|
||||||
name:dataEdit.name || "", |
|
||||||
email:dataEdit.email || "", |
|
||||||
password:"", |
|
||||||
phoneNumber:dataEdit.phone_number || "", |
|
||||||
address:dataEdit.address || "", |
|
||||||
birthPlace: dataEdit.birth_place || "", |
|
||||||
birthDate: dataEdit.birth_date || null, |
|
||||||
currentSelectGender: dataEdit.gender ? listGender.find((x) => x.value === dataEdit.gender) : null,
|
|
||||||
hobby: dataEdit.hobby || "", |
|
||||||
nik: dataEdit.ktp_number || "", |
|
||||||
currentSelectBlood: dataEdit.blood_type ? listBlood.find((x) => x.value === dataEdit.blood_type) : null,
|
|
||||||
}) |
|
||||||
}else{ |
|
||||||
this.setState({
|
|
||||||
id:0, |
|
||||||
idDivision:0, |
|
||||||
idRoles:0, |
|
||||||
name:"", |
|
||||||
email:"", |
|
||||||
password:"", |
|
||||||
phoneNumber:"", |
|
||||||
address:"", |
|
||||||
username:"", |
|
||||||
birthPlace: "", |
|
||||||
birthDate: null, |
|
||||||
currentSelectGender: null,
|
|
||||||
hobby: "", |
|
||||||
currentSelectVal:null, |
|
||||||
currentSelectRoles:null, |
|
||||||
nik: "", |
|
||||||
currentSelectBlood: null, |
|
||||||
files: [] |
|
||||||
}) |
|
||||||
} |
|
||||||
this.setState({isParentClick:false}); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
closeImg = () => { |
|
||||||
this.setState({ showImg: false }) |
|
||||||
} |
|
||||||
|
|
||||||
getUrlImagery = async (param) => { |
|
||||||
const payload = { |
|
||||||
"paging": { "start": 0, "length": -1 }, |
|
||||||
"columns": [ |
|
||||||
{ "name": "category", "logic_operator": "=", "value": "employee", "operator": "and" }, |
|
||||||
{ "name": "ref_id", "logic_operator": "=", "value": param.toString(), "operator": "and" } |
|
||||||
], |
|
||||||
"orders": { "columns": ["id"], "ascending": true } |
|
||||||
} |
|
||||||
const resultUrl = await axios.post(`${API}/image/search`, payload).then(response => response).catch(err => err.response) |
|
||||||
this.setState({ files: resultUrl.data.data }) |
|
||||||
console.log(`resultUrl`, resultUrl.data.data) |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
getDataDivision = async () => { |
|
||||||
countError++; |
|
||||||
let url = BASE_URL_GEOHR_API2+`/employee_devision.php?act=get_data`; |
|
||||||
|
|
||||||
const result = await axios |
|
||||||
.get(url) |
|
||||||
.then(res => res) |
|
||||||
.catch((error) => error.response ); |
|
||||||
console.log('cek', result) |
|
||||||
|
|
||||||
if(result && result.data && result.data.code_status === 200){ |
|
||||||
this.setState({ dataDivision:result.data.data },()=>{ |
|
||||||
this.setDataDivision(); |
|
||||||
}) |
|
||||||
}else{ |
|
||||||
if(countError<6){ |
|
||||||
this.getDataDivision(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
getDataRoles = async () => { |
|
||||||
countError++; |
|
||||||
let url = BASE_URL_GEOHR_API2+`/roles.php?act=get_data`; |
|
||||||
|
|
||||||
const result = await axios |
|
||||||
.get(url) |
|
||||||
.then(res => res) |
|
||||||
.catch((error) => error.response ); |
|
||||||
console.log('cek', result) |
|
||||||
|
|
||||||
if(result && result.data && result.data.code_status === 200){ |
|
||||||
this.setState({ dataRoles:result.data.data },()=>{ |
|
||||||
this.setDataRoles(); |
|
||||||
}) |
|
||||||
}else{ |
|
||||||
if(countError<6){ |
|
||||||
this.getDataRoles(); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
setDataDivision = () => { |
|
||||||
const { dataDivision } = this.state |
|
||||||
const listDivision = [] |
|
||||||
dataDivision.map((val, index)=> { |
|
||||||
listDivision.push({ |
|
||||||
value:val.id, |
|
||||||
label:val.name |
|
||||||
}) |
|
||||||
}) |
|
||||||
this.setState({ listDivisionSelect:listDivision }) |
|
||||||
} |
|
||||||
|
|
||||||
setDataRoles = () => { |
|
||||||
const { dataRoles } = this.state |
|
||||||
const listRoles = [] |
|
||||||
dataRoles.map((val, index)=> { |
|
||||||
listRoles.push({ |
|
||||||
value:val.id, |
|
||||||
label:val.name |
|
||||||
}) |
|
||||||
}) |
|
||||||
this.setState({ listRolesSelect:listRoles }) |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
searchDivision = (id) => { |
|
||||||
let getIndex = this.getIndexDataDivision(id); |
|
||||||
let data = this.state.dataDivision[getIndex] |
|
||||||
this.setState({ idDivision:data.id,currentSelectVal:{value:data.id,label:data.name} }) |
|
||||||
} |
|
||||||
|
|
||||||
getIndexDataDivision = (val) => { |
|
||||||
let index = this.state.dataDivision.findIndex(obj => obj.id === val); |
|
||||||
return index |
|
||||||
} |
|
||||||
|
|
||||||
searchRoles = (id) => { |
|
||||||
let getIndex = this.getIndexDataRoles(id); |
|
||||||
let data = this.state.dataRoles[getIndex] |
|
||||||
this.setState({ idRoles:data.id,currentSelectRoles:{value:data.id,label:data.name} }) |
|
||||||
} |
|
||||||
|
|
||||||
getIndexDataRoles = (val) => { |
|
||||||
let index = this.state.dataRoles.findIndex(obj => obj.id === val); |
|
||||||
return index |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
showDialog = () => { |
|
||||||
this.setState({ isParentClick : true }); |
|
||||||
} |
|
||||||
|
|
||||||
handleDeletePhoto = (data) => { |
|
||||||
this.setState({ alertDelete: true, dataPhoto: data }, () => { |
|
||||||
console.log('data photo', this.state.dataPhoto) |
|
||||||
}); |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
handleSave = async () => { |
|
||||||
const {
|
|
||||||
id, |
|
||||||
idDivision, |
|
||||||
username, |
|
||||||
name, |
|
||||||
email, |
|
||||||
password, |
|
||||||
address, |
|
||||||
phoneNumber, |
|
||||||
idRoles, |
|
||||||
birthPlace, |
|
||||||
birthDate, |
|
||||||
currentSelectGender, |
|
||||||
hobby, |
|
||||||
currentSelectBlood, |
|
||||||
nik, |
|
||||||
files, |
|
||||||
currentSelectRoles |
|
||||||
} = this.state |
|
||||||
|
|
||||||
let data = ''; |
|
||||||
if(this.props.typeDialog==="Save"){ |
|
||||||
data = { |
|
||||||
idDivision, |
|
||||||
username, |
|
||||||
name, |
|
||||||
email, |
|
||||||
password, |
|
||||||
address, |
|
||||||
phoneNumber, |
|
||||||
idRoles, |
|
||||||
birthPlace, |
|
||||||
birthDate, |
|
||||||
currentSelectGender, |
|
||||||
hobby, |
|
||||||
nik, |
|
||||||
currentSelectBlood, |
|
||||||
files, |
|
||||||
currentSelectRoles |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
this.props.closeDialog('save', data); |
|
||||||
}else{ |
|
||||||
data = { |
|
||||||
id, |
|
||||||
username, |
|
||||||
name, |
|
||||||
email, |
|
||||||
password, |
|
||||||
address, |
|
||||||
phoneNumber, |
|
||||||
idDivision, |
|
||||||
idRoles, |
|
||||||
birthPlace, |
|
||||||
birthDate, |
|
||||||
currentSelectGender, |
|
||||||
hobby, |
|
||||||
nik,
|
|
||||||
currentSelectBlood, |
|
||||||
currentSelectRoles |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
console.log('test log data', data) |
|
||||||
|
|
||||||
if (files.length > 0) { |
|
||||||
const formData = new FormData() |
|
||||||
files.map((res) => { |
|
||||||
if (res) |
|
||||||
formData.append("ref_id", id); |
|
||||||
formData.append("files", res); |
|
||||||
}) |
|
||||||
await axios.post(`${API}/image/employee/upload`, formData).then(response => response).catch(err => err.response) |
|
||||||
} |
|
||||||
|
|
||||||
this.props.closeDialog('edit', data); |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
this.setState({ id:0,idDivision:0,currentSelectVal:null, currentSelectRoles: null, currentSelectGender: null, currentSelectBlood: null }); |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
handleCancel = () => { |
|
||||||
this.setState({ id:0,currentSelectVal:null, currentSelectRoles: null, currentSelectGender: null, currentSelectBlood: null }); |
|
||||||
this.props.closeDialog('cancel', 'none') |
|
||||||
} |
|
||||||
|
|
||||||
handleSelectGs = (inputValue, actionMeta) => { |
|
||||||
this.setState({ idDivision:inputValue.value,currentSelectVal:{ value:inputValue.value,label:inputValue.label } }) |
|
||||||
} |
|
||||||
|
|
||||||
handleSelectRoles = (inputValue, actionMeta) => { |
|
||||||
this.setState({ idRoles:inputValue.value,currentSelectRoles:{ value:inputValue.value,label:inputValue.label } }, ()=> { |
|
||||||
console.log("test select role", this.state.currentSelectRoles) |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
onConfirmDeletePhoto = async () => { |
|
||||||
const { id, dataPhoto } = this.state |
|
||||||
let url = `https://oslog.id/geohr-api/image/employee/${id}/delete?files=${dataPhoto.image}` |
|
||||||
let result = await axios.delete(url) |
|
||||||
.then(res => res) |
|
||||||
.catch((error) => error.response); |
|
||||||
|
|
||||||
if(result.message!==undefined){ |
|
||||||
|
|
||||||
}else{ |
|
||||||
|
|
||||||
} |
|
||||||
console.log("test data photooo", result) |
|
||||||
|
|
||||||
if (result) { |
|
||||||
this.getUrlImagery(id) |
|
||||||
|
|
||||||
this.setState({ dataPhoto: null, alertDelete: false }) |
|
||||||
NotificationManager.success('Foto berhasil dihapus!!', 'Success!!'); |
|
||||||
} else { |
|
||||||
this.getUrlImagery(id) |
|
||||||
|
|
||||||
this.setState({ dataPhoto: null, alertDelete: false }) |
|
||||||
NotificationManager.error('Foto gagal dihapus!!', 'Failed!!'); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
renderForm = () => { |
|
||||||
const {files} = this.state |
|
||||||
const {typeDialog} = this.props |
|
||||||
let typeRole = localStorage.getItem('role_name') |
|
||||||
|
|
||||||
return( |
|
||||||
<Form> |
|
||||||
<Row> |
|
||||||
<Col md={6} xs={12}> |
|
||||||
{/* <FormGroup> |
|
||||||
<Label className="formLabel">Divisi</Label> |
|
||||||
<Select options={this.state.listDivisionSelect} onChange={this.handleSelectGs} value={this.state.currentSelectVal} isDisabled={typeDialog === "View"} /> |
|
||||||
</FormGroup> */} |
|
||||||
|
|
||||||
<Row> |
|
||||||
<Col md={6} xs={6}> |
|
||||||
<FormGroup> |
|
||||||
<Label className="formLabel">Nama Pengguna</Label> |
|
||||||
<Input readOnly={typeDialog === "View"} type="text" value={this.state.username} onChange={(e) => this.setState({username:e.target.value})} placeholder="" /> |
|
||||||
</FormGroup> |
|
||||||
</Col> |
|
||||||
<Col md={6} xs={6}> |
|
||||||
<FormGroup> |
|
||||||
<Label className="formLabel">Kata Sandi</Label> |
|
||||||
<Input readOnly={typeDialog === "View"} type="password" value={this.state.password} onChange={(e) => this.setState({password:e.target.value})} placeholder="" /> |
|
||||||
{this.props.typeDialog==="Save" ? "" : <p>*Kosongkan jika tidak ada perubahaan</p>} |
|
||||||
|
|
||||||
</FormGroup> |
|
||||||
</Col> |
|
||||||
</Row> |
|
||||||
<FormGroup> |
|
||||||
<Label className="formLabel">NIK (KTP)</Label> |
|
||||||
<Input readOnly={typeDialog === "View"} type="text" value={this.state.nik} onChange={(e) => this.setState({nik:e.target.value})} placeholder="" /> |
|
||||||
</FormGroup> |
|
||||||
|
|
||||||
<FormGroup> |
|
||||||
<Label className="formLabel">Nama</Label> |
|
||||||
<Input readOnly={typeDialog === "View"} type="text" value={this.state.name} onChange={(e) => this.setState({name:e.target.value})} placeholder="" /> |
|
||||||
</FormGroup> |
|
||||||
|
|
||||||
<FormGroup> |
|
||||||
<Label className="formLabel">Email</Label> |
|
||||||
<Input readOnly={typeDialog === "View"} type="email" value={this.state.email} onChange={(e) => this.setState({email:e.target.value})} placeholder="" /> |
|
||||||
</FormGroup> |
|
||||||
|
|
||||||
<FormGroup> |
|
||||||
<Label className="formLabel">Nomor Telepon</Label> |
|
||||||
<Input readOnly={typeDialog === "View"} type="number" value={this.state.phoneNumber} onChange={(e) => this.setState({phoneNumber:e.target.value})} placeholder="" /> |
|
||||||
</FormGroup> |
|
||||||
|
|
||||||
<FormGroup> |
|
||||||
{typeDialog !== "View" && ( |
|
||||||
<> |
|
||||||
<Label for="exampleFile">File</Label> |
|
||||||
<Input type="file" name="file" id="exampleFile" multiple onChange={this.fileSelectedHandler} /> |
|
||||||
<FormText>Max Size 1Mb</FormText> |
|
||||||
</> |
|
||||||
)} |
|
||||||
{files && ( |
|
||||||
<div style={{ maxHeight: "300px", maxWidth: "100%", overflowY: "auto",display: "flex", flexDirection: "row" }}> |
|
||||||
{files.map((item) => { |
|
||||||
let checkImg = null |
|
||||||
if (item.image) { |
|
||||||
checkImg = `${API}/assets/images/employee/${item.image}` |
|
||||||
} else { |
|
||||||
checkImg = URL.createObjectURL(item) |
|
||||||
} |
|
||||||
return ( |
|
||||||
<div> |
|
||||||
{typeDialog === "Edit" && ( |
|
||||||
<div onClick={() => this.handleDeletePhoto(item)} style={{cursor: "pointer", position: "absolute", width: 30, height: 30, borderRadius: 30 / 2, backgroundColor: "grey", marginTop: 10, marginLeft: 10, justifyContent: "center", alignContent: "center", paddingTop: 4, paddingLeft: 5 }}> |
|
||||||
<i className="cil-trash fa-lg" style={{ color: 'red'}}></i> |
|
||||||
</div> |
|
||||||
) |
|
||||||
} |
|
||||||
<img key={item.id} src={checkImg} alt="..." style={{ maxWidth: "150px", maxHeight: "150px" }} /> |
|
||||||
</div> |
|
||||||
) |
|
||||||
})} |
|
||||||
</div> |
|
||||||
) |
|
||||||
} |
|
||||||
</FormGroup> |
|
||||||
</Col> |
|
||||||
|
|
||||||
<Col md={6} xs={12}> |
|
||||||
{typeRole === "Superadmin" && ( |
|
||||||
<FormGroup> |
|
||||||
<Label className="formLabel">Roles</Label> |
|
||||||
<Select options={this.state.listRolesSelect} onChange={this.handleSelectRoles} value={this.state.currentSelectRoles} isDisabled={typeDialog === "View"} /> |
|
||||||
</FormGroup> |
|
||||||
) |
|
||||||
} |
|
||||||
|
|
||||||
<FormGroup> |
|
||||||
<Label className="formLabel">Jenis Kelamin</Label> |
|
||||||
<Select options={listGender} onChange={(inputValue, actionMeta) => this.setState({currentSelectGender: {value: inputValue.value, label: inputValue.label}})} value={this.state.currentSelectGender} isDisabled={typeDialog === "View"} /> |
|
||||||
</FormGroup> |
|
||||||
|
|
||||||
<FormGroup style={{ marginTop: 30 }}> |
|
||||||
<Label className="formLabel">Golongan Darah</Label> |
|
||||||
<Select options={listBlood} onChange={(inputValue, actionMeta) => this.setState({currentSelectBlood: {value: inputValue.value, label: inputValue.label}})} value={this.state.currentSelectBlood} isDisabled={typeDialog === "View"} /> |
|
||||||
</FormGroup> |
|
||||||
|
|
||||||
<Row> |
|
||||||
<Col md={6} xs={12}> |
|
||||||
<FormGroup> |
|
||||||
<Label className="formLabel">Tempat Lahir</Label> |
|
||||||
<Input readOnly={typeDialog === "View"} type="text" value={this.state.birthPlace} onChange={(e) => this.setState({birthPlace:e.target.value})} placeholder="" /> |
|
||||||
</FormGroup> |
|
||||||
</Col> |
|
||||||
<Col md={6} xs={12}> |
|
||||||
<FormGroup> |
|
||||||
<Label className="formLabel">Tanggal Lahir</Label> |
|
||||||
<Row> |
|
||||||
<Col md={12}> |
|
||||||
<DatePicker disabled={typeDialog === "View"} style={{width: "100%"}} onChange={(e, val) => this.setState({birthDate: val})} defaultValue={this.state.birthDate ? moment(this.state.birthDate, format) : null} /> |
|
||||||
</Col> |
|
||||||
</Row> |
|
||||||
</FormGroup> |
|
||||||
</Col> |
|
||||||
</Row> |
|
||||||
|
|
||||||
<FormGroup> |
|
||||||
<Label className="formLabel">Alamat</Label> |
|
||||||
<Input readOnly={typeDialog === "View"} type="text" value={this.state.address} onChange={(e) => this.setState({address:e.target.value})} placeholder="" /> |
|
||||||
</FormGroup> |
|
||||||
|
|
||||||
<FormGroup> |
|
||||||
<Label className="formLabel">Hobby</Label> |
|
||||||
<Input readOnly={typeDialog === "View"} type="text" value={this.state.hobby} onChange={(e) => this.setState({hobby:e.target.value})} placeholder="" /> |
|
||||||
</FormGroup> |
|
||||||
|
|
||||||
</Col> |
|
||||||
</Row> |
|
||||||
</Form> |
|
||||||
) |
|
||||||
} |
|
||||||
|
|
||||||
render() { |
|
||||||
const {typeDialog} = this.props |
|
||||||
return ( |
|
||||||
<Modal size="xl" isOpen={this.props.openDialog} toggle={this.props.toggleDialog}> |
|
||||||
<NotificationContainer /> |
|
||||||
|
|
||||||
<SweetAlert |
|
||||||
show={this.state.alertDelete} |
|
||||||
warning |
|
||||||
showCancel |
|
||||||
confirmBtnText="Delete" |
|
||||||
confirmBtnBsStyle="danger" |
|
||||||
title="Are you sure?" |
|
||||||
onConfirm={this.onConfirmDeletePhoto} |
|
||||||
onCancel={() => this.setState({ alertDelete: false, dataPhoto: null})} |
|
||||||
focusCancelBtn |
|
||||||
> |
|
||||||
Foto Akan Terhapus!! |
|
||||||
</SweetAlert> |
|
||||||
<ModalHeader toggle={() => this.handleCancel()}>{this.props.typeDialog} Karyawan</ModalHeader> |
|
||||||
<ModalBody> |
|
||||||
{this.renderForm()} |
|
||||||
</ModalBody> |
|
||||||
{typeDialog !== "View" && ( |
|
||||||
|
|
||||||
<ModalFooter> |
|
||||||
<Button color="primary" onClick={() => this.handleSave()}>{this.props.typeDialog}</Button>{' '} |
|
||||||
<Button color="secondary" onClick={() => this.handleCancel()}>Cancel</Button> |
|
||||||
</ModalFooter> |
|
||||||
)} |
|
||||||
</Modal> |
|
||||||
) |
|
||||||
} |
|
||||||
} |
|
@ -1,79 +0,0 @@ |
|||||||
import React, { Component } from 'react' |
|
||||||
import { Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap'; |
|
||||||
import { Col, Row, Button, Form, FormGroup, Label, Input } from 'reactstrap'; |
|
||||||
import moment from 'moment'; |
|
||||||
import 'antd/dist/antd.css'; |
|
||||||
|
|
||||||
export default class DialogImport extends Component { |
|
||||||
constructor(props) { |
|
||||||
super(props) |
|
||||||
this.state = { |
|
||||||
dataImport:null, |
|
||||||
openDialog: false, |
|
||||||
isParentClick: false, |
|
||||||
disable: false |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
async componentDidMount(){ |
|
||||||
this.props.showDialog(this.showDialog); |
|
||||||
} |
|
||||||
|
|
||||||
async componentDidUpdate (){ |
|
||||||
if(this.state.isParentClick===true){ |
|
||||||
this.setState({isParentClick:false}); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
showDialog = () => { |
|
||||||
this.setState({ isParentClick : true }); |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
handleSave = () => { |
|
||||||
const {
|
|
||||||
dataImport |
|
||||||
} = this.state |
|
||||||
|
|
||||||
|
|
||||||
this.props.closeDialog('import', dataImport); |
|
||||||
this.setState({ dataImport:null }); |
|
||||||
} |
|
||||||
|
|
||||||
handleCancel = () => { |
|
||||||
this.props.closeDialog('cancel', 'none') |
|
||||||
} |
|
||||||
|
|
||||||
importExcel = (e) => { |
|
||||||
e.preventDefault(); |
|
||||||
let file = e.target.files[0]; |
|
||||||
this.setState({dataImport:file}); |
|
||||||
} |
|
||||||
|
|
||||||
renderForm = () => { |
|
||||||
return( |
|
||||||
<Form> |
|
||||||
<FormGroup> |
|
||||||
<Label>Excel</Label> |
|
||||||
<Input type="file" onChange={this.importExcel} /> |
|
||||||
</FormGroup> |
|
||||||
</Form> |
|
||||||
) |
|
||||||
} |
|
||||||
|
|
||||||
render() { |
|
||||||
return ( |
|
||||||
<Modal isOpen={this.props.openDialog} toggle={this.props.toggleDialog}> |
|
||||||
<ModalHeader toggle={this.props.closeDialog}>Import Data Karyawan</ModalHeader> |
|
||||||
<ModalBody> |
|
||||||
{this.renderForm()} |
|
||||||
</ModalBody> |
|
||||||
<ModalFooter> |
|
||||||
<Button color="primary" onClick={() => this.handleSave()}>Import</Button>{' '} |
|
||||||
<Button color="secondary" onClick={() => this.handleCancel()}>Cancel</Button> |
|
||||||
</ModalFooter> |
|
||||||
</Modal> |
|
||||||
) |
|
||||||
} |
|
||||||
} |
|
@ -1,607 +0,0 @@ |
|||||||
import React, { Component } from 'react'; |
|
||||||
import { Card, CardBody, CardHeader, Col, Row, Table, Input,InputGroup, InputGroupButtonDropdown, DropdownToggle, DropdownItem, DropdownMenu,ButtonDropdown } from 'reactstrap'; |
|
||||||
import { Button } from 'reactstrap'; |
|
||||||
import axios from 'axios'; |
|
||||||
import moment from 'moment'; |
|
||||||
import SweetAlert from 'react-bootstrap-sweetalert'; |
|
||||||
import DialogForm from './DialogForm'; |
|
||||||
import DialogImport from './DialogImport'; |
|
||||||
import { NotificationContainer, NotificationManager } from 'react-notifications'; |
|
||||||
import { Pagination } from 'antd'; |
|
||||||
import { Tooltip } from 'reactstrap'; |
|
||||||
import * as XLSX from 'xlsx'; |
|
||||||
import { BASE_URL_GEOHR_API2 } from '../../../const/ApiConst' |
|
||||||
import { Icon, InlineIcon } from '@iconify/react'; |
|
||||||
import eyeFilled from '@iconify/icons-ant-design/eye-filled'; |
|
||||||
import { Link } from 'react-router-dom'; |
|
||||||
|
|
||||||
const id_org = window.localStorage.getItem('id_org'); |
|
||||||
const roleName = window.localStorage.getItem('role_name'); |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const momentFormat = 'HH:mm'; |
|
||||||
|
|
||||||
const column = [ |
|
||||||
{ name: "Organasi" }, |
|
||||||
{ name: "Nama" },
|
|
||||||
{ name: "Email" },
|
|
||||||
{ name: "Nomor Handphone" },
|
|
||||||
] |
|
||||||
|
|
||||||
const LENGTH_DATA = 10 |
|
||||||
|
|
||||||
const API = `https://oslog.id/geohr-api` |
|
||||||
|
|
||||||
|
|
||||||
export default class index extends Component { |
|
||||||
constructor(props) { |
|
||||||
super(props) |
|
||||||
this.state = { |
|
||||||
dataTable: [], |
|
||||||
finalData: [], |
|
||||||
openDialog: false, |
|
||||||
typeDialog: 'Save', |
|
||||||
dataEdit: null, |
|
||||||
alertDelete: false, |
|
||||||
idDelete: 0, |
|
||||||
dataGs: [], |
|
||||||
dataIdHo: [], |
|
||||||
search: "", |
|
||||||
page: 0, |
|
||||||
rowsPerPage: LENGTH_DATA, |
|
||||||
currentPage: 1, |
|
||||||
totalPage: 0, |
|
||||||
tooltipEdit: false, |
|
||||||
tooltipDelete: false, |
|
||||||
splitButtonOpen:false, |
|
||||||
searchDetail: "Nama", |
|
||||||
searchDetailField: "name", |
|
||||||
tooltipDetail: false, |
|
||||||
tooltipTambah:false, |
|
||||||
tooltipImport:false, |
|
||||||
tooltipExport:false, |
|
||||||
dataImport: null, |
|
||||||
aksiDropdown:false, |
|
||||||
openDialogImport:false, |
|
||||||
dataExport:false, |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
async componentDidMount() { |
|
||||||
this.getDataEmployee(); |
|
||||||
} |
|
||||||
|
|
||||||
async componentDidUpdate(prevProps, prevState) { |
|
||||||
const { search } = this.state |
|
||||||
if (search !== prevState.search) this.getDataEmployee() |
|
||||||
} |
|
||||||
|
|
||||||
toggleAksiDropdown = () => { |
|
||||||
this.setState({aksiDropdown:!this.state.aksiDropdown}); |
|
||||||
} |
|
||||||
|
|
||||||
handleSearch = e => { |
|
||||||
const value = e.target.value |
|
||||||
this.setState({ search: value, currentPage: 1 }) |
|
||||||
}; |
|
||||||
|
|
||||||
getDataEmployee = async () => { |
|
||||||
let start = 0; |
|
||||||
if (this.state.currentPage !== 1) { |
|
||||||
start = (this.state.currentPage * this.state.rowsPerPage) - this.state.rowsPerPage |
|
||||||
} |
|
||||||
let url = BASE_URL_GEOHR_API2 + `/employee.php?act=get_data&start=${start}&length=${this.state.rowsPerPage}&role_name=${roleName}`; |
|
||||||
const formData = new FormData(); |
|
||||||
formData.append("id_org", id_org); |
|
||||||
formData.append('field', this.state.searchDetailField); |
|
||||||
formData.append('value', this.state.search); |
|
||||||
const result = await axios |
|
||||||
.post(url,formData) |
|
||||||
.then(res => res) |
|
||||||
.catch((error) => error.response); |
|
||||||
if (result && result.data && result.statusText == "OK") { |
|
||||||
this.setState({ dataTable: result.data.data, totalPage: result.data.total_record }); |
|
||||||
} else { |
|
||||||
NotificationManager.error('Failed retreiving data!!', 'Failed'); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
setListIdHo = (data) => { |
|
||||||
let list = []; |
|
||||||
data.map((val, index) => { |
|
||||||
list.push(val.sales) |
|
||||||
}) |
|
||||||
this.setState({ dataIdHo: list }, () => { |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
handleOpenDialog = (type) => { |
|
||||||
this.setState({ openDialog: true, typeDialog: type }) |
|
||||||
this.showChildDialog(); |
|
||||||
} |
|
||||||
|
|
||||||
handleCloseDialog = async (type, data) => { |
|
||||||
let result = false; |
|
||||||
if (type === "save") { |
|
||||||
result = await this.saveEmployee(data); |
|
||||||
} else if (type === "edit") { |
|
||||||
result = await this.editEmployee(data); |
|
||||||
} |
|
||||||
else if (type === "cancel") { |
|
||||||
result = true; |
|
||||||
} |
|
||||||
|
|
||||||
if (result) { |
|
||||||
this.setState({ openDialog: false }) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
toggleAddDialog = () => { |
|
||||||
this.setState({ openDialog: !this.state.openDialog }) |
|
||||||
} |
|
||||||
|
|
||||||
onConfirmDelete = async () => { |
|
||||||
const { idDelete } = this.state |
|
||||||
let url = BASE_URL_GEOHR_API2 + `/employee.php?act=delete&id=${idDelete}`; |
|
||||||
let result = await axios.get(url) |
|
||||||
.then(res => res) |
|
||||||
.catch((error) => error.response); |
|
||||||
|
|
||||||
if(result.message!==undefined){ |
|
||||||
|
|
||||||
}else{ |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
if (result.data.message === "Data Has Been Deleted") { |
|
||||||
this.getDataEmployee() |
|
||||||
this.setState({ idDelete: 0, alertDelete: false }) |
|
||||||
NotificationManager.success('Data employee berhasil dihapus!!', 'Success!!'); |
|
||||||
} else { |
|
||||||
this.setState({ idDelete: 0, alertDelete: false }) |
|
||||||
NotificationManager.error('Data employee gagal dihapus!!', 'Failed!!'); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
saveEmployee = async (data) => { |
|
||||||
let url = BASE_URL_GEOHR_API2 + "/employee.php?act=input"; |
|
||||||
const formData = new FormData(); |
|
||||||
formData.append('name', data.name); |
|
||||||
formData.append('username', data.username); |
|
||||||
formData.append('phone_number', data.phoneNumber); |
|
||||||
formData.append('email', data.email); |
|
||||||
formData.append('address', data.name); |
|
||||||
formData.append('password', data.password); |
|
||||||
formData.append('birth_place', data.birthPlace); |
|
||||||
formData.append('birth_date', data.birthDate); |
|
||||||
formData.append('gender', data.currentSelectGender ? data.currentSelectGender.value : ""); |
|
||||||
formData.append('hobby', data.hobby); |
|
||||||
formData.append('blood_type', data.currentSelectBlood ? data.currentSelectBlood.value: ""); |
|
||||||
formData.append('ktp_number', data.nik); |
|
||||||
formData.append('role_id', data.currentSelectRoles ? data.currentSelectRoles.value: ""); |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if(data.idRoles!==undefined && data.idRoles!==0 && data.idRoles!==null){ |
|
||||||
formData.append('roles_id', data.idRoles); |
|
||||||
} |
|
||||||
|
|
||||||
let result = await axios.post(url, formData) |
|
||||||
.then(res => res) |
|
||||||
.catch((error) => error.response); |
|
||||||
|
|
||||||
if (!result) { |
|
||||||
return false; |
|
||||||
} |
|
||||||
|
|
||||||
if(result && result.message!==undefined){ |
|
||||||
if (result.message === "Data Has Been Saved") { |
|
||||||
this.getDataEmployee(); |
|
||||||
NotificationManager.success('Data employee berhasil ditambahkan!!', 'Success!!'); |
|
||||||
return true; |
|
||||||
} else { |
|
||||||
NotificationManager.error(`${result.data.message}`, 'Failed!!'); |
|
||||||
return false; |
|
||||||
} |
|
||||||
}else{ |
|
||||||
if (result.data.message === "Data Has Been Saved") { |
|
||||||
this.getDataEmployee(); |
|
||||||
NotificationManager.success('Data employee berhasil ditambahkan!!', 'Success!!'); |
|
||||||
return true; |
|
||||||
} else { |
|
||||||
NotificationManager.error(`${result.data.message}`, 'Failed!!'); |
|
||||||
return false; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
let ref_id = parseInt(result.data.data.id) |
|
||||||
if (ref_id) { |
|
||||||
if (data.files.length > 0) { |
|
||||||
const formData = new FormData() |
|
||||||
data.files.map((res) => { |
|
||||||
console.log('test data upload photo', res) |
|
||||||
if (res) |
|
||||||
formData.append("ref_id", ref_id); |
|
||||||
formData.append("files", res); |
|
||||||
}) |
|
||||||
await axios.post(`${API}/image/employee/upload`, formData).then(response => response).catch(err => err.response) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
editEmployee = async (data) => { |
|
||||||
let url = BASE_URL_GEOHR_API2 + `/employee.php?act=edit&id=${data.id}&role_name=${roleName}`; |
|
||||||
const formData = new FormData(); |
|
||||||
formData.append('name', data.name); |
|
||||||
formData.append('username', data.username); |
|
||||||
formData.append('phone_number', data.phoneNumber); |
|
||||||
formData.append('email', data.email); |
|
||||||
formData.append('address', data.address); |
|
||||||
formData.append('birth_place', data.birthPlace); |
|
||||||
formData.append('birth_date', data.birthDate); |
|
||||||
formData.append('gender', data.currentSelectGender ? data.currentSelectGender.value : ""); |
|
||||||
formData.append('hobby', data.hobby); |
|
||||||
formData.append('blood_type', data.currentSelectBlood ? data.currentSelectBlood.value: ""); |
|
||||||
formData.append('role_id', data.currentSelectRoles ? data.currentSelectRoles.value: ""); |
|
||||||
|
|
||||||
formData.append('ktp_number', data.nik); |
|
||||||
|
|
||||||
|
|
||||||
if(data.password!==""){ |
|
||||||
formData.append('password', data.password); |
|
||||||
} |
|
||||||
|
|
||||||
if(data.idRoles!==undefined && data.idRoles!==0 && data.idRoles!==null){ |
|
||||||
formData.append('role_id', data.idRoles); |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let result = await axios.post(url, formData) |
|
||||||
.then(res => res) |
|
||||||
.catch((error) => error.response); |
|
||||||
|
|
||||||
if (!result) { |
|
||||||
return false; |
|
||||||
} |
|
||||||
|
|
||||||
if(result && result.message!==undefined){ |
|
||||||
if (result.message === "Data Has Been Edited") { |
|
||||||
this.getDataEmployee(); |
|
||||||
NotificationManager.success('Data karyawan berhasil diedit!!', 'Success!!'); |
|
||||||
return true; |
|
||||||
} else { |
|
||||||
NotificationManager.error('Data karyawan gagal diedit!!', 'Failed!!'); |
|
||||||
return false |
|
||||||
} |
|
||||||
}else{ |
|
||||||
if (result.data.message === "Data Has Been Edited") { |
|
||||||
this.getDataEmployee(); |
|
||||||
NotificationManager.success('Data karyawan berhasil diedit!!', 'Success!!'); |
|
||||||
return true; |
|
||||||
} else { |
|
||||||
NotificationManager.error('Data karyawan gagal diedit!!', 'Failed!!'); |
|
||||||
return false; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
handleEdit = (data) => { |
|
||||||
this.setState({ dataEdit: data }); |
|
||||||
this.handleOpenDialog('Edit'); |
|
||||||
} |
|
||||||
|
|
||||||
handleDetail = (data) => { |
|
||||||
this.setState({ dataEdit: data }) |
|
||||||
this.handleOpenDialog('View'); |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
handleDelete = (id) => { |
|
||||||
this.setState({ alertDelete: true, idDelete: id }); |
|
||||||
} |
|
||||||
|
|
||||||
onShowSizeChange = (current, pageSize) => { |
|
||||||
this.setState({ rowsPerPage: pageSize }, () => { |
|
||||||
this.getDataEmployee(); |
|
||||||
}) |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
onPagination = (current, pageSize) => { |
|
||||||
this.setState({ currentPage: current, page: (current - 1) * pageSize }, () => { |
|
||||||
this.getDataEmployee(); |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
toggle = (param) => { |
|
||||||
if (param === "edit") { |
|
||||||
this.setState(prevState => ({ tooltipEdit: !prevState.tooltipEdit })) |
|
||||||
} else if (param === "delete") { |
|
||||||
this.setState(prevState => ({ tooltipDelete: !prevState.tooltipDelete })) |
|
||||||
} else if (param === "detail") { |
|
||||||
this.setState(prevState => ({ tooltipDetail: !prevState.tooltipDetail })) |
|
||||||
} else if (param === "tambah") { |
|
||||||
this.setState(prevState => ({ tooltipTambah: !prevState.tooltipTambah })) |
|
||||||
} else if (param === "import") { |
|
||||||
this.setState(prevState => ({ tooltipImport : !prevState.tooltipImport })) |
|
||||||
} else if (param === "export") { |
|
||||||
this.setState(prevState => ({ tooltipExport: !prevState.tooltipExport })) |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
toggleDropDown = () => { |
|
||||||
this.setState({splitButtonOpen:!this.state.splitButtonOpen}) |
|
||||||
} |
|
||||||
|
|
||||||
handleDialogImport = () => { |
|
||||||
this.setState({ openDialogImport: true}) |
|
||||||
this.showImportDialog(); |
|
||||||
} |
|
||||||
|
|
||||||
handleCloseImport = (type, file) => { |
|
||||||
if(type==="import"){ |
|
||||||
if(!file){ |
|
||||||
NotificationManager.error('Silahkan masukan file excel!!', 'Failed!!'); |
|
||||||
return false |
|
||||||
} |
|
||||||
|
|
||||||
if (/\.(xls?x)$/i.test(file.name) === false ) {
|
|
||||||
NotificationManager.error('File yang dimasukan bukan format excel (.xsl/.xslx)!!', 'Failed!!'); |
|
||||||
return false |
|
||||||
} |
|
||||||
|
|
||||||
this.importExcel(file); |
|
||||||
|
|
||||||
}else{ |
|
||||||
this.setState({ openDialogImport:false }); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
toggleImportDialog = () => { |
|
||||||
this.setState({ openDialogImport:!this.state.openDialogImport }) |
|
||||||
} |
|
||||||
|
|
||||||
importExcel = async (file) => { |
|
||||||
const url = `${BASE_URL_GEOHR_API2}/employee.php?act=import`;
|
|
||||||
const formData = new FormData(); |
|
||||||
formData.append('file', file); |
|
||||||
const result = await axios |
|
||||||
.post(url, formData) |
|
||||||
.then((res) => res) |
|
||||||
.catch((error) => error.response); |
|
||||||
|
|
||||||
if(result && result.code_status){ |
|
||||||
if (result.code_status === 200) { |
|
||||||
NotificationManager.success('File imported successfully', 'Success Message'); |
|
||||||
this.getDataEmployee(); |
|
||||||
this.setState({openDialogImport: false}); |
|
||||||
} else { |
|
||||||
NotificationManager.error(result.data.message, "error message"); |
|
||||||
} |
|
||||||
}else{ |
|
||||||
NotificationManager.error("Import data karyawan gagal!!", "error message"); |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
getTemplateExcel = async (event) => { |
|
||||||
event.preventDefault(); |
|
||||||
const url = `${BASE_URL_GEOHR_API2}/dok/template-import-karyawan.xlsx`; |
|
||||||
window.open(url, "_blank"); |
|
||||||
}; |
|
||||||
|
|
||||||
|
|
||||||
handleExportExcel = async () => { |
|
||||||
let start = 0; |
|
||||||
let end = "ALL";
|
|
||||||
let url = BASE_URL_GEOHR_API2 + `/employee.php?act=get_data&start=${start}&length=${end}&role_name=${roleName}`; |
|
||||||
const formData = new FormData(); |
|
||||||
formData.append('field', this.state.searchDetailField); |
|
||||||
formData.append('value', this.state.search); |
|
||||||
const result = await axios |
|
||||||
.post(url,formData) |
|
||||||
.then(res => res) |
|
||||||
.catch((error) => error.response); |
|
||||||
if (result && result.data && result.statusText == "OK") { |
|
||||||
const dataRes = result.data.data|| []; |
|
||||||
const dataExport = []; |
|
||||||
dataRes.map((val,index)=> { |
|
||||||
let row = { |
|
||||||
Nama:val.name, |
|
||||||
Organisasi:val.organization_name || "-", |
|
||||||
Nik:val.ktp_number, |
|
||||||
Username:val.username, |
|
||||||
Email:val.email, |
|
||||||
"Nomor Handphone":val.phone_number, |
|
||||||
"Tanggal Lahir":val.birth_date, |
|
||||||
"Tempat Lahir":val.birth_place, |
|
||||||
"Hobby":val.hobby, |
|
||||||
"Jenis Kelamin":val.gender, |
|
||||||
"Golongan Data":val.blood_type, |
|
||||||
} |
|
||||||
dataExport.push(row); |
|
||||||
}) |
|
||||||
this.setState({ dataExport:dataExport },()=> { |
|
||||||
this.exportExcel(); |
|
||||||
}); |
|
||||||
} else { |
|
||||||
NotificationManager.error('Failed retreiving data!!', 'Failed'); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
exportExcel = () => { |
|
||||||
const dataExcel = this.state.dataExport || []; |
|
||||||
const fileName = "Data Karyawan.xlsx"; |
|
||||||
const ws = XLSX.utils.json_to_sheet(dataExcel); |
|
||||||
const wb = XLSX.utils.book_new(); |
|
||||||
XLSX.utils.book_append_sheet(wb, ws, 'Data Karyawan'); |
|
||||||
|
|
||||||
XLSX.writeFile(wb, fileName); |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
render() { |
|
||||||
const { tooltipTambah,tooltipImport,tooltipExport,tooltipDetail, dataTable, searchDetail, splitButtonOpen, openDialog, currentPage, rowsPerPage, totalPage, search, tooltipEdit, tooltipDelete } = this.state |
|
||||||
let dataTable2 = dataTable || []; |
|
||||||
return ( |
|
||||||
<div> |
|
||||||
<NotificationContainer /> |
|
||||||
<SweetAlert |
|
||||||
show={this.state.alertDelete} |
|
||||||
warning |
|
||||||
showCancel |
|
||||||
confirmBtnText="Delete" |
|
||||||
confirmBtnBsStyle="danger" |
|
||||||
title="Are you sure?" |
|
||||||
onConfirm={this.onConfirmDelete} |
|
||||||
onCancel={() => this.setState({ alertDelete: false, idDelete: 0 })} |
|
||||||
focusCancelBtn |
|
||||||
> |
|
||||||
Data karyawan akan terhapus!! |
|
||||||
</SweetAlert> |
|
||||||
<DialogForm |
|
||||||
openDialog={openDialog} |
|
||||||
closeDialog={this.handleCloseDialog} |
|
||||||
toggleDialog={() => this.toggleAddDialog} |
|
||||||
typeDialog={this.state.typeDialog} |
|
||||||
dataEdit={this.state.dataEdit} |
|
||||||
showDialog={showDialog => this.showChildDialog = showDialog} |
|
||||||
dataHs={this.state.dataIdHo} |
|
||||||
/> |
|
||||||
<DialogImport |
|
||||||
openDialog={this.state.openDialogImport} |
|
||||||
closeDialog={this.handleCloseImport} |
|
||||||
toggleDialog={() => this.toggleImportDialog} |
|
||||||
showDialog={showDialog => this.showImportDialog = showDialog} |
|
||||||
/> |
|
||||||
<Card> |
|
||||||
<CardHeader style={{margin:0}}> |
|
||||||
<Row style={{padding:0,margin:0}}> |
|
||||||
<Col md={7} xs={7}> |
|
||||||
<h4>Karyawan</h4> |
|
||||||
</Col> |
|
||||||
<Col md={3} xs={3}> |
|
||||||
<InputGroup> |
|
||||||
<Input onChange={this.handleSearch} value={search} type="text" name="search" id="search" placeholder={`Search ${searchDetail}`} /> |
|
||||||
<InputGroupButtonDropdown addonType="prepend" |
|
||||||
isOpen={splitButtonOpen} |
|
||||||
toggle={this.toggleDropDown} |
|
||||||
> |
|
||||||
<DropdownToggle split outline /> |
|
||||||
<DropdownMenu> |
|
||||||
<DropdownItem onClick={ |
|
||||||
() => this.setState({ |
|
||||||
searchDetail: "Nama", |
|
||||||
searchDetailField: "name" |
|
||||||
})}>Nama</DropdownItem> |
|
||||||
<DropdownItem onClick={ |
|
||||||
() => this.setState({ |
|
||||||
searchDetail: "Nomor Handphone", |
|
||||||
searchDetailField: "phone_number" |
|
||||||
})}>Nomor Handphone</DropdownItem> |
|
||||||
<DropdownItem onClick={ |
|
||||||
() => this.setState({ |
|
||||||
searchDetail: "Email", |
|
||||||
searchDetailField: "email" |
|
||||||
})}>Email</DropdownItem> |
|
||||||
<DropdownItem onClick={ |
|
||||||
() => this.setState({ |
|
||||||
searchDetail: "Alamat", |
|
||||||
searchDetailField: "address" |
|
||||||
})}>Alamat</DropdownItem> |
|
||||||
</DropdownMenu> |
|
||||||
</InputGroupButtonDropdown> |
|
||||||
</InputGroup> |
|
||||||
</Col> |
|
||||||
<Col md={2} xs={2} style={{display:"flex",justifyContent:"space-between"}}> |
|
||||||
<Button id="TooltipTambah" color="success" onClick={() => this.handleOpenDialog('Save')}><i className="fa fa-plus"></i></Button> |
|
||||||
<ButtonDropdown id="TooltipImport" direction="down" isOpen={this.state.aksiDropdown} toggle={() => this.toggleAksiDropdown()}> |
|
||||||
<DropdownToggle color="info" caret > |
|
||||||
<i className="fa fa-cloud-upload"></i> |
|
||||||
</DropdownToggle> |
|
||||||
<DropdownMenu> |
|
||||||
<DropdownItem onClick={() => this.handleDialogImport()}>Import Data Karyawan</DropdownItem> |
|
||||||
<DropdownItem onClick={(e) => this.getTemplateExcel(e)}>Download Template</DropdownItem> |
|
||||||
</DropdownMenu> |
|
||||||
</ButtonDropdown> |
|
||||||
<Button id="TooltipExport" color="primary" onClick={()=> this.handleExportExcel()}><i className="fa fa-print"></i></Button> |
|
||||||
<Tooltip placement="right" isOpen={tooltipTambah} target="TooltipTambah" toggle={() => this.toggle("tambah")}> |
|
||||||
Tambah |
|
||||||
</Tooltip> |
|
||||||
<Tooltip placement="right" isOpen={tooltipImport} target="TooltipImport" toggle={() => this.toggle("import")}> |
|
||||||
Import Excel |
|
||||||
</Tooltip> |
|
||||||
<Tooltip placement="right" isOpen={tooltipExport} target="TooltipExport" toggle={() => this.toggle("export")}> |
|
||||||
Export Excel |
|
||||||
</Tooltip> |
|
||||||
</Col> |
|
||||||
</Row> |
|
||||||
</CardHeader> |
|
||||||
<CardBody> |
|
||||||
<Table responsive striped hover> |
|
||||||
<thead> |
|
||||||
<tr> |
|
||||||
<th>Aksi</th> |
|
||||||
{column.map((i, index) => { |
|
||||||
return ( |
|
||||||
<th key={index} scope="row">{i.name}</th> |
|
||||||
) |
|
||||||
})} |
|
||||||
</tr> |
|
||||||
</thead> |
|
||||||
<tbody> |
|
||||||
{dataTable2.map((n) => { |
|
||||||
return ( |
|
||||||
<tr key={n.id}> |
|
||||||
<td> |
|
||||||
<i id="TooltipDelete" className="cil-trash fa-lg" style={{ color: 'red', marginRight: '10px', cursor: "pointer" }} onClick={() => this.handleDelete(n.id)}></i> |
|
||||||
<Tooltip placement="right" isOpen={tooltipDelete} target="TooltipDelete" toggle={() => this.toggle("delete")}> |
|
||||||
Hapus |
|
||||||
</Tooltip> |
|
||||||
<i id="TooltipEdit" className="cil-pencil fa-lg" style={{ color: 'green', cursor: "pointer" }} onClick={() => this.handleEdit(n)}></i> |
|
||||||
<Tooltip placement="right" isOpen={tooltipEdit} target="TooltipEdit" toggle={() => this.toggle("edit")}> |
|
||||||
Edit |
|
||||||
</Tooltip> |
|
||||||
<i id="TooltipDetail" style={{ marginLeft: 12, color: "blue", cursor: "pointer", }} onClick={() => this.handleDetail(n)}> |
|
||||||
|
|
||||||
<Icon style={{ marginBottom: 6 }} color="blue" width={22} height={22} icon={eyeFilled} /> |
|
||||||
</i> |
|
||||||
|
|
||||||
<Tooltip placement="right" isOpen={tooltipDetail} target="TooltipDetail" toggle={() => this.toggle("detail")}> |
|
||||||
Detail |
|
||||||
</Tooltip> |
|
||||||
</td> |
|
||||||
<td>{n.organization_name===null ? n.chairman_org || "-" : n.organization_name || "-"}</td> |
|
||||||
<td>{n.name}</td> |
|
||||||
<td>{n.email || "-"}</td> |
|
||||||
<td>{n.phone_number || "-"}</td> |
|
||||||
</tr> |
|
||||||
) |
|
||||||
})} |
|
||||||
</tbody> |
|
||||||
</Table> |
|
||||||
<Pagination |
|
||||||
showSizeChanger |
|
||||||
onShowSizeChange={this.onShowSizeChange} |
|
||||||
onChange={this.onPagination} |
|
||||||
defaultCurrent={currentPage} |
|
||||||
pageSize={rowsPerPage} |
|
||||||
total={totalPage} |
|
||||||
pageSizeOptions={["10", "15", "20", "25", "30", "35", "40"]} |
|
||||||
/> |
|
||||||
</CardBody> |
|
||||||
</Card> |
|
||||||
</div> |
|
||||||
) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
@ -1,262 +0,0 @@ |
|||||||
import React, { Component } from 'react' |
|
||||||
import { Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap'; |
|
||||||
import { Col, Row, Button, Form, FormGroup, Label, Input } from 'reactstrap'; |
|
||||||
import Select from 'react-select' |
|
||||||
|
|
||||||
export default class DialogForm extends Component { |
|
||||||
constructor(props) { |
|
||||||
super(props) |
|
||||||
this.state = { |
|
||||||
openDialog: false, |
|
||||||
type_sales:'B2B', |
|
||||||
name: '', |
|
||||||
email: '', |
|
||||||
address: '', |
|
||||||
username: '', |
|
||||||
phoneNumber: '', |
|
||||||
password:'', |
|
||||||
id: 0, |
|
||||||
idGs:0, |
|
||||||
isParentClick: false, |
|
||||||
file: [], |
|
||||||
fileObj: [], |
|
||||||
fileArray: [], |
|
||||||
dataGs: [], |
|
||||||
currentSelectVal: null, |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
async componentDidMount(){ |
|
||||||
this.props.showDialog(this.showDialog); |
|
||||||
this.cekDataGs() |
|
||||||
} |
|
||||||
|
|
||||||
async componentDidUpdate (){ |
|
||||||
if(this.state.isParentClick===true){ |
|
||||||
await this.cekDataGs() |
|
||||||
if(this.props.typeDialog==="Edit"){ |
|
||||||
let dataGs = this.searchGs(this.props.dataEdit.group_sales); |
|
||||||
this.setState({
|
|
||||||
idGs:this.props.dataEdit.group_sales, |
|
||||||
id:this.props.dataEdit.id, |
|
||||||
name:this.props.dataEdit.name, |
|
||||||
type_sales:this.props.dataEdit.type_sales, |
|
||||||
email: this.props.dataEdit.email, |
|
||||||
address: this.props.dataEdit.address, |
|
||||||
username: this.props.dataEdit.username, |
|
||||||
phoneNumber: this.props.dataEdit.phone_number, |
|
||||||
password:this.props.dataEdit.password, |
|
||||||
currentSelectVal:dataGs |
|
||||||
}) |
|
||||||
}else{ |
|
||||||
this.setState({
|
|
||||||
id:0, |
|
||||||
name:'', |
|
||||||
type_sales:'B2B', |
|
||||||
email: '', |
|
||||||
address:'', |
|
||||||
username: '', |
|
||||||
phoneNumber: '', |
|
||||||
password: '', |
|
||||||
currentSelectVal:null |
|
||||||
}) |
|
||||||
} |
|
||||||
this.setState({isParentClick:false}); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
searchGs = (idGs) => { |
|
||||||
let getIndex = this.getIndexDataGs(idGs); |
|
||||||
return this.state.dataGs[getIndex]; |
|
||||||
} |
|
||||||
|
|
||||||
getIndexDataGs = (val) => { |
|
||||||
let index = this.state.dataGs.findIndex(obj => obj.value === val); |
|
||||||
return index |
|
||||||
} |
|
||||||
|
|
||||||
cekDataGs = () => { |
|
||||||
if(this.state.dataGs.length===0){ |
|
||||||
let data = []; |
|
||||||
this.props.dataGs.map((val,index) => { |
|
||||||
data.push( |
|
||||||
{ |
|
||||||
value: val.id, |
|
||||||
label: val.name |
|
||||||
} |
|
||||||
) |
|
||||||
}); |
|
||||||
this.setState({ dataGs:data }) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
showDialog = () => { |
|
||||||
this.setState({ isParentClick : true }); |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
handleSave = () => { |
|
||||||
const { file, name, email, id, address, phoneNumber, password, username, idGs,type_sales } = this.state |
|
||||||
let data = ''; |
|
||||||
if(this.props.typeDialog==="Save"){ |
|
||||||
data = { |
|
||||||
username, |
|
||||||
password, |
|
||||||
name,
|
|
||||||
email,
|
|
||||||
address,
|
|
||||||
phone_number:phoneNumber, |
|
||||||
group_sales:idGs, |
|
||||||
type_sales |
|
||||||
} |
|
||||||
this.props.closeDialog('save', data, file); |
|
||||||
}else{ |
|
||||||
data = { |
|
||||||
id, |
|
||||||
username, |
|
||||||
password, |
|
||||||
name,
|
|
||||||
email,
|
|
||||||
address,
|
|
||||||
phone_number:phoneNumber, |
|
||||||
group_sales:idGs, |
|
||||||
type_sales |
|
||||||
} |
|
||||||
this.props.closeDialog('edit', data, file); |
|
||||||
} |
|
||||||
|
|
||||||
this.setState({ id:'',username:'',password:'',name:'',email:'',address:'',phoneNumber:'',file:[],idGs:0,type_sales:'B2B',currentSelectVal:null }); |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
handleCancel = () => { |
|
||||||
this.setState({ id:'',username:'',password:'',name:'',email:'',address:'',phoneNumber:'',file:[],idGs:0,type_sales:'B2B' }); |
|
||||||
this.props.closeDialog('cancel', 'none', 'none') |
|
||||||
} |
|
||||||
|
|
||||||
uploadMultipleImage = (event) => { |
|
||||||
this.setState({ fileObj: [...this.state.fileObj, event.target.files],file: [...this.state.file, event.target.files] }, ()=> { |
|
||||||
this.setUrl() |
|
||||||
}) |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
setUrl = () => { |
|
||||||
for (let i = 0; i < this.state.fileObj[0].length; i++) { |
|
||||||
this.setState({ fileArray: [...this.state.fileArray, URL.createObjectURL(this.state.fileObj[0][i])],fileObj:[] }) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
handleSelectGs = (inputValue, actionMeta) => { |
|
||||||
this.setState({ idGs:inputValue.value,currentSelectVal:{ value:inputValue.value,label:inputValue.label } }) |
|
||||||
} |
|
||||||
|
|
||||||
handleTypeSales = (e) => { |
|
||||||
this.setState({ type_sales:e.target.value }) |
|
||||||
} |
|
||||||
|
|
||||||
renderForm = () => { |
|
||||||
return( |
|
||||||
<Form> |
|
||||||
<Row form> |
|
||||||
<Col md={6}> |
|
||||||
<FormGroup> |
|
||||||
<Label for="exampleEmail">Group Sales </Label> |
|
||||||
<Select options={this.state.dataGs} onChange={this.handleSelectGs} value={this.state.currentSelectVal} /> |
|
||||||
</FormGroup> |
|
||||||
</Col> |
|
||||||
<Col md={6}> |
|
||||||
<FormGroup> |
|
||||||
<Label for="examplePassword">Username</Label> |
|
||||||
<Input type="text" value={this.state.username} onChange={(e)=> this.setState({ username:e.target.value })} placeholder="username " /> |
|
||||||
</FormGroup> |
|
||||||
</Col> |
|
||||||
</Row> |
|
||||||
<Row form> |
|
||||||
<Col md={6}> |
|
||||||
<FormGroup> |
|
||||||
<Label for="exampleEmail">Password </Label> |
|
||||||
<Input type="password" value={this.state.password} onChange={(e)=> this.setState({ password:e.target.value })} placeholder="password" /> |
|
||||||
</FormGroup> |
|
||||||
</Col> |
|
||||||
<Col md={6}> |
|
||||||
<FormGroup> |
|
||||||
<Label for="examplePassword">Name</Label> |
|
||||||
<Input type="text" value={this.state.name} onChange={(e)=> this.setState({ name:e.target.value })} placeholder="name " /> |
|
||||||
</FormGroup> |
|
||||||
</Col> |
|
||||||
</Row> |
|
||||||
<Row form> |
|
||||||
<Col md={6}> |
|
||||||
<FormGroup> |
|
||||||
<Label for="exampleEmail">Email</Label> |
|
||||||
<Input type="email" value={this.state.email} onChange={(e)=> this.setState({ email:e.target.value })} placeholder="email" /> |
|
||||||
</FormGroup> |
|
||||||
</Col> |
|
||||||
<Col md={6}> |
|
||||||
<FormGroup> |
|
||||||
<Label for="examplePassword">Address</Label> |
|
||||||
<Input type="text" value={this.state.address} onChange={(e)=> this.setState({ address:e.target.value })} placeholder="address " /> |
|
||||||
</FormGroup> |
|
||||||
</Col> |
|
||||||
</Row> |
|
||||||
<Row form> |
|
||||||
<Col md={6}> |
|
||||||
<FormGroup> |
|
||||||
<Label for="exampleEmail">Phone Number</Label> |
|
||||||
<Input type="number"value={this.state.phoneNumber} onChange={(e)=> this.setState({ phoneNumber:e.target.value })} placeholder="phone number" /> |
|
||||||
</FormGroup> |
|
||||||
</Col> |
|
||||||
<Col md={6}> |
|
||||||
<Label>Type Sales</Label> |
|
||||||
<Row> |
|
||||||
<Col md={6}> |
|
||||||
<FormGroup check> |
|
||||||
<Label check> |
|
||||||
<Input type="radio" name="radioTypeC" value="B2B" onChange={this.handleTypeSales} checked={this.state.type_sales==="B2B"} />{' '} |
|
||||||
B2B |
|
||||||
</Label> |
|
||||||
</FormGroup> |
|
||||||
</Col> |
|
||||||
<Col md={6}> |
|
||||||
<FormGroup check> |
|
||||||
<Label check> |
|
||||||
<Input type="radio" name="radioTypeC" value="B2C" onChange={this.handleTypeSales} checked={this.state.type_sales==="B2C"} />{' '} |
|
||||||
B2C |
|
||||||
</Label> |
|
||||||
</FormGroup> |
|
||||||
</Col> |
|
||||||
</Row> |
|
||||||
</Col> |
|
||||||
</Row> |
|
||||||
<FormGroup> |
|
||||||
<div style={{overflowY:"auto "}}> |
|
||||||
{(this.state.fileArray || []).map((url,index) => ( |
|
||||||
<img key={index} src={url} alt="..." style={{ maxWidth:"150px",maxHeight:"150px" }} /> |
|
||||||
))} |
|
||||||
</div> |
|
||||||
</FormGroup> |
|
||||||
<FormGroup> |
|
||||||
<Label for="exampleAddress">Images</Label> |
|
||||||
<Input type="file" onChange={this.uploadMultipleImage} /> |
|
||||||
</FormGroup> |
|
||||||
|
|
||||||
</Form> |
|
||||||
) |
|
||||||
} |
|
||||||
|
|
||||||
render() { |
|
||||||
return ( |
|
||||||
<Modal isOpen={this.props.openDialog} toggle={this.props.toggleDialog} size="xl"> |
|
||||||
<ModalHeader toggle={this.props.closeDialog}>Add Sales</ModalHeader> |
|
||||||
<ModalBody> |
|
||||||
{this.renderForm()} |
|
||||||
</ModalBody> |
|
||||||
<ModalFooter> |
|
||||||
<Button color="primary" onClick={() => this.handleSave()}>{this.props.typeDialog}</Button>{' '} |
|
||||||
<Button color="secondary" onClick={() => this.handleCancel()}>Cancel</Button> |
|
||||||
</ModalFooter> |
|
||||||
</Modal> |
|
||||||
) |
|
||||||
} |
|
||||||
} |
|
@ -1,347 +0,0 @@ |
|||||||
import React, { Component } from 'react'; |
|
||||||
import { Card, CardBody, CardHeader, Col, Row, Table, Input, Modal, ModalHeader, ModalBody, ModalFooter, FormGroup, Label } from 'reactstrap'; |
|
||||||
import { Button } from 'reactstrap'; |
|
||||||
import axios from 'axios'; |
|
||||||
import SweetAlert from 'react-bootstrap-sweetalert'; |
|
||||||
import DialogForm from './DialogForm'; |
|
||||||
import { NotificationContainer, NotificationManager} from 'react-notifications'; |
|
||||||
import { Pagination } from 'antd'; |
|
||||||
import { Icon, InlineIcon } from '@iconify/react'; |
|
||||||
import settingOutlined from '@iconify/icons-ant-design/setting-outlined'; |
|
||||||
import {Link} from 'react-router-dom' |
|
||||||
import Select from 'react-select' |
|
||||||
|
|
||||||
import { SketchPicker } from 'react-color'; |
|
||||||
|
|
||||||
|
|
||||||
const BASE_URL = "https://oslog.id/geohr-api/"; |
|
||||||
|
|
||||||
|
|
||||||
const column = [ |
|
||||||
{ name: "Group Sales" }, |
|
||||||
{ name: "Name" }, |
|
||||||
{ name: "Phone Number" }, |
|
||||||
{ name: "Email" }, |
|
||||||
{ name: "Address" }, |
|
||||||
] |
|
||||||
|
|
||||||
const layerSales = [ |
|
||||||
{ |
|
||||||
"id": 1, |
|
||||||
"rule_name": "sales yang incomenya lebih dari 1000000", |
|
||||||
"style": { |
|
||||||
"fill_color": "#22194D", |
|
||||||
}, |
|
||||||
"rule": { |
|
||||||
"column": "income", |
|
||||||
"operator": ">", |
|
||||||
"value": 1000000, |
|
||||||
} |
|
||||||
}, |
|
||||||
{ |
|
||||||
"id": 2, |
|
||||||
"rule_name": "sales yang punya nama mohammad", |
|
||||||
"style": { |
|
||||||
"fill_color": "#22194D", |
|
||||||
}, |
|
||||||
"rule": { |
|
||||||
"column": "name", |
|
||||||
"operator": "like", |
|
||||||
"value": "mohammad" |
|
||||||
} |
|
||||||
}, |
|
||||||
|
|
||||||
|
|
||||||
] |
|
||||||
|
|
||||||
const options = [ |
|
||||||
{ value: 'group-sales', label: 'Group Sales' }, |
|
||||||
{ value: 'name', label: 'Name' }, |
|
||||||
{ value: 'phone-number', label: 'Phone Number' }, |
|
||||||
{ value: 'email', label: 'Email' }, |
|
||||||
{ value: 'address', label: 'Address' } |
|
||||||
|
|
||||||
] |
|
||||||
|
|
||||||
const logicOperator = [ |
|
||||||
{ value: '>', label: '>' }, |
|
||||||
{ value: '>=', label: '>=' }, |
|
||||||
{ value: '<', label: '<' }, |
|
||||||
{ value: '<=', label: '<=' }, |
|
||||||
{ value: '==', label: '==' }, |
|
||||||
{ value: '<>', label: '<>' }, |
|
||||||
] |
|
||||||
|
|
||||||
|
|
||||||
const LENGTH_DATA = 10 |
|
||||||
export default class SettingSales extends Component { |
|
||||||
constructor(props) { |
|
||||||
super(props) |
|
||||||
this.state = { |
|
||||||
dataTable: [], |
|
||||||
openDialog: false, |
|
||||||
typeDialog: 'Save', |
|
||||||
dataEdit: null, |
|
||||||
alertDelete: false, |
|
||||||
idDelete: 0, |
|
||||||
dataGs: [], |
|
||||||
search: "", |
|
||||||
page: 0, |
|
||||||
rowsPerPage: LENGTH_DATA, |
|
||||||
currentPage: 1, |
|
||||||
totalPage: 0, |
|
||||||
layersSales: [], |
|
||||||
modalEdit: false, |
|
||||||
modalAdd: false, |
|
||||||
id: 0, |
|
||||||
fill_color: "#000", |
|
||||||
column: "", |
|
||||||
operator: "", |
|
||||||
value: "", |
|
||||||
dataEdit: null, |
|
||||||
|
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
async componentDidMount (){ |
|
||||||
this.getRuleSales() |
|
||||||
} |
|
||||||
|
|
||||||
async componentDidUpdate (prevProps, prevState){ |
|
||||||
const { search } = this.state |
|
||||||
if (search !== prevState.search) this.getRuleSales() |
|
||||||
} |
|
||||||
|
|
||||||
handleOpenDialog = (type) => { |
|
||||||
this.setState({modalEdit: true, typeDialog: type }) |
|
||||||
this.handleSetData() |
|
||||||
} |
|
||||||
|
|
||||||
handleSetData = () => { |
|
||||||
const { dataEdit, typeDialog} = this.state |
|
||||||
if(typeDialog === "Edit") { |
|
||||||
this.setState({ |
|
||||||
id: dataEdit.id, |
|
||||||
rule_name: dataEdit.rule_name, |
|
||||||
fill_color: dataEdit.style.fill_color, |
|
||||||
column: dataEdit.rule.column, |
|
||||||
value: dataEdit.rule.value, |
|
||||||
operator: dataEdit.rule.operator |
|
||||||
|
|
||||||
}) |
|
||||||
} else { |
|
||||||
this.setState({ |
|
||||||
id: 0, |
|
||||||
rule_name: "", |
|
||||||
fill_color: "#000", |
|
||||||
column: null, |
|
||||||
value:"", |
|
||||||
operator: null |
|
||||||
|
|
||||||
}) |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
handleEdit = (data) => { |
|
||||||
this.setState({dataEdit: data}) |
|
||||||
this.handleOpenDialog('Edit') |
|
||||||
console.log('test data edit', data) |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
handleCancel = () => { |
|
||||||
this.setState({ |
|
||||||
|
|
||||||
rule_name: "", |
|
||||||
fill_color: "#000", |
|
||||||
column: null, |
|
||||||
value:"", |
|
||||||
operator: null, |
|
||||||
modalEdit: false |
|
||||||
}) |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
handleSave = () => { |
|
||||||
this.setState({ |
|
||||||
|
|
||||||
rule_name: "", |
|
||||||
fill_color: "#000", |
|
||||||
column: null, |
|
||||||
value:"", |
|
||||||
operator: null, |
|
||||||
modalEdit: false }) |
|
||||||
|
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
toggleAdd = () => { |
|
||||||
this.setState({modalAdd: !this.state.modalAdd}) |
|
||||||
} |
|
||||||
|
|
||||||
getRuleSales = () => { |
|
||||||
this.setState({layersSales: layerSales}) |
|
||||||
} |
|
||||||
|
|
||||||
handleChangeComplete = (color, event) => { |
|
||||||
|
|
||||||
console.log('handleChangeComplete',color, event); |
|
||||||
this.setState({fill_color: color.hex}); |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
render() { |
|
||||||
const {layersSales, modalEdit, modalAdd, search, openDialog, currentPage, rowsPerPage,totalPage, dataTable } = this.state |
|
||||||
let noSeq = 0; |
|
||||||
return ( |
|
||||||
<div> |
|
||||||
<NotificationContainer/> |
|
||||||
<SweetAlert |
|
||||||
show={this.state.alertDelete} |
|
||||||
warning |
|
||||||
showCancel |
|
||||||
confirmBtnText="Delete" |
|
||||||
confirmBtnBsStyle="danger" |
|
||||||
title="Are you sure?" |
|
||||||
onConfirm={()=> this.setState({ alertDelete:false })} |
|
||||||
onCancel={()=> this.setState({ alertDelete:false })} |
|
||||||
focusCancelBtn |
|
||||||
> |
|
||||||
Rule sales akan terhapus!! |
|
||||||
</SweetAlert> |
|
||||||
|
|
||||||
<Card> |
|
||||||
<CardHeader style={{ display: "flex", justifyContent: "space-between" }}> |
|
||||||
<h4>Rules Sales</h4> |
|
||||||
<div> |
|
||||||
<Button onClick={this.handleOpenDialog} color="primary" >Add Rule</Button> |
|
||||||
</div> |
|
||||||
</CardHeader> |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<CardBody> |
|
||||||
{layersSales.map((n) => { |
|
||||||
return( |
|
||||||
<Row key={n.id}> |
|
||||||
<Col > |
|
||||||
|
|
||||||
<Card className="layer-list"> |
|
||||||
<CardBody> |
|
||||||
<Row> |
|
||||||
<Col xs={2}> |
|
||||||
<div style={{width: 20, height: 20, backgroundColor: n.style.fill_color }} /> |
|
||||||
</Col> |
|
||||||
|
|
||||||
<Col xs={8} > |
|
||||||
<span className="layer-title">{n.rule_name}</span> |
|
||||||
</Col> |
|
||||||
<Col > |
|
||||||
<div style={{ flexDirection: "row", justifyContent: "flex-end", }}> |
|
||||||
<Button onClick={()=> this.handleEdit(n)} color="success">Edit</Button> |
|
||||||
<Button onClick={()=> this.setState({alertDelete: true})} style={{ marginLeft: 16 }} color="danger">Hapus</Button> |
|
||||||
|
|
||||||
</div> |
|
||||||
|
|
||||||
</Col> |
|
||||||
|
|
||||||
</Row> |
|
||||||
</CardBody> |
|
||||||
</Card> |
|
||||||
|
|
||||||
</Col> |
|
||||||
|
|
||||||
</Row> |
|
||||||
|
|
||||||
|
|
||||||
) |
|
||||||
}) |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
</CardBody> |
|
||||||
</Card> |
|
||||||
<Modal isOpen={modalEdit} toggle={this.handleCancel} > |
|
||||||
<ModalHeader toggle={modalEdit}>Edit Rule Name</ModalHeader> |
|
||||||
<ModalBody> |
|
||||||
<div className="modal-body-container"> |
|
||||||
<FormGroup> |
|
||||||
<Label>Layer Name</Label> |
|
||||||
<Input value={this.state.rule_name} onChange={(e)=> this.setState({ rule_name :e.target.value })} /> |
|
||||||
</FormGroup> |
|
||||||
|
|
||||||
<FormGroup> |
|
||||||
<Label>Fill Color</Label> |
|
||||||
<SketchPicker |
|
||||||
color={ this.state.fill_color } |
|
||||||
onChangeComplete={ this.handleChangeColorComplete } |
|
||||||
/> |
|
||||||
</FormGroup> |
|
||||||
<FormGroup> |
|
||||||
<Label>Rule</Label> |
|
||||||
<Row> |
|
||||||
<Col > |
|
||||||
<Select value={this.state.column} options={options} /> |
|
||||||
</Col> |
|
||||||
<Col> |
|
||||||
<Select value={this.state.operator} options={logicOperator} /> |
|
||||||
|
|
||||||
</Col> |
|
||||||
<Col > |
|
||||||
<Input value={this.state.value} onChange={(e)=> this.setState({ value :e.target.value })} /> |
|
||||||
</Col> |
|
||||||
</Row> |
|
||||||
</FormGroup> |
|
||||||
</div> |
|
||||||
</ModalBody> |
|
||||||
<ModalFooter> |
|
||||||
<Button color="primary" onClick={this.handleSave}>Update</Button>{' '} |
|
||||||
<Button color="secondary" onClick={this.handleCancel}>Cancel</Button> |
|
||||||
</ModalFooter> |
|
||||||
</Modal> |
|
||||||
{/* <Modal isOpen={modalAdd} toggle={this.toggleAdd} > |
|
||||||
<ModalHeader toggle={modalEdit}>Add Rule Name</ModalHeader> |
|
||||||
<ModalBody> |
|
||||||
<div className="modal-body-container"> |
|
||||||
<FormGroup> |
|
||||||
<Label>Rule Name</Label> |
|
||||||
<Input /> |
|
||||||
</FormGroup> |
|
||||||
<FormGroup> |
|
||||||
<Label>Fill Color</Label> |
|
||||||
<SketchPicker /> |
|
||||||
</FormGroup> |
|
||||||
<FormGroup> |
|
||||||
<Label>Rule</Label> |
|
||||||
<Row> |
|
||||||
<Col> |
|
||||||
<Select options={options} /> |
|
||||||
</Col> |
|
||||||
<Col> |
|
||||||
<Select options={logicOperator} /> |
|
||||||
|
|
||||||
</Col> |
|
||||||
<Col xs={5}> |
|
||||||
<Input /> |
|
||||||
</Col> |
|
||||||
</Row> |
|
||||||
</FormGroup> |
|
||||||
</div> |
|
||||||
</ModalBody> |
|
||||||
<ModalFooter> |
|
||||||
<Button color="primary" onClick={this.toggleAdd}>Save</Button>{' '} |
|
||||||
<Button color="secondary" onClick={this.toggleAdd}>Cancel</Button> |
|
||||||
</ModalFooter> |
|
||||||
</Modal> */} |
|
||||||
|
|
||||||
</div> |
|
||||||
) |
|
||||||
} |
|
||||||
} |
|
@ -1,399 +0,0 @@ |
|||||||
import React, { Component } from 'react'; |
|
||||||
import { Card, CardBody, CardHeader, Col, Row, Table, Input, InputGroup, InputGroupButtonDropdown, DropdownToggle, DropdownItem, DropdownMenu } from 'reactstrap'; |
|
||||||
import { Button } from 'reactstrap'; |
|
||||||
import axios from 'axios'; |
|
||||||
import SweetAlert from 'react-bootstrap-sweetalert'; |
|
||||||
import DialogForm from './DialogForm'; |
|
||||||
import { NotificationContainer, NotificationManager } from 'react-notifications'; |
|
||||||
import { Pagination } from 'antd'; |
|
||||||
import { Icon, InlineIcon } from '@iconify/react'; |
|
||||||
import settingOutlined from '@iconify/icons-ant-design/setting-outlined'; |
|
||||||
import { Link } from 'react-router-dom'; |
|
||||||
import { Tooltip } from 'reactstrap'; |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const BASE_URL = "https://oslog.id/geohr-api/"; |
|
||||||
|
|
||||||
|
|
||||||
const column = [ |
|
||||||
{ name: "Group Sales" }, |
|
||||||
{ name: "Name" }, |
|
||||||
{ name: "Phone Number" }, |
|
||||||
{ name: "Email" }, |
|
||||||
{ name: "Address" }, |
|
||||||
] |
|
||||||
|
|
||||||
const LENGTH_DATA = 10 |
|
||||||
export default class index extends Component { |
|
||||||
constructor(props) { |
|
||||||
super(props) |
|
||||||
this.state = { |
|
||||||
dataTable: [], |
|
||||||
openDialog: false, |
|
||||||
typeDialog: 'Save', |
|
||||||
dataEdit: null, |
|
||||||
alertDelete: false, |
|
||||||
idDelete: 0, |
|
||||||
dataGs: [], |
|
||||||
search: "", |
|
||||||
page: 0, |
|
||||||
rowsPerPage: LENGTH_DATA, |
|
||||||
currentPage: 1, |
|
||||||
totalPage: 0, |
|
||||||
splitButtonOpen: false, |
|
||||||
dropdownOpen: false, |
|
||||||
searchDetail: "All", |
|
||||||
searchDetailField: "name", |
|
||||||
tooltipDelete: false, |
|
||||||
tooltipEdit: false |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
async componentDidMount() { |
|
||||||
this.getDataSales(); |
|
||||||
this.getDataGroupSales(); |
|
||||||
} |
|
||||||
|
|
||||||
async componentDidUpdate(prevProps, prevState) { |
|
||||||
const { search } = this.state |
|
||||||
if (search !== prevState.search) this.getDataSales() |
|
||||||
} |
|
||||||
|
|
||||||
getDataGroupSales = async () => { |
|
||||||
let url = BASE_URL + "group-sales/search"; |
|
||||||
const obj = { |
|
||||||
"paging": { "start": 0, "length": -1 }, |
|
||||||
"columns": [ |
|
||||||
{ |
|
||||||
"name": "name", |
|
||||||
"logic_operator": "ilike", |
|
||||||
"value": "", |
|
||||||
"operator": "and" |
|
||||||
} |
|
||||||
], |
|
||||||
"orders": { "columns": ["name"], "ascending": true } |
|
||||||
} |
|
||||||
|
|
||||||
const result = await axios |
|
||||||
.post(url, obj) |
|
||||||
.then(res => res) |
|
||||||
.catch((error) => error.response); |
|
||||||
if (result && result.data && result.data.message == "OK") { |
|
||||||
this.setState({ dataGs: result.data.data }); |
|
||||||
} else { |
|
||||||
NotificationManager.error('Failed retreiving data!!', 'Failed'); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
getDataSales = async () => { |
|
||||||
const { searchDetail, searchDetailField } = this.state |
|
||||||
let url = BASE_URL + "sales/search"; |
|
||||||
let start = 0 |
|
||||||
if (this.state.currentPage !== 1) { |
|
||||||
start = (this.state.currentPage * this.state.rowsPerPage) - this.state.rowsPerPage |
|
||||||
} |
|
||||||
const obj = { |
|
||||||
"paging": { "start": start, "length": this.state.rowsPerPage }, |
|
||||||
...searchDetail === "All" && |
|
||||||
{ |
|
||||||
"filter_columns": [ |
|
||||||
{ "name": "name", "value": this.state.search.toString() }, |
|
||||||
{ "name": "phone_number", "value": this.state.search.toString() }, |
|
||||||
{ "name": "email", "value": this.state.search.toString() }, |
|
||||||
{ "name": "address", "value": this.state.search.toString() }, |
|
||||||
{ "name": "name", "value": this.state.search.toString(), "table_name": "m_group_sales" }, |
|
||||||
], |
|
||||||
}, |
|
||||||
...searchDetail !== "All" && searchDetail !== "Group Sales" && |
|
||||||
{ |
|
||||||
"columns": [ |
|
||||||
{ "name": searchDetailField, "logic_operator": "ilike", "operator": "and", "value": this.state.search.toString() } |
|
||||||
] |
|
||||||
}, |
|
||||||
...searchDetail === "Group Sales" && |
|
||||||
{ |
|
||||||
"columns": [ |
|
||||||
{ "name": searchDetailField, "logic_operator": "ilike", "operator": "and", "value": this.state.search.toString(), "table_name": "m_group_sales" } |
|
||||||
] |
|
||||||
}, |
|
||||||
|
|
||||||
"joins": [ |
|
||||||
{ "name": "group_sales", "column_results": ["name", "description"] } |
|
||||||
], |
|
||||||
"orders": { "columns": ["name"], "ascending": true } |
|
||||||
} |
|
||||||
|
|
||||||
const result = await axios |
|
||||||
.post(url, obj) |
|
||||||
.then(res => res) |
|
||||||
.catch((error) => error.response); |
|
||||||
if (result && result.data && result.data.message == "OK") { |
|
||||||
this.setState({ dataTable: result.data.data, totalPage: result.data.totalRecord }); |
|
||||||
} else { |
|
||||||
NotificationManager.error('Failed retreiving data!!', 'Failed'); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
handleOpenDialog = (type) => { |
|
||||||
this.setState({ openDialog: true, typeDialog: type }) |
|
||||||
this.showChildDialog(); |
|
||||||
} |
|
||||||
|
|
||||||
handleCloseDialog = (type, data, files) => { |
|
||||||
if (type === "save") { |
|
||||||
this.saveSales(data, files); |
|
||||||
} else if (type === "edit") { |
|
||||||
this.editSales(data, files); |
|
||||||
this.uploadImage(files, data.id); |
|
||||||
} |
|
||||||
|
|
||||||
this.setState({ openDialog: false }) |
|
||||||
} |
|
||||||
|
|
||||||
toggleAddDialog = () => { |
|
||||||
this.setState({ openDialog: !this.state.openDialog }) |
|
||||||
} |
|
||||||
|
|
||||||
onConfirmDelete = async () => { |
|
||||||
const { idDelete } = this.state |
|
||||||
let url = BASE_URL + `sales/${idDelete}/delete`; |
|
||||||
const result = await axios.delete(url) |
|
||||||
.then(res => res) |
|
||||||
.catch((error) => error.response); |
|
||||||
if (result && result.data && result.data.message === "OK") { |
|
||||||
this.getDataSales() |
|
||||||
this.setState({ idDelete: 0, alertDelete: false }) |
|
||||||
NotificationManager.success('Data group sales berhasil dihapus!!', 'Success!!'); |
|
||||||
} else { |
|
||||||
this.setState({ idDelete: 0, alertDelete: false }) |
|
||||||
NotificationManager.error('Data group sales galal dihapus!!', 'Failed!!'); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
saveSales = async (obj, files) => { |
|
||||||
let url = BASE_URL + "sales/add"; |
|
||||||
let data = JSON.stringify(obj); |
|
||||||
const result = await axios.post(url, data) |
|
||||||
.then(res => res) |
|
||||||
.catch((error) => error.response); |
|
||||||
if (result && result.data && result.data.message === "OK") { |
|
||||||
let ref_id = parseInt(result.data.data.id); |
|
||||||
this.uploadImage(files, ref_id); |
|
||||||
NotificationManager.success('Data sales berhasil ditambahkan!!', 'Success!!'); |
|
||||||
} else { |
|
||||||
NotificationManager.error(`${result.data.message}`, 'Failed!!'); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
editSales = async (data) => { |
|
||||||
let url = BASE_URL + `sales/${data.id}/edit`; |
|
||||||
const obj = JSON.stringify(data); |
|
||||||
const result = await axios.put(url, obj) |
|
||||||
.then(res => res) |
|
||||||
.catch((error) => error.response); |
|
||||||
if (result && result.data && result.data.message === "OK") { |
|
||||||
this.getDataSales(); |
|
||||||
NotificationManager.success('Data sales berhasil diedit!!', 'Success!!'); |
|
||||||
} else { |
|
||||||
NotificationManager.error('Data sales galal diedit!!', 'Failed!!'); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
uploadImage = async (files, idRef) => { |
|
||||||
if (files.length > 0) { |
|
||||||
let promises = []; |
|
||||||
let response = []; |
|
||||||
let url = BASE_URL + `image/m_sales/upload`; |
|
||||||
files.map((val, index) => { |
|
||||||
let formData = new FormData(); |
|
||||||
formData.append("ref_id", idRef); |
|
||||||
formData.append("files", val[0]); |
|
||||||
promises.push(axios.post(url, formData) |
|
||||||
.then(res => { response.push(res) })) |
|
||||||
}) |
|
||||||
await Promise.all(promises); |
|
||||||
} |
|
||||||
|
|
||||||
this.getDataSales() |
|
||||||
} |
|
||||||
|
|
||||||
handleEdit = (data) => { |
|
||||||
this.setState({ dataEdit: data }); |
|
||||||
this.handleOpenDialog('Edit'); |
|
||||||
} |
|
||||||
|
|
||||||
handleDelete = (id) => { |
|
||||||
this.setState({ alertDelete: true, idDelete: id }); |
|
||||||
} |
|
||||||
|
|
||||||
onShowSizeChange = (current, pageSize) => { |
|
||||||
this.setState({ rowsPerPage: pageSize }, () => { |
|
||||||
this.getDataSales(); |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
onPagination = (current, pageSize) => { |
|
||||||
this.setState({ currentPage: current, page: (current - 1) * pageSize }, () => { |
|
||||||
this.getDataSales(); |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
handleSearch = e => { |
|
||||||
const value = e.target.value |
|
||||||
this.setState({ search: value, currentPage: 1 }) |
|
||||||
}; |
|
||||||
|
|
||||||
toggleDropDown = () => { |
|
||||||
this.setState(prevState => ({ splitButtonOpen: !prevState.splitButtonOpen })) |
|
||||||
} |
|
||||||
|
|
||||||
toggle = (param) => { |
|
||||||
if (param === "edit") { |
|
||||||
this.setState(prevState => ({ tooltipEdit: !prevState.tooltipEdit })) |
|
||||||
} else if (param === "delete") { |
|
||||||
this.setState(prevState => ({ tooltipDelete: !prevState.tooltipDelete })) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
render() { |
|
||||||
const { search, openDialog, currentPage, rowsPerPage, totalPage, dataTable, splitButtonOpen, searchDetail, tooltipDelete, tooltipEdit } = this.state |
|
||||||
let noSeq = 0; |
|
||||||
return ( |
|
||||||
<div> |
|
||||||
<NotificationContainer /> |
|
||||||
<SweetAlert |
|
||||||
show={this.state.alertDelete} |
|
||||||
warning |
|
||||||
showCancel |
|
||||||
confirmBtnText="Delete" |
|
||||||
confirmBtnBsStyle="danger" |
|
||||||
title="Are you sure?" |
|
||||||
onConfirm={this.onConfirmDelete} |
|
||||||
onCancel={() => this.setState({ alertDelete: false, idDelete: 0 })} |
|
||||||
focusCancelBtn |
|
||||||
> |
|
||||||
Data group sales akan terhapus!! |
|
||||||
</SweetAlert> |
|
||||||
<DialogForm |
|
||||||
openDialog={openDialog} |
|
||||||
closeDialog={this.handleCloseDialog} |
|
||||||
toggleDialog={() => this.toggleAddDialog} |
|
||||||
typeDialog={this.state.typeDialog} |
|
||||||
dataEdit={this.state.dataEdit} |
|
||||||
showDialog={showDialog => this.showChildDialog = showDialog} |
|
||||||
dataGs={this.state.dataGs} |
|
||||||
/> |
|
||||||
<Card> |
|
||||||
<CardHeader style={{ display: "flex", justifyContent: "space-between" }}> |
|
||||||
<h4>Sales</h4> |
|
||||||
<div> |
|
||||||
<Button color="primary" onClick={() => this.handleOpenDialog('Save')}>Add Sales</Button> |
|
||||||
<Link style={{ marginLeft: 16 }} to="/sales/setting-sales"> |
|
||||||
<Icon width={35} height={35} icon={settingOutlined} /> |
|
||||||
</Link> |
|
||||||
|
|
||||||
</div> |
|
||||||
</CardHeader> |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<CardBody> |
|
||||||
<InputGroup style={{ maxWidth: "200px", marginBottom: "20px" }}> |
|
||||||
<Input onChange={this.handleSearch} value={search} type="text" name="search" id="search" placeholder={`Search ${searchDetail}`} /> |
|
||||||
<InputGroupButtonDropdown addonType="prepend" |
|
||||||
isOpen={splitButtonOpen} |
|
||||||
toggle={this.toggleDropDown} |
|
||||||
> |
|
||||||
<DropdownToggle split outline /> |
|
||||||
<DropdownMenu> |
|
||||||
<DropdownItem onClick={ |
|
||||||
() => this.setState({ |
|
||||||
searchDetail: "All", |
|
||||||
searchDetailField: "name" |
|
||||||
})}>All</DropdownItem> |
|
||||||
<DropdownItem onClick={ |
|
||||||
() => this.setState({ |
|
||||||
searchDetail: "Name", |
|
||||||
searchDetailField: "name" |
|
||||||
})}>Name</DropdownItem> |
|
||||||
<DropdownItem onClick={ |
|
||||||
() => this.setState({ |
|
||||||
searchDetail: "Group Sales", |
|
||||||
searchDetailField: "name" |
|
||||||
})}>Group Sales</DropdownItem> |
|
||||||
<DropdownItem onClick={ |
|
||||||
() => this.setState({ |
|
||||||
searchDetail: "Phone Number", |
|
||||||
searchDetailField: "phone_number" |
|
||||||
})}>Phone Number</DropdownItem> |
|
||||||
<DropdownItem onClick={ |
|
||||||
() => this.setState({ |
|
||||||
searchDetail: "Email", |
|
||||||
searchDetailField: "email" |
|
||||||
})}>Email</DropdownItem> |
|
||||||
<DropdownItem onClick={ |
|
||||||
() => this.setState({ |
|
||||||
searchDetail: "Address", |
|
||||||
searchDetailField: "address" |
|
||||||
})}>Address</DropdownItem> |
|
||||||
</DropdownMenu> |
|
||||||
</InputGroupButtonDropdown> |
|
||||||
</InputGroup> |
|
||||||
<Table responsive striped hover> |
|
||||||
<thead> |
|
||||||
<tr> |
|
||||||
<th>Actions</th> |
|
||||||
{column.map((i, index) => { |
|
||||||
return ( |
|
||||||
<th key={index} scope="row">{i.name}</th> |
|
||||||
) |
|
||||||
})} |
|
||||||
</tr> |
|
||||||
</thead> |
|
||||||
<tbody> |
|
||||||
{dataTable.map((n) => { |
|
||||||
return ( |
|
||||||
<tr key={n.id}> |
|
||||||
<td> |
|
||||||
{/* delete */} |
|
||||||
<i id="TooltipDelete" className="cil-trash fa-lg" style={{ color: 'red', marginRight: '10px', cursor: "pointer" }} onClick={() => this.handleDelete(n.id)}></i> |
|
||||||
<Tooltip placement="right" isOpen={tooltipDelete} target="TooltipDelete" toggle={() => this.toggle("delete")}> |
|
||||||
Delete |
|
||||||
</Tooltip> |
|
||||||
|
|
||||||
{/* edit */} |
|
||||||
<i id="TooltipEdit" className="cil-pencil fa-lg" style={{ color: 'green', cursor: "pointer" }} onClick={() => this.handleEdit(n)}></i> |
|
||||||
<Tooltip placement="right" isOpen={tooltipEdit} target="TooltipEdit" toggle={() => this.toggle("edit")}> |
|
||||||
Edit |
|
||||||
</Tooltip> |
|
||||||
</td> |
|
||||||
<td>{n.join.group_sales_name}</td> |
|
||||||
<td>{n.name}</td> |
|
||||||
<td>{n.phone_number}</td> |
|
||||||
<td>{n.email}</td> |
|
||||||
<td>{n.address}</td> |
|
||||||
</tr> |
|
||||||
) |
|
||||||
})} |
|
||||||
</tbody> |
|
||||||
</Table> |
|
||||||
<Pagination |
|
||||||
showSizeChanger |
|
||||||
onShowSizeChange={this.onShowSizeChange} |
|
||||||
onChange={this.onPagination} |
|
||||||
defaultCurrent={currentPage} |
|
||||||
pageSize={rowsPerPage} |
|
||||||
total={totalPage} |
|
||||||
pageSizeOptions={["10", "15", "20", "25", "30", "35", "40"]} |
|
||||||
/> |
|
||||||
</CardBody> |
|
||||||
</Card> |
|
||||||
</div> |
|
||||||
) |
|
||||||
} |
|
||||||
} |
|
@ -1,50 +0,0 @@ |
|||||||
import React, { Component } from 'react' |
|
||||||
import DataTable from '../../../components/DataTable' |
|
||||||
import { API_LIST_DATA_SUBDISTRICT, API_INSERT_DATA_SUBDISTRICT, API_UPDATE_DATA_SUBDISTRICT, API_DELETE_DATA_SUBDISTRICT } from '../../../const/ApiConst.js' |
|
||||||
|
|
||||||
const columns = [{ |
|
||||||
dataField: 'id', |
|
||||||
alias: "Id", |
|
||||||
showInput: false, |
|
||||||
type: "number", |
|
||||||
state: 0 |
|
||||||
}, { |
|
||||||
dataField: 'subdistrict_name', |
|
||||||
alias: "Subdistrict Name", |
|
||||||
showInput: true, |
|
||||||
type: "text", |
|
||||||
state: "" |
|
||||||
}, { |
|
||||||
dataField: 'last_updated', |
|
||||||
alias: "Last Updated", |
|
||||||
showInput: false, |
|
||||||
type: "text", |
|
||||||
state: "" |
|
||||||
}]; |
|
||||||
|
|
||||||
class MasterSubdistrict extends Component { |
|
||||||
constructor(props) { |
|
||||||
super(props) |
|
||||||
this.state = {} |
|
||||||
} |
|
||||||
|
|
||||||
componentDidMount() {} |
|
||||||
|
|
||||||
render() { |
|
||||||
|
|
||||||
return ( |
|
||||||
<div> |
|
||||||
<DataTable |
|
||||||
title="Subdistrict" |
|
||||||
columns={columns} |
|
||||||
urlParamGet={API_LIST_DATA_SUBDISTRICT} |
|
||||||
urlParamInsert={API_INSERT_DATA_SUBDISTRICT} |
|
||||||
urlParamUpdate={API_UPDATE_DATA_SUBDISTRICT} |
|
||||||
urlParamDelete={API_DELETE_DATA_SUBDISTRICT} |
|
||||||
/> |
|
||||||
</div> |
|
||||||
) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
export default MasterSubdistrict; |
|
@ -1,6 +0,0 @@ |
|||||||
{ |
|
||||||
"name": "MasterSubdistrict", |
|
||||||
"version": "0.0.0", |
|
||||||
"private": true, |
|
||||||
"main": "./MasterSubdistrict.js" |
|
||||||
} |
|
@ -1,50 +0,0 @@ |
|||||||
import React, { Component } from 'react' |
|
||||||
import DataTable from '../../../components/DataTable' |
|
||||||
import { API_LIST_DATA_VILLAGE, API_INSERT_DATA_VILLAGE, API_UPDATE_DATA_VILLAGE, API_DELETE_DATA_VILLAGE } from '../../../const/ApiConst.js' |
|
||||||
|
|
||||||
const columns = [{ |
|
||||||
dataField: 'id', |
|
||||||
alias: "Id", |
|
||||||
showInput: false, |
|
||||||
type: "number", |
|
||||||
state: 0 |
|
||||||
}, { |
|
||||||
dataField: 'village_name', |
|
||||||
alias: "Village Name", |
|
||||||
showInput: true, |
|
||||||
type: "text", |
|
||||||
state: "" |
|
||||||
}, { |
|
||||||
dataField: 'last_updated', |
|
||||||
alias: "Last Updated", |
|
||||||
showInput: false, |
|
||||||
type: "text", |
|
||||||
state: "" |
|
||||||
}]; |
|
||||||
|
|
||||||
class MasterVillage extends Component { |
|
||||||
constructor(props) { |
|
||||||
super(props) |
|
||||||
this.state = {} |
|
||||||
} |
|
||||||
|
|
||||||
componentDidMount() {} |
|
||||||
|
|
||||||
render() { |
|
||||||
|
|
||||||
return ( |
|
||||||
<div> |
|
||||||
<DataTable |
|
||||||
title="VILLAGE" |
|
||||||
columns={columns} |
|
||||||
urlParamGet={API_LIST_DATA_VILLAGE} |
|
||||||
urlParamInsert={API_INSERT_DATA_VILLAGE} |
|
||||||
urlParamUpdate={API_UPDATE_DATA_VILLAGE} |
|
||||||
urlParamDelete={API_DELETE_DATA_VILLAGE} |
|
||||||
/> |
|
||||||
</div> |
|
||||||
) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
export default MasterVillage; |
|
@ -1,6 +0,0 @@ |
|||||||
{ |
|
||||||
"name": "MasterVillage", |
|
||||||
"version": "0.0.0", |
|
||||||
"private": true, |
|
||||||
"main": "./MasterVillage.js" |
|
||||||
} |
|
@ -1,106 +0,0 @@ |
|||||||
import React, { Component } from 'react' |
|
||||||
import { Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap'; |
|
||||||
import { Col, Row, Button, Form, FormGroup, Label, Input } from 'reactstrap'; |
|
||||||
import Select from 'react-select' |
|
||||||
import axios from 'axios'; |
|
||||||
import moment from 'moment'; |
|
||||||
import { TimePicker } from 'antd'; |
|
||||||
import 'antd/dist/antd.css'; |
|
||||||
|
|
||||||
export default class DialogForm extends Component { |
|
||||||
constructor(props) { |
|
||||||
super(props) |
|
||||||
this.state = { |
|
||||||
id: 0, |
|
||||||
lat:"", |
|
||||||
lon:"", |
|
||||||
status:"", |
|
||||||
name:"", |
|
||||||
openDialog: false, |
|
||||||
isParentClick: false, |
|
||||||
disable: false |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
async componentDidMount(){ |
|
||||||
this.props.showDialog(this.showDialog); |
|
||||||
} |
|
||||||
|
|
||||||
async componentDidUpdate (){ |
|
||||||
if(this.state.isParentClick===true){ |
|
||||||
const { dataEdit } = this.props |
|
||||||
console.log("cek", dataEdit); |
|
||||||
this.setState({
|
|
||||||
id:dataEdit.id, |
|
||||||
lat:dataEdit.lat, |
|
||||||
lon:dataEdit.lon, |
|
||||||
status:dataEdit.status_response, |
|
||||||
name:dataEdit.employee_name |
|
||||||
}) |
|
||||||
|
|
||||||
this.setState({isParentClick:false}); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
showDialog = () => { |
|
||||||
this.setState({ isParentClick : true }); |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
handleSave = () => { |
|
||||||
const {
|
|
||||||
lat, |
|
||||||
lon, |
|
||||||
status, |
|
||||||
id |
|
||||||
} = this.state |
|
||||||
|
|
||||||
let data = { |
|
||||||
lat, |
|
||||||
lon, |
|
||||||
status_response:status, |
|
||||||
id |
|
||||||
} |
|
||||||
this.props.closeDialog('save', data); |
|
||||||
this.setState({ id:0,lat:"",lon:"",status:'active' }); |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
handleCancel = () => { |
|
||||||
this.props.closeDialog('cancel', 'none') |
|
||||||
} |
|
||||||
|
|
||||||
renderForm = () => { |
|
||||||
return( |
|
||||||
<Form> |
|
||||||
<FormGroup> |
|
||||||
<Label>Name</Label> |
|
||||||
<Input type="text" value={this.state.name} readOnly /> |
|
||||||
</FormGroup> |
|
||||||
<FormGroup> |
|
||||||
<Label>Status Approval</Label> |
|
||||||
<Input type="select" disabled={this.state.disable} value={this.state.status} onChange={(e)=>this.setState({ status:e.target.value })}> |
|
||||||
<option value="active">Active</option> |
|
||||||
<option value="non active">Non Active</option> |
|
||||||
</Input> |
|
||||||
</FormGroup> |
|
||||||
</Form> |
|
||||||
) |
|
||||||
} |
|
||||||
|
|
||||||
render() { |
|
||||||
return ( |
|
||||||
<Modal isOpen={this.props.openDialog} toggle={this.props.toggleDialog}> |
|
||||||
<ModalHeader toggle={this.props.closeDialog}>Edit Status Response</ModalHeader> |
|
||||||
<ModalBody> |
|
||||||
{this.renderForm()} |
|
||||||
</ModalBody> |
|
||||||
<ModalFooter> |
|
||||||
<Button color="primary" onClick={() => this.handleSave()}>Save</Button>{' '} |
|
||||||
<Button color="secondary" onClick={() => this.handleCancel()}>Cancel</Button> |
|
||||||
</ModalFooter> |
|
||||||
</Modal> |
|
||||||
) |
|
||||||
} |
|
||||||
} |
|
@ -1,85 +0,0 @@ |
|||||||
import React, { Component } from 'react' |
|
||||||
import { Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap'; |
|
||||||
import { Col, Row, Button, Form, FormGroup, Label, Input } from 'reactstrap'; |
|
||||||
import Map from './Map' |
|
||||||
import 'antd/dist/antd.css'; |
|
||||||
|
|
||||||
const ERROR_LATLON = "Geom cannot be empty" |
|
||||||
const ERROR_COMPANY = "Company cannot be empty" |
|
||||||
const ERROR_NAME = "name cannot be empty" |
|
||||||
const ERROR_RADIUS = "Buffer Radius cannot be empty" |
|
||||||
|
|
||||||
export default class DialogForm extends Component { |
|
||||||
constructor(props) { |
|
||||||
super(props) |
|
||||||
this.state = { |
|
||||||
id: 0, |
|
||||||
lat:0, |
|
||||||
lon:0, |
|
||||||
openDialog: false, |
|
||||||
isParentClick: false, |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
async componentDidMount(){ |
|
||||||
this.props.showDialog(this.showDialog); |
|
||||||
} |
|
||||||
|
|
||||||
async componentDidUpdate (){ |
|
||||||
if(this.state.isParentClick===true){ |
|
||||||
const { dataMap } = this.props |
|
||||||
this.setState({
|
|
||||||
lat:dataMap.lat, |
|
||||||
lon:dataMap.lon |
|
||||||
}) |
|
||||||
this.setState({isParentClick:false}); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
showDialog = () => { |
|
||||||
this.setState({ isParentClick : true }); |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
handleSave = () => { |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
handleCancel = () => { |
|
||||||
this.props.closeDialog('cancel', 'none') |
|
||||||
} |
|
||||||
|
|
||||||
getLocation = (param) => { |
|
||||||
console.log(`getLocation`, param) |
|
||||||
this.setState({ |
|
||||||
latlonMessage: param != "" ? "" : ERROR_LATLON, |
|
||||||
lat: param.lat, |
|
||||||
lon: param.lng, |
|
||||||
latlon: `lat:${param.lat} lng:${param.lng}` |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
renderForm = () => { |
|
||||||
return( |
|
||||||
<div style={{ width: '100%', minHeight: '100px' }}> |
|
||||||
<Map method={'View'} getLocation={this.getLocation} lat={this.state.lat} lng={this.state.lon} /> |
|
||||||
</div> |
|
||||||
) |
|
||||||
} |
|
||||||
|
|
||||||
render() { |
|
||||||
return ( |
|
||||||
<Modal isOpen={this.props.openDialog} toggle={this.props.toggleDialog}> |
|
||||||
<ModalHeader toggle={this.props.closeDialog}>Map</ModalHeader> |
|
||||||
<ModalBody> |
|
||||||
{this.renderForm()} |
|
||||||
</ModalBody> |
|
||||||
<ModalFooter> |
|
||||||
{/* <Button color="primary" onClick={() => this.handleSave()}>{this.props.typeDialog}</Button>{' '} */} |
|
||||||
<Button color="secondary" onClick={() => this.handleCancel()}>Close</Button> |
|
||||||
</ModalFooter> |
|
||||||
</Modal> |
|
||||||
) |
|
||||||
} |
|
||||||
} |
|
@ -1,104 +0,0 @@ |
|||||||
import React, { useEffect, useMemo, useState } from 'react' |
|
||||||
import { Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap'; |
|
||||||
import { Button, Form, FormGroup, Label, Input, Col, Row } from 'reactstrap'; |
|
||||||
import { Select, Table } from 'antd' |
|
||||||
import { BASE_SIMPRO } from '../../../const/ApiConst'; |
|
||||||
import { NotificationContainer, NotificationManager } from 'react-notifications'; |
|
||||||
import 'antd/dist/antd.css'; |
|
||||||
import axios from 'axios'; |
|
||||||
import moment from 'moment'; |
|
||||||
|
|
||||||
const { Option } = Select |
|
||||||
|
|
||||||
const DialogView = ({ openDialog, closeDialog, toggleDialog, dataPlanning, nameProyekParent }) => { |
|
||||||
const token = localStorage.getItem("token") |
|
||||||
const HEADER = { |
|
||||||
headers: { |
|
||||||
"Content-Type": "application/json", |
|
||||||
"Authorization": `Bearer ${token}` |
|
||||||
} |
|
||||||
} |
|
||||||
const [dataPlan, setDataPlan] = useState([]); |
|
||||||
|
|
||||||
useEffect(() => { |
|
||||||
setDataPlan(dataPlanning) |
|
||||||
}, [dataPlanning]); |
|
||||||
|
|
||||||
|
|
||||||
const RenderTableLaporanPlan = (tableData) => { |
|
||||||
const columns = [ |
|
||||||
{ |
|
||||||
title: 'Tanggal', |
|
||||||
dataIndex: 'tanggal', |
|
||||||
key: 'tanggal', |
|
||||||
render: (text, record) => <>{moment(text.tanggal).format("YYYY-MM-DD")}</>, |
|
||||||
}, |
|
||||||
{ title: 'Jumlah Pekerja', dataIndex: 'jumlah_pekerjaan', key: 'jumlah_pekerjaan' }, |
|
||||||
{ title: 'Status', dataIndex: 'status', key: 'status' }, |
|
||||||
{ title: 'deskripsi', dataIndex: 'deskripsi', key: 'deskripsi' }, |
|
||||||
]; |
|
||||||
|
|
||||||
return ( |
|
||||||
<Table |
|
||||||
size="small" |
|
||||||
columns={columns} |
|
||||||
dataSource={tableData} |
|
||||||
/> |
|
||||||
) |
|
||||||
} |
|
||||||
|
|
||||||
const RenderTablePlan = useMemo(() => { |
|
||||||
let idx = 0 |
|
||||||
const columns = [ |
|
||||||
{
|
|
||||||
title: 'No',
|
|
||||||
dataIndex: 'no',
|
|
||||||
key: 'id',
|
|
||||||
render: (text, record) => <>{idx+1}</>, |
|
||||||
}, |
|
||||||
|
|
||||||
{ |
|
||||||
title: 'Waspang', |
|
||||||
dataIndex: 'created_by', |
|
||||||
key: 'created_by', |
|
||||||
render: (text, record) => <>{record.created_by}</>, |
|
||||||
}, |
|
||||||
{ title: 'Jumlah Pekerjaan', dataIndex: 'jumlah_pekerjaan', key: 'jumlah_pekerjaan' }, |
|
||||||
{ |
|
||||||
title: 'Deskripsi', |
|
||||||
dataIndex: 'deskripsi', |
|
||||||
key: 'deskripsi', |
|
||||||
render: (text, record) => <>{record.deskripsi}</>, |
|
||||||
}, |
|
||||||
]; |
|
||||||
|
|
||||||
return ( |
|
||||||
<Table |
|
||||||
size="small" |
|
||||||
columns={columns} |
|
||||||
expandable={{ |
|
||||||
expandedRowRender: record => RenderTableLaporanPlan(record.realisasi), |
|
||||||
rowExpandable: record => record.realisasi, |
|
||||||
}} |
|
||||||
dataSource={dataPlan} |
|
||||||
/> |
|
||||||
) |
|
||||||
}, [dataPlan]) |
|
||||||
|
|
||||||
|
|
||||||
return ( |
|
||||||
<Modal size="xl" isOpen={openDialog} toggle={toggleDialog}> |
|
||||||
<ModalHeader className="capitalize" toggle={closeDialog}>View Realisasi</ModalHeader> |
|
||||||
<ModalBody> |
|
||||||
{RenderTablePlan} |
|
||||||
</ModalBody> |
|
||||||
<ModalFooter> |
|
||||||
{/* <Button color="primary" onClick={() => handleSave()}>{typeDialog}</Button>{' '} */} |
|
||||||
<Button className="capitalize" color="secondary" onClick={closeDialog}>Close</Button> |
|
||||||
</ModalFooter> |
|
||||||
</Modal> |
|
||||||
) |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
export default DialogView; |
|
@ -1,83 +0,0 @@ |
|||||||
import React, { useState, useRef, useMemo, useCallback, useEffect } from 'react' |
|
||||||
import { MapContainer, TileLayer, Marker, Popup, Polygon } from 'react-leaflet' |
|
||||||
|
|
||||||
const center = { |
|
||||||
lat: -6.200000, |
|
||||||
lng: 106.816666 |
|
||||||
} |
|
||||||
|
|
||||||
const DraggableMarker = (props) => { |
|
||||||
const { method } = props |
|
||||||
let lat = props.lat |
|
||||||
let lng = props.lng |
|
||||||
const currentPos = [lat, lng] |
|
||||||
console.log(`currentPos`, currentPos) |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const [draggable, setDraggable] = useState(true) |
|
||||||
const [position, setPosition] = useState(center) |
|
||||||
|
|
||||||
|
|
||||||
const markerRef = useRef(null) |
|
||||||
const eventHandlers = useMemo( |
|
||||||
() => ({ |
|
||||||
dragend() { |
|
||||||
const marker = markerRef.current |
|
||||||
if (marker != null) { |
|
||||||
setPosition(marker.getLatLng()) |
|
||||||
props.getLocation(marker.getLatLng()) |
|
||||||
} |
|
||||||
}, |
|
||||||
}), |
|
||||||
[], |
|
||||||
) |
|
||||||
return ( |
|
||||||
<> |
|
||||||
|
|
||||||
{method === "View" && ( |
|
||||||
<Marker |
|
||||||
eventHandlers={eventHandlers} |
|
||||||
position={currentPos} |
|
||||||
ref={markerRef}> |
|
||||||
</Marker> |
|
||||||
)} |
|
||||||
|
|
||||||
{method === "Edit" && ( |
|
||||||
<Marker |
|
||||||
draggable={draggable} |
|
||||||
eventHandlers={eventHandlers} |
|
||||||
position={currentPos ? currentPos : position} |
|
||||||
ref={markerRef}> |
|
||||||
</Marker> |
|
||||||
)} |
|
||||||
{method === "Save" && ( |
|
||||||
<Marker |
|
||||||
draggable={draggable} |
|
||||||
eventHandlers={eventHandlers} |
|
||||||
position={position} |
|
||||||
ref={markerRef}> |
|
||||||
</Marker> |
|
||||||
)} |
|
||||||
</> |
|
||||||
) |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
const purpleOptions = { color: 'purple' } |
|
||||||
const RenderMap = (props) => { |
|
||||||
let lat = props.lat |
|
||||||
let lng = props.lng |
|
||||||
const currentPos = (lat !== "" && lng !== "") ? [lat, lng] : center |
|
||||||
return ( |
|
||||||
<MapContainer center={currentPos} zoom={13} scrollWheelZoom={false} style={{ height: '70vh' }}> |
|
||||||
{/* <Polygon pathOptions={purpleOptions} positions={polygon} /> */} |
|
||||||
<TileLayer |
|
||||||
attribution='© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors' |
|
||||||
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" |
|
||||||
/> |
|
||||||
<DraggableMarker {...props} /> |
|
||||||
</MapContainer> |
|
||||||
) |
|
||||||
} |
|
||||||
export default RenderMap; |
|
@ -1,608 +0,0 @@ |
|||||||
import React, { Component } from 'react'; |
|
||||||
import { Card, CardBody, CardHeader, Col, Row, Table, Input, InputGroup } from 'reactstrap'; |
|
||||||
import { Button } from 'reactstrap'; |
|
||||||
import axios from 'axios'; |
|
||||||
import moment from 'moment'; |
|
||||||
import SweetAlert from 'react-bootstrap-sweetalert'; |
|
||||||
import DialogForm from './DialogForm'; |
|
||||||
import DialogEdit from './DialogEdit'; |
|
||||||
import { NotificationContainer, NotificationManager } from 'react-notifications'; |
|
||||||
import { Pagination, Tooltip } from 'antd'; |
|
||||||
import { DatePicker } from 'antd'; |
|
||||||
import * as XLSX from 'xlsx'; |
|
||||||
import { PLANNING_REALISASI_SEARCH, PLANNING_SEARCH } from '../../../const/ApiConst.js'; |
|
||||||
import DialogView from './DialogView'; |
|
||||||
|
|
||||||
|
|
||||||
const { RangePicker } = DatePicker; |
|
||||||
|
|
||||||
const token = window.localStorage.getItem('token'); |
|
||||||
const config = { |
|
||||||
headers:
|
|
||||||
{
|
|
||||||
Authorization : `Bearer ${token}`, |
|
||||||
"Content-type" : `application/json` |
|
||||||
} |
|
||||||
}; |
|
||||||
|
|
||||||
const proyek_id = localStorage.getItem('proyek_id'); |
|
||||||
const role_id = localStorage.getItem('role_id'); |
|
||||||
|
|
||||||
const column = [ |
|
||||||
{ name: "No" }, |
|
||||||
{ name: "Proyek" }, |
|
||||||
{ name: "Pekerjaan" }, |
|
||||||
{ name: "Target" }, |
|
||||||
{ name: "Actual" }, |
|
||||||
{ name: "Team Leader" }, |
|
||||||
{ name: "Waspang" }, |
|
||||||
{ name: "Tanggal" }, |
|
||||||
{ name: "Lihat" }, |
|
||||||
] |
|
||||||
|
|
||||||
const LENGTH_DATA = 10 |
|
||||||
|
|
||||||
export default class index extends Component { |
|
||||||
constructor(props) { |
|
||||||
super(props) |
|
||||||
this.state = { |
|
||||||
dataTable: [], |
|
||||||
dataExport: [], |
|
||||||
openDialog: false, |
|
||||||
openDialogEdit:false, |
|
||||||
typeDialog: 'Save', |
|
||||||
dataEdit: null, |
|
||||||
alertDelete: false, |
|
||||||
idDelete: 0, |
|
||||||
dataGs: [], |
|
||||||
dataIdHo: [], |
|
||||||
search: "", |
|
||||||
page: 0, |
|
||||||
rowsPerPage: LENGTH_DATA, |
|
||||||
currentPage: 1, |
|
||||||
totalPage: 0, |
|
||||||
tooltipMap: false, |
|
||||||
tooltipDelete: false, |
|
||||||
typeClock: "All", |
|
||||||
startDate:moment(moment().format("YYYY-M-D")), |
|
||||||
endDate:moment(moment().format("YYYY-M-D")), |
|
||||||
currentDay: 'today', |
|
||||||
dataMap:"", |
|
||||||
tooltipExport:false, |
|
||||||
openDialogPlan: false, |
|
||||||
dataRealisasi: [] |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
async componentDidMount() { |
|
||||||
this.getDataReportPlanning(); |
|
||||||
} |
|
||||||
|
|
||||||
async componentDidUpdate(prevProps, prevState) { |
|
||||||
const { search,startDate,dataExport } = this.state |
|
||||||
if (search !== prevState.search) this.getDataReportPlanning() |
|
||||||
if (startDate !== prevState.startDate) this.getDataReportPlanning() |
|
||||||
if (dataExport !== prevState.dataExport){ |
|
||||||
if(dataExport.length > 0){ |
|
||||||
this.exportExcel() |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
handleSearch = e => { |
|
||||||
const value = e.target.value |
|
||||||
this.setState({ search: value, currentPage: 1 }) |
|
||||||
}; |
|
||||||
|
|
||||||
getDataReportPlanning = async () => { |
|
||||||
let start = 0; |
|
||||||
if (this.state.currentPage !== 1 && this.state.currentPage > 1) { |
|
||||||
start = (this.state.currentPage * this.state.rowsPerPage) - this.state.rowsPerPage |
|
||||||
} |
|
||||||
|
|
||||||
let dateStart = moment(this.state.startDate).format("YYYY-MM-DD 00:00:00"); |
|
||||||
let dateEnd = moment(this.state.endDate).format("YYYY-MM-DD 23:59:59"); |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const formData = { |
|
||||||
"columns": [ |
|
||||||
{ |
|
||||||
"name": "created_at", |
|
||||||
"logic_operator": "range", |
|
||||||
"value": dateStart, |
|
||||||
"value1": dateEnd, |
|
||||||
"operator": "AND" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"name": "nama", |
|
||||||
"logic_operator": "ilike", |
|
||||||
"value": this.state.search, |
|
||||||
"operator": "AND", |
|
||||||
} |
|
||||||
], |
|
||||||
"joins": [ |
|
||||||
{ |
|
||||||
"name": "m_proyek", |
|
||||||
"column_join": "proyek_id", |
|
||||||
"column_results": [ |
|
||||||
"nama", |
|
||||||
"biaya", |
|
||||||
"color_progress", |
|
||||||
"jumlah_pekerja", |
|
||||||
"pic", |
|
||||||
"mulai_proyek", |
|
||||||
"akhir_proyek" |
|
||||||
] |
|
||||||
}, |
|
||||||
{ |
|
||||||
"name": "m_subproyek", |
|
||||||
"column_join": "subproyek_id", |
|
||||||
"column_results": [ |
|
||||||
"nama", |
|
||||||
"biaya", |
|
||||||
"color_progress", |
|
||||||
"jumlah_pekerja", |
|
||||||
"pic", |
|
||||||
"mulai_proyek", |
|
||||||
"akhir_proyek" |
|
||||||
] |
|
||||||
}, |
|
||||||
{ |
|
||||||
"name": "m_users", |
|
||||||
"column_join": "user_id", |
|
||||||
"column_results": [ |
|
||||||
"name", |
|
||||||
"username", |
|
||||||
"email", |
|
||||||
"phone_number", |
|
||||||
"gender" |
|
||||||
] |
|
||||||
} |
|
||||||
], |
|
||||||
"orders": { |
|
||||||
"columns": [ |
|
||||||
"planning_id" |
|
||||||
], |
|
||||||
"ascending": true |
|
||||||
}, |
|
||||||
"paging": { |
|
||||||
"start": start, |
|
||||||
"length": this.state.rowsPerPage |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
if(parseInt(role_id)!==1){ |
|
||||||
formData.columns.push( |
|
||||||
{ |
|
||||||
"name": "id", |
|
||||||
"logic_operator": "=", |
|
||||||
"value": proyek_id, |
|
||||||
"operator": "AND", |
|
||||||
"table_name": "m_proyek" |
|
||||||
} |
|
||||||
) |
|
||||||
} |
|
||||||
|
|
||||||
const result = await axios |
|
||||||
.post(PLANNING_REALISASI_SEARCH, formData, config) |
|
||||||
.then(res => res) |
|
||||||
.catch((error) => error.response); |
|
||||||
|
|
||||||
if(result && result.data && result.data.code==200){ |
|
||||||
console.log("cek res planning", result.data.data) |
|
||||||
this.setState({ dataTable: result.data.data, totalPage: result.data.totalRecord }); |
|
||||||
}else{ |
|
||||||
NotificationManager.error('Gagal Menerima Data!!', 'Failed'); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
handleCloseDialogPlan = () => { |
|
||||||
this.setState({openDialogPlan: false}) |
|
||||||
} |
|
||||||
|
|
||||||
handleOpenDialogPlan = (param) => { |
|
||||||
this.setState({openDialogPlan: true}) |
|
||||||
this.setState({dataRealisasi: param.realisasi}) |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
toggleAddDialogPlan = () => { |
|
||||||
this.setState({openDialogPlan: !this.stateopenDialogPlan}) |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
handleOpenDialog = (type) => { |
|
||||||
if(type==="Map"){ |
|
||||||
this.setState({ openDialog: true }) |
|
||||||
this.showChildDialog(); |
|
||||||
}else{ |
|
||||||
this.setState({ openDialogEdit: true }) |
|
||||||
this.showDialogEdit(); |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
handleCloseDialog = () => { |
|
||||||
this.setState({ openDialog: false }) |
|
||||||
} |
|
||||||
|
|
||||||
handleCloseDialogEdit = (type, data) => { |
|
||||||
if(type==="save"){ |
|
||||||
this.updateStatusResponse(data); |
|
||||||
} |
|
||||||
this.setState({ openDialogEdit: false }) |
|
||||||
} |
|
||||||
|
|
||||||
toggleMapDialog = () => { |
|
||||||
this.setState({ openDialog: !this.state.openDialog }) |
|
||||||
} |
|
||||||
|
|
||||||
toggleEditDialog = () => { |
|
||||||
this.setState({ openDialogEdit:!this.state.openDialogEdit }); |
|
||||||
} |
|
||||||
|
|
||||||
handleMap = data => { |
|
||||||
this.setState({ dataMap: data }); |
|
||||||
this.handleOpenDialog('Map'); |
|
||||||
} |
|
||||||
|
|
||||||
handleEdit = data => { |
|
||||||
this.setState({ dataEdit:data }); |
|
||||||
this.handleOpenDialog('Edit'); |
|
||||||
} |
|
||||||
|
|
||||||
handleDelete = (id) => { |
|
||||||
this.setState({ alertDelete: true, idDelete: id }); |
|
||||||
} |
|
||||||
|
|
||||||
onShowSizeChange = (current, pageSize) => { |
|
||||||
this.setState({ rowsPerPage: pageSize }, () => { |
|
||||||
this.getDataReportPlanning(); |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
onPagination = (current, pageSize) => { |
|
||||||
this.setState({ currentPage: current, page: (current - 1) * pageSize }, () => { |
|
||||||
this.getDataReportPlanning(); |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
toggle = (param) => { |
|
||||||
if (param === "map") { |
|
||||||
this.setState(prevState => ({ tooltipMap: !prevState.tooltipMap })) |
|
||||||
}else if(param==="edit"){ |
|
||||||
this.setState(prevState => ({ tooltipEdit: !prevState.tooltipEdit })) |
|
||||||
} else if (param === "delete") { |
|
||||||
this.setState(prevState => ({ tooltipDelete: !prevState.tooltipDelete })) |
|
||||||
} else if (param === "export") { |
|
||||||
this.setState(prevState => ({ tooltipExport: !prevState.tooltipExport })) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
handleDatePicker = (date, dateString) => { |
|
||||||
this.setState({ startDate:date[0],endDate:date[1] },()=>{ |
|
||||||
this.getDataReportPlanning(); |
|
||||||
}) |
|
||||||
} |
|
||||||
|
|
||||||
handleTipe = (e) => { |
|
||||||
this.setState({ typeClock:e.target.value }, () => { |
|
||||||
this.getDataReportPlanning(); |
|
||||||
}); |
|
||||||
} |
|
||||||
|
|
||||||
handleExportExcel = async () => { |
|
||||||
let dateStart = moment(this.state.startDate).format("YYYY-MM-DD 00:00:00"); |
|
||||||
let dateEnd = moment(this.state.endDate).format("YYYY-MM-DD 23:59:59"); |
|
||||||
|
|
||||||
const payload = { |
|
||||||
"columns": [ |
|
||||||
{ |
|
||||||
"name": "created_at", |
|
||||||
"logic_operator": "range", |
|
||||||
"value": dateStart, |
|
||||||
"value1": dateEnd, |
|
||||||
"operator": "AND" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"name": "nama", |
|
||||||
"logic_operator": "ilike", |
|
||||||
"value": this.state.search, |
|
||||||
"operator": "AND", |
|
||||||
} |
|
||||||
], |
|
||||||
"joins": [ |
|
||||||
{ |
|
||||||
"name": "m_proyek", |
|
||||||
"column_join": "proyek_id", |
|
||||||
"column_results": [ |
|
||||||
"nama", |
|
||||||
"biaya", |
|
||||||
"color_progress", |
|
||||||
"jumlah_pekerja", |
|
||||||
"pic", |
|
||||||
"mulai_proyek", |
|
||||||
"akhir_proyek" |
|
||||||
] |
|
||||||
}, |
|
||||||
{ |
|
||||||
"name": "m_subproyek", |
|
||||||
"column_join": "subproyek_id", |
|
||||||
"column_results": [ |
|
||||||
"nama", |
|
||||||
"biaya", |
|
||||||
"color_progress", |
|
||||||
"jumlah_pekerja", |
|
||||||
"pic", |
|
||||||
"mulai_proyek", |
|
||||||
"akhir_proyek" |
|
||||||
] |
|
||||||
}, |
|
||||||
{ |
|
||||||
"name": "m_users", |
|
||||||
"column_join": "user_id", |
|
||||||
"column_results": [ |
|
||||||
"name", |
|
||||||
"username", |
|
||||||
"email", |
|
||||||
"phone_number", |
|
||||||
"gender" |
|
||||||
] |
|
||||||
} |
|
||||||
], |
|
||||||
"orders": { |
|
||||||
"columns": [ |
|
||||||
"planning_id" |
|
||||||
], |
|
||||||
"ascending": true |
|
||||||
}, |
|
||||||
"paging": { |
|
||||||
"start": 0, |
|
||||||
"length": -1 |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
if(parseInt(role_id)!==1){ |
|
||||||
payload.columns.push( |
|
||||||
{ |
|
||||||
"name": "id", |
|
||||||
"logic_operator": "=", |
|
||||||
"value": proyek_id, |
|
||||||
"operator": "AND", |
|
||||||
"table_name": "m_proyek" |
|
||||||
} |
|
||||||
) |
|
||||||
} |
|
||||||
|
|
||||||
const result = await axios |
|
||||||
.post(PLANNING_REALISASI_SEARCH, payload, config) |
|
||||||
.then(res => res) |
|
||||||
.catch((error) => error.response); |
|
||||||
|
|
||||||
|
|
||||||
if(result && result.data && result.data.code == 200){ |
|
||||||
let resData = result.data.data; |
|
||||||
const excelData = []; |
|
||||||
resData.map((n, index) => { |
|
||||||
let dataRow = { |
|
||||||
"Proyek": n.join ? n.join.m_proyek_nama : "-", |
|
||||||
"Pekerjaan": n.nama ? n.nama : "-", |
|
||||||
"Target" : n.jumlah_titik ? n.jumlah_titik : "0", |
|
||||||
"Actual" : n.realisasi ? this.renderActual(n.realisasi) : "0", |
|
||||||
"Team Leader" : n.join.m_subproyek_pic ? `${n.join.m_subproyek_pic}` : "-", |
|
||||||
"Waspang" : n.join.m_users_name ? `${n.join.m_users_name}` : "-", |
|
||||||
"Tanggal" : n.target_planning ? moment(n.target_planning).format("DD-MM-YYYY") : "-", |
|
||||||
} |
|
||||||
excelData.push(dataRow) |
|
||||||
}) |
|
||||||
this.setState({dataExport:excelData}) |
|
||||||
}else{ |
|
||||||
NotificationManager.error('Gagal Export Data!!', 'Failed'); |
|
||||||
}
|
|
||||||
} |
|
||||||
|
|
||||||
exportExcel = () => { |
|
||||||
const dataExcel = this.state.dataExport || []; |
|
||||||
const fileName = `Data Planning vs realisasi.xlsx`; |
|
||||||
const ws = XLSX.utils.json_to_sheet(dataExcel); |
|
||||||
const wb = XLSX.utils.book_new(); |
|
||||||
XLSX.utils.book_append_sheet(wb, ws, `Data Planning vs realisasi`); |
|
||||||
|
|
||||||
XLSX.writeFile(wb, fileName); |
|
||||||
this.setState({dataExport:[] }) |
|
||||||
} |
|
||||||
|
|
||||||
updateStatusResponse = async (data) => { |
|
||||||
let url = ``; |
|
||||||
|
|
||||||
const formData = new FormData(); |
|
||||||
formData.append("lat", data.lat); |
|
||||||
formData.append("lon", data.lon); |
|
||||||
formData.append("status_response", data.status_response); |
|
||||||
|
|
||||||
const result = await axios |
|
||||||
.post(url, formData) |
|
||||||
.then(res => res) |
|
||||||
.catch((error) => error.response); |
|
||||||
if(result && result.data){ |
|
||||||
if (result.data.code_status == 200) { |
|
||||||
NotificationManager.success('Berhasil update status response!!', 'Success!'); |
|
||||||
} else { |
|
||||||
NotificationManager.error('Gagal update status response!!', 'Failed'); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
renderActual = (realisasi) => { |
|
||||||
let data = realisasi || [] |
|
||||||
let sumActual = 0 |
|
||||||
data.map((val, index) => { |
|
||||||
sumActual += parseInt(val.jumlah_pekerjaan) |
|
||||||
}) |
|
||||||
return sumActual |
|
||||||
} |
|
||||||
|
|
||||||
renderTable = () => { |
|
||||||
const dataTable2 = this.state.dataTable || []; |
|
||||||
return ( |
|
||||||
<tbody> |
|
||||||
{dataTable2.length!==0 ? dataTable2.map((n, index) => { |
|
||||||
return ( |
|
||||||
<tr key={index}> |
|
||||||
<td>{index + 1}</td> |
|
||||||
<td>{ n.join ? n.join.m_proyek_nama : "-" }</td> |
|
||||||
<td>{ n.nama ? n.nama : "-"}</td> |
|
||||||
<td>{ n.jumlah_titik ? n.jumlah_titik : "0" }</td> |
|
||||||
<td>{ n.realisasi ? this.renderActual(n.realisasi) : "0" }</td> |
|
||||||
<td>{ n.join.m_subproyek_pic ? `${n.join.m_subproyek_pic}` : "-" }</td> |
|
||||||
<td>{ n.join.m_users_name ? `${n.join.m_users_name}` : "-" }</td> |
|
||||||
<td>{ n.target_planning ? moment(n.target_planning).format("DD-MM-YYYY") : "-" }</td> |
|
||||||
<td> |
|
||||||
{/* <i id="TooltipDelete" className="cil-trash fa-lg" style={{ color: 'red', marginRight: '10px', cursor: "pointer" }} onClick={() => this.handleDelete(n.id)}></i> |
|
||||||
<Tooltip placement="right" isOpen={this.state.tooltipDelete} target="TooltipDelete" toggle={() => this.toggle("delete")}> |
|
||||||
Delete |
|
||||||
</Tooltip>*/} |
|
||||||
{/* <i id="TooltipEdit" className="cil-pencil fa-lg" style={{ color: 'green', cursor: "pointer" }} onClick={() => this.handleEdit(n)}></i> |
|
||||||
<Tooltip placement="right" isOpen={this.state.tooltipEdit} target="TooltipEdit" toggle={() => this.toggle("edit")}> |
|
||||||
Edit |
|
||||||
</Tooltip> |
|
||||||
{' '} */} |
|
||||||
<Tooltip title="View Realisasi"> |
|
||||||
<i onClick={() => this.handleOpenDialogPlan(n)} id="tooltipMap" className="fa fa-eye fa-lg" style={{ color: 'black', cursor: "pointer" }}></i> |
|
||||||
</Tooltip> |
|
||||||
</td> |
|
||||||
</tr> |
|
||||||
) |
|
||||||
}) : <tr> |
|
||||||
<td colSpan="9" align="center">No Data Available</td> |
|
||||||
</tr> |
|
||||||
}
|
|
||||||
</tbody> |
|
||||||
) |
|
||||||
} |
|
||||||
|
|
||||||
handleChangeDay = (e) => { |
|
||||||
const val = e.target.value; |
|
||||||
this.setState({ currentDay:val }); |
|
||||||
if(val==="today"){ |
|
||||||
this.setState({ |
|
||||||
startDate:moment(moment().format("YYYY-M-D")), |
|
||||||
endDate:moment(moment().format("YYYY-M-D")),
|
|
||||||
currentPage: 1 |
|
||||||
}) |
|
||||||
}else if(val==="3 day"){ |
|
||||||
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"){ |
|
||||||
this.setState({ |
|
||||||
startDate:moment(moment().subtract(7, "days").format("YYYY-M-D")), |
|
||||||
endDate:moment(moment().format("YYYY-M-D")),
|
|
||||||
currentPage: 1 |
|
||||||
}) |
|
||||||
}else{ |
|
||||||
this.setState({ |
|
||||||
startDate:moment(moment().format("YYYY-M-D")), |
|
||||||
endDate:moment(moment().format("YYYY-M-D")),
|
|
||||||
currentPage: 1 |
|
||||||
}) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
render() { |
|
||||||
const { tooltipExport,dataTable, openDialogEdit, openDialog, currentPage, rowsPerPage, totalPage, search, tooltipMap, tooltipDelete } = this.state |
|
||||||
return ( |
|
||||||
<div> |
|
||||||
<NotificationContainer /> |
|
||||||
{/* <SweetAlert |
|
||||||
show={this.state.alertDelete} |
|
||||||
warning |
|
||||||
showCancel |
|
||||||
confirmBtnText="Delete" |
|
||||||
confirmBtnBsStyle="danger" |
|
||||||
title="Are you sure?" |
|
||||||
onConfirm={this.onConfirmDelete} |
|
||||||
onCancel={() => this.setState({ alertDelete: false, idDelete: 0 })} |
|
||||||
focusCancelBtn |
|
||||||
> |
|
||||||
Data tipe karyawan akan terhapus!! |
|
||||||
</SweetAlert> */} |
|
||||||
<DialogForm |
|
||||||
openDialog={openDialog} |
|
||||||
closeDialog={this.handleCloseDialog} |
|
||||||
toggleDialog={() => this.toggleMapDialog} |
|
||||||
dataMap={this.state.dataMap} |
|
||||||
showDialog={showDialog => this.showChildDialog = showDialog} |
|
||||||
/> |
|
||||||
<DialogEdit |
|
||||||
openDialog={openDialogEdit} |
|
||||||
closeDialog={this.handleCloseDialogEdit} |
|
||||||
toggleDialog={() => this.toggleEditDialog} |
|
||||||
dataEdit={this.state.dataEdit} |
|
||||||
showDialog={showDialog => this.showDialogEdit = showDialog} |
|
||||||
/> |
|
||||||
<Card> |
|
||||||
<CardHeader style={{ display: "flex", justifyContent: "space-between" }}> |
|
||||||
<h4>Planning Vs Realisasi</h4> |
|
||||||
<div> |
|
||||||
{/* <Button color="primary" onClick={() => this.handleOpenDialog('Save')}>Tambah Broadcast</Button>{' '} */} |
|
||||||
<Tooltip title="Export Excel"> |
|
||||||
<Button id="TooltipExport" color="primary" onClick={()=> this.handleExportExcel()}><i className="fa fa-print"></i></Button> |
|
||||||
</Tooltip> |
|
||||||
</div> |
|
||||||
</CardHeader> |
|
||||||
<CardBody> |
|
||||||
<div style={{ display: "flex", justifyContent: "space-between", marginBottom:"25px" }}> |
|
||||||
<div style={{ width:"100%",display:"inline-flex",alignItems:"center" }}> |
|
||||||
<div style={{ width:"50%",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> |
|
||||||
</Input> |
|
||||||
</div> |
|
||||||
<div style={{ width:"50%" }}> |
|
||||||
<RangePicker size="default" allowClear={false} value={[this.state.startDate, this.state.endDate]} onChange={this.handleDatePicker}/>{' '} |
|
||||||
<Button color="primary" onClick={() => this.getDataReportPlanning()}>Cari</Button> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
<Input onChange={this.handleSearch} value={search} type="text" name="search" id="search" placeholder="Cari Nama Pekerjaan" style={{ maxWidth: "200px", marginBottom: "20px" }} /> |
|
||||||
</div> |
|
||||||
<Table responsive striped hover> |
|
||||||
<thead> |
|
||||||
<tr> |
|
||||||
{/* <th>Actions</th> */} |
|
||||||
{column.map((i, index) => { |
|
||||||
return ( |
|
||||||
<th key={index} scope="row">{i.name}</th> |
|
||||||
) |
|
||||||
})} |
|
||||||
</tr> |
|
||||||
</thead> |
|
||||||
{ this.renderTable() } |
|
||||||
</Table> |
|
||||||
<Pagination |
|
||||||
showSizeChanger |
|
||||||
onShowSizeChange={this.onShowSizeChange} |
|
||||||
onChange={this.onPagination} |
|
||||||
defaultCurrent={currentPage} |
|
||||||
pageSize={rowsPerPage} |
|
||||||
total={parseInt(totalPage)} |
|
||||||
pageSizeOptions={["10", "15", "20", "25", "30", "35", "40"]} |
|
||||||
/> |
|
||||||
</CardBody> |
|
||||||
</Card> |
|
||||||
|
|
||||||
<DialogView |
|
||||||
openDialog={this.state.openDialogPlan} |
|
||||||
closeDialog={() => this.handleCloseDialogPlan()} |
|
||||||
toggleDialog={() => this.toggleAddDialogPlan()} |
|
||||||
dataPlanning={this.state.dataRealisasi} |
|
||||||
/> |
|
||||||
</div> |
|
||||||
) |
|
||||||
} |
|
||||||
} |
|
@ -1,211 +0,0 @@ |
|||||||
import React, { useEffect, useState } from 'react' |
|
||||||
import { Modal, ModalHeader, ModalBody, ModalFooter,Row,Col } from 'reactstrap'; |
|
||||||
import { Button, Form, FormGroup, Label, Input } from 'reactstrap'; |
|
||||||
import { DatePicker,Select } from 'antd'; |
|
||||||
import moment from 'moment'; |
|
||||||
import 'antd/dist/antd.css'; |
|
||||||
|
|
||||||
const { Option } = Select |
|
||||||
const DialogForm = ({openDialog, closeDialog, toggleDialog, typeDialog, dataEdit, dataRole}) => { |
|
||||||
const [id, setId] = useState(0) |
|
||||||
const [user_id, setUserId] = useState(0) |
|
||||||
const [name, setName] = useState('') |
|
||||||
const [username, setUsername] = useState('') |
|
||||||
const [birth_place, setBirthPlace] = useState('') |
|
||||||
const [birth_date, setBirthDate] = useState(moment(moment().format('YYYY-MM-DD'))) |
|
||||||
const [email, setEmail] = useState('') |
|
||||||
const [phone_number, setPhoneNumber] = useState('') |
|
||||||
const [address, setAddress] = useState('') |
|
||||||
const [gender, setGender] = useState('Laki-laki') |
|
||||||
const [password, setPassword] = useState('') |
|
||||||
const [role_id,setIdRole] = useState(null) |
|
||||||
useEffect(()=> { |
|
||||||
if(typeDialog==="Edit"){ |
|
||||||
if(dataEdit){ |
|
||||||
setId(dataEdit.id) |
|
||||||
setIdRole(3) |
|
||||||
setUserId(dataEdit.user_id) |
|
||||||
if(dataEdit.join){ |
|
||||||
setName(dataEdit.join.m_users_name) |
|
||||||
setEmail(dataEdit.join.m_users_email) |
|
||||||
setBirthDate(dataEdit.join.m_users_birth_date ? moment(moment(dataEdit.join.m_users_birth_date).format("YYYY-MM-DD")) : moment(moment())) |
|
||||||
setBirthPlace(dataEdit.join.m_users_birth_place) |
|
||||||
setPhoneNumber(dataEdit.join.m_users_phone_number) |
|
||||||
setGender(dataEdit.join.m_users_gender || "Laki-laki") |
|
||||||
setAddress(dataEdit.join.m_users_address) |
|
||||||
setUsername(dataEdit.join.m_users_username) |
|
||||||
} |
|
||||||
} |
|
||||||
}else{ |
|
||||||
setId(0) |
|
||||||
setName('') |
|
||||||
setEmail('') |
|
||||||
setBirthDate(moment(moment().format('YYYY-MM-DD'))) |
|
||||||
setBirthPlace('') |
|
||||||
setPhoneNumber('') |
|
||||||
setGender('Laki-laki') |
|
||||||
setAddress('') |
|
||||||
setUsername('') |
|
||||||
setPassword('') |
|
||||||
setIdRole(3) |
|
||||||
setUserId(0) |
|
||||||
} |
|
||||||
},[dataEdit,openDialog]) |
|
||||||
|
|
||||||
const handleSave = () => { |
|
||||||
let data = ''; |
|
||||||
if(typeDialog==="Save"){ |
|
||||||
data = { |
|
||||||
name, |
|
||||||
username, |
|
||||||
phone_number, |
|
||||||
email, |
|
||||||
birth_date, |
|
||||||
birth_place, |
|
||||||
gender, |
|
||||||
address, |
|
||||||
password, |
|
||||||
role_id, |
|
||||||
user_id |
|
||||||
} |
|
||||||
closeDialog('save', data); |
|
||||||
}else{ |
|
||||||
data = { |
|
||||||
id, |
|
||||||
name, |
|
||||||
username, |
|
||||||
phone_number, |
|
||||||
email, |
|
||||||
birth_date, |
|
||||||
birth_place, |
|
||||||
gender, |
|
||||||
address, |
|
||||||
role_id, |
|
||||||
user_id |
|
||||||
} |
|
||||||
|
|
||||||
if(password!==''){ |
|
||||||
data['password'] = password |
|
||||||
} |
|
||||||
|
|
||||||
closeDialog('edit', data); |
|
||||||
} |
|
||||||
setId(0) |
|
||||||
setName('') |
|
||||||
setEmail('') |
|
||||||
setBirthDate(moment(moment().format('YYYY-MM-DD'))) |
|
||||||
setBirthPlace('') |
|
||||||
setPhoneNumber('') |
|
||||||
setGender('Laki-laki') |
|
||||||
setAddress('') |
|
||||||
setUsername('') |
|
||||||
setPassword('') |
|
||||||
setIdRole(3) |
|
||||||
setUserId(0) |
|
||||||
} |
|
||||||
|
|
||||||
const handleCancel = () => { |
|
||||||
closeDialog('cancel', 'none') |
|
||||||
setId(0) |
|
||||||
setName('') |
|
||||||
setEmail('') |
|
||||||
setBirthDate(moment(moment().format('YYYY-MM-DD'))) |
|
||||||
setBirthPlace('') |
|
||||||
setPhoneNumber('') |
|
||||||
setGender('Laki-laki') |
|
||||||
setAddress('') |
|
||||||
setUsername('') |
|
||||||
setPassword('') |
|
||||||
setIdRole(null) |
|
||||||
setUserId(0) |
|
||||||
} |
|
||||||
|
|
||||||
const handleDatePicker = (date, dateString) => { |
|
||||||
setBirthDate(date) |
|
||||||
} |
|
||||||
|
|
||||||
const setupOption = () => { |
|
||||||
return( |
|
||||||
<> |
|
||||||
{dataRole.map((val, index)=> { |
|
||||||
return( |
|
||||||
<Option key={index} value={val.id}>{val.name}</Option> |
|
||||||
) |
|
||||||
})} |
|
||||||
</> |
|
||||||
) |
|
||||||
} |
|
||||||
|
|
||||||
const onChangeRole = (val) => { |
|
||||||
setIdRole(val) |
|
||||||
} |
|
||||||
|
|
||||||
const renderForm = () => { |
|
||||||
return( |
|
||||||
<Form> |
|
||||||
<Row> |
|
||||||
<Col> |
|
||||||
<FormGroup> |
|
||||||
<Label className="capitalize">Nama</Label> |
|
||||||
<Input type="text" value={name} onChange={(e)=> setName(e.target.value)} placeholder={`Nama..`}/> |
|
||||||
</FormGroup> |
|
||||||
<FormGroup> |
|
||||||
<Label>Tempat Lahir</Label> |
|
||||||
<Input type="text" value={birth_place} onChange={(e)=> setBirthPlace(e.target.value) } placeholder={`Tempat lahir..`} /> |
|
||||||
</FormGroup> |
|
||||||
<FormGroup> |
|
||||||
<Label>Tanggal Lahir</Label> |
|
||||||
<DatePicker style={{width:"100%"}} value={birth_date} onChange={handleDatePicker} /> |
|
||||||
</FormGroup> |
|
||||||
<FormGroup> |
|
||||||
<Label className="capitalize">Jenis Kelamin</Label> |
|
||||||
<Input type="select" value={gender} onChange={(e)=> setGender(e.target.value)} placeholder={`Jenis Kelamin..`}> |
|
||||||
<option value="Laki-laki">Laki-laki</option> |
|
||||||
<option value="Perempuan">Perempuan</option> |
|
||||||
</Input> |
|
||||||
</FormGroup> |
|
||||||
<FormGroup> |
|
||||||
<Label className="capitalize">Alamat</Label> |
|
||||||
<Input type="textarea" value={address} onChange={(e)=> setAddress(e.target.value)} placeholder={`Alamat..`} /> |
|
||||||
</FormGroup> |
|
||||||
</Col> |
|
||||||
<Col> |
|
||||||
<FormGroup> |
|
||||||
<Label>Username</Label> |
|
||||||
<Input type="text" value={username} onChange={(e)=> setUsername(e.target.value)} placeholder="username.." /> |
|
||||||
</FormGroup> |
|
||||||
<FormGroup> |
|
||||||
<Label>Email</Label> |
|
||||||
<Input type="text" value={email} onChange={(e)=> setEmail(e.target.value)} placeholder="email.." /> |
|
||||||
</FormGroup> |
|
||||||
<FormGroup> |
|
||||||
<Label>Nomor Hp</Label> |
|
||||||
<Input type="text" value={phone_number} onChange={(e)=> setPhoneNumber(e.target.value)} placeholder={`Nomor Hp..`} /> |
|
||||||
</FormGroup> |
|
||||||
<FormGroup> |
|
||||||
<Label>Password</Label> |
|
||||||
<Input type="password" value={password} onChange={(e)=> setPassword(e.target.value)} placeholder="password.." /> |
|
||||||
</FormGroup> |
|
||||||
</Col> |
|
||||||
</Row> |
|
||||||
</Form> |
|
||||||
) |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
return ( |
|
||||||
<Modal size="lg" isOpen={openDialog} toggle={toggleDialog}> |
|
||||||
<ModalHeader className="capitalize" toggle={closeDialog}>{typeDialog=="Save" ? `Tambah` : "Edit"} User Waspang</ModalHeader> |
|
||||||
<ModalBody> |
|
||||||
{renderForm()} |
|
||||||
</ModalBody> |
|
||||||
<ModalFooter> |
|
||||||
<Button color="primary" onClick={() => handleSave()}>{typeDialog}</Button>{' '} |
|
||||||
<Button className="capitalize" color="secondary" onClick={() => handleCancel()}>Batal</Button> |
|
||||||
</ModalFooter> |
|
||||||
</Modal> |
|
||||||
) |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
export default DialogForm; |
|
@ -1,156 +0,0 @@ |
|||||||
import React, { useEffect, useState } from 'react' |
|
||||||
import { Modal, ModalHeader, ModalBody, ModalFooter, Row, Col } from 'reactstrap'; |
|
||||||
import { Button, Form, FormGroup, Label, Input } from 'reactstrap'; |
|
||||||
import { Select, DatePicker } from 'antd'; |
|
||||||
import moment from 'moment'; |
|
||||||
import 'antd/dist/antd.css'; |
|
||||||
const proyekId = localStorage.getItem('proyek_id'); |
|
||||||
const { Option } = Select; |
|
||||||
const DialogProyek = ({ openDialog, closeDialog, toggleDialog, dataWaspangProyek, dataProyek, waspangId }) => { |
|
||||||
const [id, setId] = useState(0) |
|
||||||
const [proyek_id, setProyekId] = useState(null) |
|
||||||
const [user_id, setUserId] = useState(null) |
|
||||||
const [userIdAdd, setUserIdAdd] = useState(0) |
|
||||||
const [startDate, setStartDate] = useState(moment(moment())) |
|
||||||
const [endDate, setEndDate] = useState(moment(moment())) |
|
||||||
const [type, setType] = useState("add") |
|
||||||
const [disableSelectProyek, setDisableSelectProyek] = useState(false) |
|
||||||
const [role_id, setRoleId] = useState(localStorage.getItem('role_id')) |
|
||||||
|
|
||||||
useEffect(() => { |
|
||||||
if (waspangId) { |
|
||||||
setUserIdAdd(waspangId) |
|
||||||
} |
|
||||||
}, [waspangId]) |
|
||||||
|
|
||||||
useEffect(() => { |
|
||||||
let data = dataWaspangProyek || [] |
|
||||||
console.log("waspang id", waspangId) |
|
||||||
console.log("role_id", role_id) |
|
||||||
if (data.length > 0) { |
|
||||||
let dataObj = data[0] |
|
||||||
setType("edit") |
|
||||||
setProyekId(dataObj.proyek_id) |
|
||||||
if (dataObj.mulai) { |
|
||||||
setStartDate(moment(moment(dataObj.mulai))) |
|
||||||
} else { |
|
||||||
setStartDate(moment(moment())) |
|
||||||
} |
|
||||||
|
|
||||||
if (dataObj.mulai) { |
|
||||||
setEndDate(moment(moment(dataObj.akhir))) |
|
||||||
} else { |
|
||||||
setEndDate(moment(moment())) |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
setUserId(dataObj.user_id) |
|
||||||
setId(dataObj.id) |
|
||||||
} else { |
|
||||||
setProyekId(null) |
|
||||||
setStartDate(moment(moment())) |
|
||||||
setEndDate(moment(moment())) |
|
||||||
setType("add") |
|
||||||
} |
|
||||||
|
|
||||||
if (parseInt(role_id) === 2) { |
|
||||||
setProyekId(parseInt(proyekId)) |
|
||||||
setDisableSelectProyek(true) |
|
||||||
} |
|
||||||
}, [dataWaspangProyek, openDialog]) |
|
||||||
|
|
||||||
useEffect(() => { |
|
||||||
if (parseInt(role_id) === 2) { |
|
||||||
setProyekId(parseInt(proyekId)) |
|
||||||
setDisableSelectProyek(true) |
|
||||||
} |
|
||||||
}, [role_id]) |
|
||||||
const handleCancel = () => { |
|
||||||
closeDialog('cancel', 'none') |
|
||||||
setId(0) |
|
||||||
setProyekId(null) |
|
||||||
} |
|
||||||
|
|
||||||
const onChangeParent = (value) => { |
|
||||||
setProyekId(value) |
|
||||||
} |
|
||||||
|
|
||||||
const setupOption = () => { |
|
||||||
return ( |
|
||||||
<> |
|
||||||
{dataProyek.map((val, index) => { |
|
||||||
return ( |
|
||||||
<Option key={index} value={val.id}>{val.nama}</Option> |
|
||||||
) |
|
||||||
})} |
|
||||||
</> |
|
||||||
) |
|
||||||
} |
|
||||||
|
|
||||||
const handleStartDate = (date, string) => { |
|
||||||
setStartDate(date) |
|
||||||
} |
|
||||||
|
|
||||||
const handleEndDate = (date, string) => { |
|
||||||
setEndDate(date) |
|
||||||
} |
|
||||||
|
|
||||||
const handleSave = () => { |
|
||||||
let data = { |
|
||||||
type, |
|
||||||
mulai: startDate, |
|
||||||
akhir: endDate, |
|
||||||
proyek_id, |
|
||||||
user_id |
|
||||||
} |
|
||||||
|
|
||||||
if (type === "add") { |
|
||||||
data['user_id'] = userIdAdd |
|
||||||
} |
|
||||||
|
|
||||||
if (type === "edit") { |
|
||||||
data['id'] = id |
|
||||||
} |
|
||||||
|
|
||||||
closeDialog("save", data) |
|
||||||
} |
|
||||||
|
|
||||||
const renderForm = () => { |
|
||||||
return ( |
|
||||||
<Form> |
|
||||||
<FormGroup> |
|
||||||
<Label className="capitalize">Proyek</Label> |
|
||||||
{/* <Input type="text" value={alias} onChange={(e)=> setAlias(e.target.value)} placeholder={`Icon..`} /> */} |
|
||||||
<Select showSearch value={proyek_id} onChange={onChangeParent} placeholder="Select Proyek .." style={{ width: '100%' }} disabled={disableSelectProyek}> |
|
||||||
{setupOption()} |
|
||||||
</Select> |
|
||||||
</FormGroup> |
|
||||||
<FormGroup> |
|
||||||
<Label className="capitalize">Tanggal Mulai</Label> |
|
||||||
<DatePicker style={{ width: "100%" }} value={startDate} onChange={handleStartDate} allowClear={false} /> |
|
||||||
</FormGroup> |
|
||||||
<FormGroup> |
|
||||||
<Label className="capitalize">Tanggal</Label> |
|
||||||
<DatePicker style={{ width: "100%" }} value={endDate} onChange={handleEndDate} allowClear={false} /> |
|
||||||
</FormGroup> |
|
||||||
</Form> |
|
||||||
) |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
return ( |
|
||||||
<Modal isOpen={openDialog} toggle={toggleDialog}> |
|
||||||
<ModalHeader className="capitalize" toggle={() => closeDialog("none", "none")}>Save User Proyek</ModalHeader> |
|
||||||
<ModalBody> |
|
||||||
{renderForm()} |
|
||||||
</ModalBody> |
|
||||||
<ModalFooter> |
|
||||||
<Button color="primary" onClick={() => handleSave()}>Save</Button>{' '} |
|
||||||
<Button className="capitalize" color="secondary" onClick={() => handleCancel()}>Batal</Button> |
|
||||||
</ModalFooter> |
|
||||||
</Modal> |
|
||||||
) |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
export default DialogProyek; |
|
@ -1,686 +0,0 @@ |
|||||||
import React, { useState, useEffect } from 'react'; |
|
||||||
import { Card, CardBody, CardHeader, Col, Row, Table, Input } from 'reactstrap'; |
|
||||||
import { Button } from 'reactstrap'; |
|
||||||
import axios from 'axios'; |
|
||||||
import * as XLSX from 'xlsx'; |
|
||||||
import SweetAlert from 'react-bootstrap-sweetalert'; |
|
||||||
import DialogForm from './DialogForm'; |
|
||||||
import { NotificationContainer, NotificationManager } from 'react-notifications'; |
|
||||||
import { Pagination, Tooltip } from 'antd'; |
|
||||||
import {
|
|
||||||
USER_ADD, |
|
||||||
USER_SEARCH, |
|
||||||
USER_EDIT, |
|
||||||
USER_DELETE,
|
|
||||||
ROLE_SEARCH, |
|
||||||
USERROLE_ADD, |
|
||||||
USERROLE_EDIT, |
|
||||||
USERROLE_DELETE, |
|
||||||
USERROLE_SEARCH, |
|
||||||
USERPROYEK_SEARCH, |
|
||||||
PROYEK_SEARCH, |
|
||||||
USERPROYEK_EDIT, |
|
||||||
USERPROYEK_ADD |
|
||||||
} from '../../../const/ApiConst.js';import moment from 'moment'; |
|
||||||
import DialogProyek from './DialogProyek'; |
|
||||||
const token = window.localStorage.getItem('token'); |
|
||||||
const config = { |
|
||||||
headers:
|
|
||||||
{
|
|
||||||
Authorization : `Bearer ${token}`, |
|
||||||
"Content-type" : `application/json` |
|
||||||
} |
|
||||||
}; |
|
||||||
const column =
|
|
||||||
[ |
|
||||||
{ name: "Nama" }, |
|
||||||
{ name: "Tempat Lahir" }, |
|
||||||
{ name: "Tanggal Lahir" }, |
|
||||||
{ name: "Nomor Telepon" }, |
|
||||||
{ name: "Email" }, |
|
||||||
{ name: "Proyek"} |
|
||||||
] |
|
||||||
|
|
||||||
|
|
||||||
const IndexUser = ({params}) => { |
|
||||||
const [dataTable, setDatatable] = useState([]) |
|
||||||
const [search, setSearch] = useState('') |
|
||||||
const [currentPage, setCurrentPage] = useState(1) |
|
||||||
const [totalPage, setTotalPage] = useState(0) |
|
||||||
const [openDialog, setOpenDialog] = useState(false) |
|
||||||
const [typeDialog, setTypeDialog] = useState('Save') |
|
||||||
const [idDelete, setIdDelete] = useState(0) |
|
||||||
const [dataProyek, setDataProyek] = useState([]) |
|
||||||
const [alertDelete, setAlertDelete] = useState(false) |
|
||||||
const [dataEdit, setDataEdit] = useState([]) |
|
||||||
const [rowsPerPage, setRowsPerPage] = useState(10) |
|
||||||
const [clickOpenModal, setClickOpenModal] = useState(false) |
|
||||||
const [allDataUserProyek, setAllDataUserProyek] = useState([]) |
|
||||||
const [dataRole, setDataRole] = useState([]) |
|
||||||
const [dataExport, setDataExport] = useState([]) |
|
||||||
const [openDialogProyek, setOpenDialogProyek] = useState(false) |
|
||||||
const [dataWaspangProyek, setDataWaspangProyek] = useState([]) |
|
||||||
const [waspangId, setWaspangId] = useState([]) |
|
||||||
const pageName = params.name; |
|
||||||
useEffect(()=> { |
|
||||||
getAllDataRole(); |
|
||||||
getAllDataProyek(); |
|
||||||
getAllDataUserProyek(); |
|
||||||
},[]) |
|
||||||
|
|
||||||
useEffect(()=> { |
|
||||||
getDataUser(); |
|
||||||
},[search,rowsPerPage,currentPage]) |
|
||||||
|
|
||||||
useEffect(()=> { |
|
||||||
const cekData = dataExport || [] |
|
||||||
if(cekData.length > 0){ |
|
||||||
exportExcel() |
|
||||||
} |
|
||||||
},[dataExport]) |
|
||||||
|
|
||||||
const handleSearch = e => { |
|
||||||
const value = e.target.value |
|
||||||
setSearch(value); |
|
||||||
setCurrentPage(1) |
|
||||||
}; |
|
||||||
|
|
||||||
const getAllDataRole = async () => { |
|
||||||
|
|
||||||
const payload = { |
|
||||||
"paging": {"start": 0, "length": -1}, |
|
||||||
"columns": [ |
|
||||||
{"name": "name", "logic_operator": "ilike", "value": "", "operator": "AND"} |
|
||||||
], |
|
||||||
"joins": [], |
|
||||||
"orders": {"columns": ["id"], "ascending": false} |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const result = await axios |
|
||||||
.post(ROLE_SEARCH, payload, config) |
|
||||||
.then(res => res) |
|
||||||
.catch((error) => error.response); |
|
||||||
|
|
||||||
|
|
||||||
if(result && result.data && result.data.code == 200){ |
|
||||||
setDataRole(result.data.data); |
|
||||||
}else{ |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
const getAllDataProyek = async () => { |
|
||||||
|
|
||||||
const payload = { |
|
||||||
"paging": {"start": 0, "length": -1}, |
|
||||||
"columns": [ |
|
||||||
{"name": "nama", "logic_operator": "ilike", "value": "", "operator": "AND"} |
|
||||||
], |
|
||||||
"joins": [], |
|
||||||
"orders": {"columns": ["id"], "ascending": false} |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const result = await axios |
|
||||||
.post(PROYEK_SEARCH, payload, config) |
|
||||||
.then(res => res) |
|
||||||
.catch((error) => error.response); |
|
||||||
|
|
||||||
if(result && result.data && result.data.code == 200){ |
|
||||||
setDataProyek(result.data.data); |
|
||||||
}else{ |
|
||||||
|
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
const getAllDataUserProyek = async () => { |
|
||||||
const formData = { |
|
||||||
"paging": {"start": 0, "length": -1}, |
|
||||||
"columns": [ |
|
||||||
], |
|
||||||
"joins": [ |
|
||||||
{ |
|
||||||
"name":"m_proyek", |
|
||||||
"column_join":"proyek_id", |
|
||||||
"column_results":[ |
|
||||||
"nama", |
|
||||||
] |
|
||||||
} |
|
||||||
], |
|
||||||
"orders": {"columns": ["id"], "ascending": false} |
|
||||||
} |
|
||||||
const result = await axios.post(USERPROYEK_SEARCH, formData, config) |
|
||||||
.then(res => res) |
|
||||||
.catch((error) => error.response); |
|
||||||
|
|
||||||
if(result && result.data && result.data.code===200){ |
|
||||||
setAllDataUserProyek(result.data.data) |
|
||||||
}else{ |
|
||||||
|
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
const getDataUser = async () => { |
|
||||||
|
|
||||||
let start = 0; |
|
||||||
|
|
||||||
if (currentPage !== 1 && currentPage > 1) { |
|
||||||
start = (currentPage * rowsPerPage) - rowsPerPage |
|
||||||
} |
|
||||||
|
|
||||||
const payload = { |
|
||||||
"paging":{ |
|
||||||
"start":start, |
|
||||||
"length":rowsPerPage |
|
||||||
}, |
|
||||||
"filter_columns":[ |
|
||||||
{ |
|
||||||
"name":"name", |
|
||||||
"value":"", |
|
||||||
"table_name":"m_users" |
|
||||||
} |
|
||||||
], |
|
||||||
"columns":[ |
|
||||||
{ |
|
||||||
"name":"name", |
|
||||||
"logic_operator":"like", |
|
||||||
"value":search, |
|
||||||
"operator":"AND", |
|
||||||
"table_name":"m_users" |
|
||||||
}, |
|
||||||
{ |
|
||||||
"name":"id", |
|
||||||
"logic_operator":"=", |
|
||||||
"value":'3', |
|
||||||
"operator":"AND", |
|
||||||
"table_name":"m_roles" |
|
||||||
} |
|
||||||
], |
|
||||||
"joins":[ |
|
||||||
{ |
|
||||||
"name":"m_users", |
|
||||||
"column_join":"user_id", |
|
||||||
"column_results":[ |
|
||||||
"username", |
|
||||||
"name", |
|
||||||
"email", |
|
||||||
"gender", |
|
||||||
"phone_number", |
|
||||||
"address", |
|
||||||
"birth_place", |
|
||||||
"birth_date" |
|
||||||
] |
|
||||||
}, |
|
||||||
{ |
|
||||||
"name":"m_roles", |
|
||||||
"column_join":"role_id", |
|
||||||
"column_results":[ |
|
||||||
"name" |
|
||||||
] |
|
||||||
} |
|
||||||
], |
|
||||||
"orders":{ |
|
||||||
"columns":[ |
|
||||||
"id" |
|
||||||
], |
|
||||||
"ascending":false |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const result = await axios |
|
||||||
.post(USERROLE_SEARCH, payload, config) |
|
||||||
.then(res => res) |
|
||||||
.catch((error) => error.response); |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if(result && result.data && result.data.code == 200){ |
|
||||||
setDatatable(result.data.data); |
|
||||||
setTotalPage(result.data.totalRecord); |
|
||||||
}else{ |
|
||||||
NotificationManager.error('Gagal Mengambil Data!!', 'Failed'); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
const handleOpenDialog = async (type) => { |
|
||||||
await setTypeDialog(type) |
|
||||||
setOpenDialog(true) |
|
||||||
} |
|
||||||
|
|
||||||
const handleCloseDialog = (type, data) => { |
|
||||||
if (type === "save") { |
|
||||||
saveUser(data); |
|
||||||
} else if (type === "edit") { |
|
||||||
editUser(data); |
|
||||||
} |
|
||||||
setDataEdit([]) |
|
||||||
setOpenDialog(false) |
|
||||||
} |
|
||||||
|
|
||||||
const toggleAddDialog = () => { |
|
||||||
setOpenDialog(!openDialog) |
|
||||||
} |
|
||||||
|
|
||||||
const onConfirmDelete = async () => { |
|
||||||
let url = USER_DELETE(idDelete); |
|
||||||
|
|
||||||
const result = await axios.delete(url,config) |
|
||||||
.then(res => res) |
|
||||||
.catch((error) => error.response); |
|
||||||
|
|
||||||
if (result && result.data && result.data.code === 200) { |
|
||||||
getDataUser() |
|
||||||
setIdDelete(0) |
|
||||||
setAlertDelete(false) |
|
||||||
NotificationManager.success(`Data user berhasil dihapus!`, 'Success!!'); |
|
||||||
} else { |
|
||||||
setIdDelete(0) |
|
||||||
setAlertDelete(false) |
|
||||||
NotificationManager.error(`Data user gagal dihapus!}`, 'Failed!!'); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
const userRoleDelete = async (id) => { |
|
||||||
let url = USERROLE_DELETE(id); |
|
||||||
|
|
||||||
const result = await axios.delete(url,config) |
|
||||||
.then(res => res) |
|
||||||
.catch((error) => error.response); |
|
||||||
|
|
||||||
if (result && result.data && result.data.code === 200) { |
|
||||||
|
|
||||||
} else { |
|
||||||
|
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
const saveUser = async (data) => {
|
|
||||||
const formData = data |
|
||||||
|
|
||||||
const result = await axios.post(USER_ADD, formData, config) |
|
||||||
.then(res => res) |
|
||||||
.catch((error) => error.response); |
|
||||||
|
|
||||||
if(result && result.data && result.data.code===200){ |
|
||||||
let dataRes = result.data.data |
|
||||||
addUserRole(dataRes.id, data.role_id) |
|
||||||
} else { |
|
||||||
NotificationManager.error(`${result.data.message}`, 'Failed!!'); |
|
||||||
}
|
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
const editUser = async (data) => { |
|
||||||
|
|
||||||
let url = USER_EDIT(data.user_id) |
|
||||||
|
|
||||||
const formData = data |
|
||||||
|
|
||||||
const result = await axios.put(url, formData, config) |
|
||||||
.then(res => res) |
|
||||||
.catch((error) => error.response); |
|
||||||
|
|
||||||
if(result && result.data && result.data.code===200){ |
|
||||||
editUserRole(data) |
|
||||||
} else { |
|
||||||
NotificationManager.error(`${result.data.message}`, `Failed!!`); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
const addUserRole = async (user_id, role_id) => { |
|
||||||
const formData = { |
|
||||||
user_id, |
|
||||||
role_id |
|
||||||
} |
|
||||||
const result = await axios.post(USERROLE_ADD, formData, config) |
|
||||||
.then(res => res) |
|
||||||
.catch((error) => error.response); |
|
||||||
|
|
||||||
if(result && result.data && result.data.code===200){ |
|
||||||
getDataUser(); |
|
||||||
NotificationManager.success(`Data user berhasil ditambahkan`, 'Success!!'); |
|
||||||
} else { |
|
||||||
NotificationManager.error(`${result.data.message}`, `Failed!!`); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
const editUserRole = async (data) => { |
|
||||||
let url = USERROLE_EDIT(data.id) |
|
||||||
|
|
||||||
const formData = { |
|
||||||
user_id:data.user_id, |
|
||||||
role_id:data.role_id |
|
||||||
} |
|
||||||
|
|
||||||
const result = await axios.put(url, formData, config) |
|
||||||
.then(res => res) |
|
||||||
.catch((error) => error.response); |
|
||||||
|
|
||||||
if(result && result.data && result.data.code===200){ |
|
||||||
getDataUser(); |
|
||||||
NotificationManager.success(`Data user berhasil di edit`, 'Success!!'); |
|
||||||
} else { |
|
||||||
NotificationManager.error(`${result.data.message}`, `Failed!!`); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
const handleEdit = async (data) => { |
|
||||||
await setDataEdit(data) |
|
||||||
handleOpenDialog('Edit'); |
|
||||||
} |
|
||||||
|
|
||||||
const handleDelete = async (id) => { |
|
||||||
await setAlertDelete(true) |
|
||||||
await setIdDelete(id) |
|
||||||
} |
|
||||||
|
|
||||||
const onShowSizeChange = (current, pageSize) => { |
|
||||||
setRowsPerPage(pageSize) |
|
||||||
} |
|
||||||
|
|
||||||
const onPagination = (current, pageSize) => { |
|
||||||
setCurrentPage(current) |
|
||||||
} |
|
||||||
|
|
||||||
const handleExportExcel = async () => { |
|
||||||
|
|
||||||
const payload = { |
|
||||||
"paging":{ |
|
||||||
"start":0, |
|
||||||
"length":-1 |
|
||||||
}, |
|
||||||
"filter_columns":[ |
|
||||||
{ |
|
||||||
"name":"name", |
|
||||||
"value":"", |
|
||||||
"table_name":"m_users" |
|
||||||
} |
|
||||||
], |
|
||||||
"columns":[ |
|
||||||
{ |
|
||||||
"name":"name", |
|
||||||
"logic_operator":"like", |
|
||||||
"value":search, |
|
||||||
"operator":"AND", |
|
||||||
"table_name":"m_users" |
|
||||||
} |
|
||||||
], |
|
||||||
"joins":[ |
|
||||||
{ |
|
||||||
"name":"m_users", |
|
||||||
"column_join":"user_id", |
|
||||||
"column_results":[ |
|
||||||
"username", |
|
||||||
"name", |
|
||||||
"email", |
|
||||||
"gender", |
|
||||||
"phone_number", |
|
||||||
"address", |
|
||||||
"birth_place", |
|
||||||
"birth_date" |
|
||||||
] |
|
||||||
}, |
|
||||||
{ |
|
||||||
"name":"m_roles", |
|
||||||
"column_join":"role_id", |
|
||||||
"column_results":[ |
|
||||||
"name" |
|
||||||
] |
|
||||||
} |
|
||||||
], |
|
||||||
"orders":{ |
|
||||||
"columns":[ |
|
||||||
"id" |
|
||||||
], |
|
||||||
"ascending":false |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const result = await axios |
|
||||||
.post(USERROLE_SEARCH, payload, config) |
|
||||||
.then(res => res) |
|
||||||
.catch((error) => error.response); |
|
||||||
|
|
||||||
if(result && result.data && result.data.code == 200){ |
|
||||||
let resData = result.data.data; |
|
||||||
const excelData = []; |
|
||||||
resData.map((n, index) => { |
|
||||||
let dataRow = { |
|
||||||
"Name" :n.join.m_users_name ? n.join.m_users_name : "-", |
|
||||||
"Email" :n.join.m_users_email ? n.join.m_users_email : "-", |
|
||||||
"Username" :n.join.m_users_username ? n.join.m_users_username : "-", |
|
||||||
"Phone Number":n.join.m_users_phone_number ? n.join.m_users_phone_number : "-", |
|
||||||
"Address":n.join.m_users_address ? n.join.m_users_address : "-", |
|
||||||
"Birth Date":n.join.m_users_birth_date ? moment(n.join.m_users_birth_date).format("YYYY-MM-DD") : "-", |
|
||||||
"Birth Place":n.join.m_users_birth_place ? n.join.m_users_birth_place : "-", |
|
||||||
"Gender":n.join.m_users_gender ? n.join.m_users_gender : "-" |
|
||||||
} |
|
||||||
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); |
|
||||||
} |
|
||||||
|
|
||||||
const cancelDelete = () => { |
|
||||||
setAlertDelete(false) |
|
||||||
setIdDelete(0) |
|
||||||
} |
|
||||||
|
|
||||||
const renderRoleProyek = (role_name, user_id) => { |
|
||||||
const userProyek = allDataUserProyek || [] |
|
||||||
let index = userProyek.findIndex(x => parseInt(x.user_id) === parseInt(user_id)); |
|
||||||
if(index>=0){ |
|
||||||
return allDataUserProyek[index].join.m_proyek_nama |
|
||||||
}else{ |
|
||||||
return role_name; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
const handleWaspangProyek = async (data) => { |
|
||||||
await setWaspangId(data.user_id) |
|
||||||
getDataWaspangProyek(data.user_id); |
|
||||||
} |
|
||||||
|
|
||||||
const getDataWaspangProyek = async (id) => { |
|
||||||
const formData = { |
|
||||||
"paging": {"start": 0, "length": -1}, |
|
||||||
"columns": [ |
|
||||||
{"name": "user_id", "logic_operator": "=", "value": id.toString(), "operator": "AND"} |
|
||||||
], |
|
||||||
"joins": [], |
|
||||||
"orders": {"columns": ["id"], "ascending": false} |
|
||||||
} |
|
||||||
const result = await axios.post(USERPROYEK_SEARCH, formData, config) |
|
||||||
.then(res => res) |
|
||||||
.catch((error) => error.response); |
|
||||||
|
|
||||||
if(result && result.data && result.data.code===200){ |
|
||||||
let dataRes = result.data.data |
|
||||||
if(dataRes.length > 0){ |
|
||||||
await setDataWaspangProyek(result.data.data) |
|
||||||
setOpenDialogProyek(true) |
|
||||||
}else { |
|
||||||
await setDataWaspangProyek([]) |
|
||||||
setOpenDialogProyek(true) |
|
||||||
} |
|
||||||
|
|
||||||
} else { |
|
||||||
NotificationManager.error(`${result.data.message}`, `Failed!!`); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
const closeProyekDialog = (type, data) => { |
|
||||||
if(type==="save"){ |
|
||||||
if(data.type==="add"){ |
|
||||||
saveWaspangProyek(data) |
|
||||||
}else{ |
|
||||||
editWaspangProyek(data) |
|
||||||
} |
|
||||||
} |
|
||||||
setOpenDialogProyek(false) |
|
||||||
} |
|
||||||
|
|
||||||
const saveWaspangProyek = async (data) => { |
|
||||||
const formData = data |
|
||||||
|
|
||||||
const result = await axios.post(USERPROYEK_ADD, formData, config) |
|
||||||
.then(res => res) |
|
||||||
.catch((error) => error.response); |
|
||||||
|
|
||||||
if(result && result.data && result.data.code===200){ |
|
||||||
NotificationManager.success(`Data user proyek berhasil ditambahkan`, 'Success!!'); |
|
||||||
} else { |
|
||||||
NotificationManager.error(`${result.data.message}`, `Failed!!`); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
const editWaspangProyek = async (data) => { |
|
||||||
|
|
||||||
let url = USERPROYEK_EDIT(data.id) |
|
||||||
|
|
||||||
const formData = data |
|
||||||
|
|
||||||
const result = await axios.put(url, formData, config) |
|
||||||
.then(res => res) |
|
||||||
.catch((error) => error.response); |
|
||||||
|
|
||||||
if(result && result.data && result.data.code===200){ |
|
||||||
NotificationManager.success(`Data user proyek berhasil diedit`, 'Success!!'); |
|
||||||
} else { |
|
||||||
NotificationManager.error(`${result.data.message}`, `Failed!!`); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
const toggleProyekDialog = () => { |
|
||||||
setOpenDialogProyek(!openDialogProyek) |
|
||||||
} |
|
||||||
|
|
||||||
return ( |
|
||||||
<div> |
|
||||||
<NotificationContainer /> |
|
||||||
<SweetAlert |
|
||||||
show={alertDelete} |
|
||||||
warning |
|
||||||
showCancel |
|
||||||
confirmBtnText="Delete" |
|
||||||
confirmBtnBsStyle="danger" |
|
||||||
title={`Apakah kamu yakin?`} |
|
||||||
onConfirm={onConfirmDelete} |
|
||||||
onCancel={() => cancelDelete()} |
|
||||||
focusCancelBtn |
|
||||||
> |
|
||||||
Data user waspang akan terhapus!! |
|
||||||
</SweetAlert> |
|
||||||
<DialogForm |
|
||||||
openDialog={openDialog} |
|
||||||
closeDialog={handleCloseDialog} |
|
||||||
toggleDialog={() => toggleAddDialog} |
|
||||||
typeDialog={typeDialog} |
|
||||||
dataEdit={dataEdit} |
|
||||||
clickOpenModal={clickOpenModal} |
|
||||||
dataRole={dataRole} |
|
||||||
/> |
|
||||||
<DialogProyek |
|
||||||
openDialog={openDialogProyek} |
|
||||||
closeDialog={closeProyekDialog} |
|
||||||
dataProyek={dataProyek} |
|
||||||
dataWaspangProyek={dataWaspangProyek} |
|
||||||
toggleDialog={toggleProyekDialog} |
|
||||||
waspangId={waspangId} |
|
||||||
/> |
|
||||||
<Card> |
|
||||||
<CardHeader style={{ display: "flex", justifyContent: "space-between" }}> |
|
||||||
<h4>{pageName}</h4> |
|
||||||
<Row> |
|
||||||
<Col> |
|
||||||
<Input onChange={handleSearch} value={search} type="text" name="search" id="search" placeholder={`Cari nama`} /> |
|
||||||
</Col> |
|
||||||
<Col> |
|
||||||
<Tooltip title="Tambah User Waspang"> |
|
||||||
<Button id="TooltipTambah" color="success" onClick={() => handleOpenDialog('Save')}><i className="fa fa-plus"></i></Button> |
|
||||||
</Tooltip> |
|
||||||
<Tooltip title="Export Excel"> |
|
||||||
<Button style={{marginLeft:"5px"}} id="TooltipExport" color="primary" onClick={()=> handleExportExcel()}><i className="fa fa-print"></i></Button> |
|
||||||
</Tooltip> |
|
||||||
</Col> |
|
||||||
</Row> |
|
||||||
</CardHeader> |
|
||||||
<CardBody> |
|
||||||
<Table responsive striped hover> |
|
||||||
<thead> |
|
||||||
<tr> |
|
||||||
<th className="capitalize">Aksi</th> |
|
||||||
{column.map((i, index) => { |
|
||||||
return ( |
|
||||||
<th key={index} scope="row">{i.name}</th> |
|
||||||
) |
|
||||||
})} |
|
||||||
</tr> |
|
||||||
</thead> |
|
||||||
<tbody> |
|
||||||
{dataTable.length<=0 ?
|
|
||||||
<tr> |
|
||||||
<td colSpan="7" align="center">No Data Available</td> |
|
||||||
</tr> : null} |
|
||||||
{dataTable.map((n, index) => { |
|
||||||
return ( |
|
||||||
<tr key={index}> |
|
||||||
<td> |
|
||||||
<Tooltip title="Delete"> |
|
||||||
<i id="TooltipDelete" className="fa fa-trash" style={{ color: 'red', marginRight: '10px', cursor: "pointer" }} onClick={() => handleDelete(n.user_id)}></i> |
|
||||||
</Tooltip> |
|
||||||
<Tooltip title="Edit"> |
|
||||||
<i id="TooltipEdit" className="fa fa-pencil" style={{ color: 'green', cursor: "pointer",marginRight: '10px' }} onClick={() => handleEdit(n)}></i> |
|
||||||
</Tooltip> |
|
||||||
<Tooltip title={`Proyek`}> |
|
||||||
<i onClick={() => handleWaspangProyek(n)} style={{color:"black", cursor: "pointer"}} className="cil-task"></i> |
|
||||||
</Tooltip> |
|
||||||
</td> |
|
||||||
<td>{n.join ? n.join.m_users_name : "-"}</td> |
|
||||||
<td>{n.join ? n.join.m_users_birth_place || "-" : "-"}</td> |
|
||||||
<td>{n.join.m_users_birth_date ? moment(n.join.m_users_birth_date).format("YYYY-MM-DD") : "-"}</td> |
|
||||||
<td>{n.join ? n.join.m_users_phone_number : "-"}</td> |
|
||||||
<td>{n.join ? n.join.m_users_email : "-"}</td> |
|
||||||
{/* <td>{n.join ? n.join.m_roles_name : "-"}</td> */} |
|
||||||
<td>{n.join ? n.role_id===3 ? renderRoleProyek(n.join.m_roles_name, n.user_id) : n.join.m_roles_name : "-"}</td> |
|
||||||
</tr> |
|
||||||
) |
|
||||||
})} |
|
||||||
</tbody> |
|
||||||
</Table> |
|
||||||
<Pagination |
|
||||||
showSizeChanger |
|
||||||
onShowSizeChange={onShowSizeChange} |
|
||||||
onChange={onPagination} |
|
||||||
defaultCurrent={currentPage} |
|
||||||
pageSize={rowsPerPage} |
|
||||||
total={totalPage} |
|
||||||
pageSizeOptions={["10", "15", "20", "25", "30", "35", "40"]} |
|
||||||
/> |
|
||||||
</CardBody> |
|
||||||
</Card> |
|
||||||
</div> |
|
||||||
) |
|
||||||
} |
|
||||||
|
|
||||||
export default IndexUser; |
|