Browse Source

first commit

pull/2/head
Anggara MAG 2 years ago
parent
commit
c9ac6d9796
  1. 14
      .editorconfig
  2. 3
      .env
  3. 28
      .gitignore
  4. 410
      API_GeoHR_docs.md
  5. 476
      CHANGELOG.md
  6. 172
      CONTRIBUTING.md
  7. 2473
      CRA.md
  8. 20
      ISSUE_TEMPLATE.md
  9. 21
      LICENSE
  10. 41
      REACT.md
  11. 57
      README.md
  12. 177
      README_COREUI_TEMPLATE.md
  13. BIN
      docs/WhatsApp Image 2022-07-07 at 11.53.46 AM.jpeg
  14. 137
      package.json
  15. 0
      public/assets/.gitkeep
  16. BIN
      public/assets/img/avatars/1.jpg
  17. BIN
      public/assets/img/avatars/2.jpg
  18. BIN
      public/assets/img/avatars/3.jpg
  19. BIN
      public/assets/img/avatars/4.jpg
  20. BIN
      public/assets/img/avatars/5.jpg
  21. BIN
      public/assets/img/avatars/6.jpg
  22. BIN
      public/assets/img/avatars/7.jpg
  23. BIN
      public/assets/img/avatars/8.jpg
  24. BIN
      public/assets/img/favicon.png
  25. BIN
      public/assets/img/favicon_bmd_denpasar.png
  26. BIN
      public/assets/img/favicon_old.png
  27. 101
      public/index.html
  28. 15
      public/manifest.json
  29. BIN
      public/simpro-icon.ico
  30. 46
      src/App.js
  31. 11
      src/App.scss
  32. 9
      src/App.test.js
  33. 151
      src/_nav.js
  34. 16
      src/assets/css/customscroll.css
  35. 3275
      src/assets/db/bmd_denpasar_2018_27012020.sql
  36. 3044
      src/assets/db/bmd_denpasar_27012020.sql
  37. 13
      src/assets/docs/layer_legend.txt
  38. 208
      src/assets/docs/layer_styles.txt
  39. 643
      src/assets/docs/wfs_example.txt
  40. BIN
      src/assets/img/avatars/user.png
  41. BIN
      src/assets/img/base_map/bali.PNG
  42. BIN
      src/assets/img/base_map/bali_citra.PNG
  43. BIN
      src/assets/img/base_map/esri.PNG
  44. BIN
      src/assets/img/base_map/google.PNG
  45. BIN
      src/assets/img/base_map/google_street.PNG
  46. BIN
      src/assets/img/base_map/iu_map.PNG
  47. BIN
      src/assets/img/base_map/osm.PNG
  48. BIN
      src/assets/img/base_map/osm_light.PNG
  49. 44
      src/assets/img/brand/logo.svg
  50. BIN
      src/assets/img/brand/logo_bmd_denpasar.png
  51. BIN
      src/assets/img/brand/logo_kominfo.jpeg
  52. BIN
      src/assets/img/brand/logo_siopas.png
  53. BIN
      src/assets/img/brand/logo_siopas_old.png
  54. 17
      src/assets/img/brand/sygnet.svg
  55. BIN
      src/assets/img/image.png
  56. BIN
      src/assets/img/kominfo/dashboard.jpg
  57. BIN
      src/assets/img/kominfo/dashboard_kominfo_image_2G.jpg
  58. BIN
      src/assets/img/kominfo/dashboard_kominfo_image_3G.jpg
  59. BIN
      src/assets/img/kominfo/dashboard_kominfo_image_4G.jpg
  60. BIN
      src/assets/img/login/carousel1.jpeg
  61. BIN
      src/assets/img/login/carousel2.jpeg
  62. BIN
      src/assets/img/login/carousel3.jpeg
  63. BIN
      src/assets/img/login/slide1.jpg
  64. BIN
      src/assets/img/login/slide2.jpg
  65. BIN
      src/assets/img/login/slide3.jpg
  66. BIN
      src/assets/img/login/slide4.jpg
  67. BIN
      src/assets/img/logo-surveyor-indonesia-2.png
  68. BIN
      src/assets/img/logo-surveyor-indonesia.png
  69. BIN
      src/assets/img/logo_adyawinsa.jpg
  70. BIN
      src/assets/img/logo_kit.png
  71. BIN
      src/assets/img/logo_nawakara.png
  72. BIN
      src/assets/img/map/customer.png
  73. BIN
      src/assets/img/map/office.png
  74. BIN
      src/assets/img/map/officec.png
  75. BIN
      src/assets/img/map/pin2.png
  76. BIN
      src/assets/img/map/pin_ori.png
  77. BIN
      src/assets/img/map/pin_route_green.png
  78. BIN
      src/assets/img/map/pin_route_red.png
  79. BIN
      src/assets/img/map/store.png
  80. 1064
      src/assets/json/indonesia.json
  81. 9
      src/components/AddFeature/AddFeature.css
  82. 141
      src/components/AddFeature/AddFeature.js
  83. 6
      src/components/AddFeature/package.json
  84. 101
      src/components/AdmTree/AdmTree.css
  85. 734
      src/components/AdmTree/AdmTree.js
  86. 544
      src/components/AdmTree/AdmTree_backup.js
  87. 136
      src/components/AdmTree/example.js
  88. 6
      src/components/AdmTree/package.json
  89. 74
      src/components/BaseMap/BaseMap.css
  90. 71
      src/components/BaseMap/BaseMap.js
  91. 6
      src/components/BaseMap/package.json
  92. 19
      src/components/CreateNewLayer/CreateNewLayer.css
  93. 348
      src/components/CreateNewLayer/CreateNewLayer.js
  94. 6
      src/components/CreateNewLayer/package.json
  95. 25
      src/components/CustomModal/CustomModal.js
  96. 6
      src/components/CustomModal/package.json
  97. 52
      src/components/DailyInfo/DailyInfo.css
  98. 655
      src/components/DailyInfo/DailyInfo.js
  99. 357
      src/components/DailyInfo/DialogBottom.js
  100. 6
      src/components/DailyInfo/package.json
  101. Some files were not shown because too many files have changed in this diff Show More

14
.editorconfig

@ -0,0 +1,14 @@
# Editor configuration, see http://editorconfig.org
root = true
[*]
charset = utf-8
end_of_line = lf
indent_size = 2
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
[*.md]
max_line_length = off
trim_trailing_whitespace = false

3
.env

@ -0,0 +1,3 @@
PORT=3000
CHOKIDAR_USEPOLLING=true
GENERATE_SOURCEMAP=false

28
.gitignore vendored

@ -0,0 +1,28 @@
# See https://help.github.com/ignore-files/ for more about ignoring files.
# dependencies
/node_modules
/src/views/Report/ControlMonitoringv1.rar
# testing
/coverage
# production
/build
# misc
.DS_Store
.idea
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*
package-lock.json
yarn.lock
src/components/MapToolbar/MapToolbar_backup2.js
src/const/ApiConst.js

410
API_GeoHR_docs.md

@ -0,0 +1,410 @@
## API LOGIN
Payload Login Sales
```
[POST] https://oslog.id/geohr-api/sales/login
{
"username": null, //string
"password": null //string
}
```
## API UPLOAD IMAGE
Payload Upload Image
```
[POST] https://oslog.id/geohr-api/image/{category}/upload
//notes: gunakan form-data
Payload di form-data:
ref_id: "" //diambil dari id berdasarkan categorynya
files: tipe datanya file (ini file image1)
files: tipe datanya file (ini file image2)
files: tipe datanya file (ini file image3)
files: tipe datanya file (ini file image4, dst)
```
## API OFFICE
Search
```
[POST] https://oslog.id/geohr-api/office/monitoring
Payload
{
"paging": {"start": 0, "length": 10},
"columns": [
{"name":"name", "logic_operator": "like", "value": "", "operator": "and"}
],
"orders": {"columns": ["name"], "ascending": true}
}
Response
{
"code": 200,
"data": {
"type": "FeatureCollection",
"features": [
{
"id": "m_office.37",
"geometry_name": "the_geom",
"type": "Feature",
"properties": {
"id": "m_office.37",
"company": 5,
"name": "goro",
"employes": "goro",
"address": "goro",
"description": "goro",
"buffer_radius": 100,
"lat": -6.178889275035602,
"lon": 106.83972036828338,
"geom": "POLYGON((93.8211107249645 106.839720368283,64.5317888436193 36.1290422496288,-6.17888927503533 6.83972036828345,-76.8895673936901 36.1290422496285,-106.178889275036 106.839720368283,-76.8895673936905 177.550398486938,-6.17888927503596 206.839720368283,64.5317888436189 177.550398486939,93.8211107249645 106.839720368283))",
"created_by": "@system",
"created_date": "2021-06-15T13:54:24.157516Z",
"modified_by": "@system",
"modified_date": "2021-06-15T13:54:24.157516Z",
"join": {
"": ""
}
},
"geometry": {
"type": "Point",
"coordinates": [
106.83972036828338,
-6.178889275035602
]
}
},
{
"id": "m_office.36",
"geometry_name": "the_geom",
"type": "Feature",
"properties": {
"id": "m_office.36",
"company": 1,
"name": "tori",
"employes": "tori",
"address": "toritori",
"description": "toriaja",
"buffer_radius": 100,
"lat": -5.992300230787033,
"lon": 106.0353342769051,
"geom": "POLYGON((94.0076997692131 106.035334276905,64.7183778878679 35.3246561582504,-5.99230023078677 6.03533427690506,-76.7029783494415 35.3246561582501,-105.992300230787 106.035334276905,-76.702978349442 176.74601239556,-5.99230023078739 206.035334276905,64.7183778878674 176.74601239556,94.0076997692131 106.035334276905))",
"created_by": "@system",
"created_date": "2021-06-15T13:20:33.590436Z",
"modified_by": "@system",
"modified_date": "2021-06-15T13:52:05.91823Z",
"join": {
"": ""
}
},
"geometry": {
"type": "Point",
"coordinates": [
106.0353342769051,
-5.992300230787033
]
}
}
]
},
"executionTime": "2.122619ms",
"message": "OK",
"totalRecord": 2
}
```
Payload Add/Edit Office
```
[POST] https://oslog.id/geohr-api/office/add
[PUT] https://oslog.id/geohr-api/office/{id:[0-9]+}/edit
{
"company": null, //int
"name": null, //string
"employes": null, //string
"address": null, //string
"description": null, //string
"geom": null //string
}
```
## API CUSTOMER
Monitoring
```
[POST] https://oslog.id/geohr-api/customer/monitoring
{
"paging": {"start": 0, "length": 10},
"columns": [
{"name":"name", "logic_operator": "like", "value": "", "operator": "and"}
],
"orders": {"columns": ["name"], "ascending": true}
}
```
## API SALES
Search
```
[POST] https://oslog.id/geohr-api/sales/monitoring
Payload
{
"paging": {"start": 0, "length": 10},
"columns": [
{"name":"name", "logic_operator": "like", "value": "", "operator": "and", "table_name": "m_group_sales"}
],
"joins": [
{"name": "group_sales", "column_results": ["name", "description"]}
],
"orders": {"columns": ["name"], "ascending": true}
}
Response
{
"code": 200,
"data": {
"type": "FeatureCollection",
"features": [
{
"id": "m_sales.1",
"geometry_name": "the_geom",
"type": "Feature",
"properties": {
"id": "m_sales.1",
"group_sales": 7,
"username": "ibnuh",
"password": "7f2ababa423061c509f4923dd04b6cf1",
"session_login": "5459aff0-82c9-40bb-a34e-e6278fd9c173",
"name": "ibnu hamdani",
"phone_number": "083823134569",
"email": "ibnuhamdani234@gmail.com",
"address": "jl tenjo bogor",
"achieve": null,
"type_sales": null,
"lat": -6.2622531,
"lon": 106.7881649,
"created_by": "admin",
"created_date": "2021-06-15T03:35:32.852925Z",
"modified_by": "admin",
"modified_date": "2021-06-15T03:35:32.852925Z",
"join": {
"group_sales_description": "Group Sales Wilayah Kebayoran baru",
"group_sales_name": "Kebayoran Baru"
}
},
"geometry": {
"type": "Point",
"coordinates": [
106.7881649,
-6.2622531
]
}
}
]
},
"executionTime": "1.916764ms",
"message": "OK",
"totalRecord": 1
}
```
Payload Add/Edit Sales
```
[POST] https://oslog.id/geohr-api/sales/add
[PUT] https://oslog.id/geohr-api/sales/{id:[0-9]+}/edit
{
"group_sales": null, //int
"username": null, //string
"password": null, //string
"name": null, //string
"phone_number": null, //string
"email": null, //string
"address": null, //string
"image": null //string
}
```
## API GROUP SALES
Search
```
[POST] https://oslog.id/geohr-api/group-sales/search
{
"paging": {"start": 0, "length": 10},
"columns": [
{"name":"name", "logic_operator": "like", "value": "", "operator": "and"}
],
"orders": {"columns": ["name"], "ascending": true}
}
```
Payload Add/Edit Group Sales
```
[POST] https://oslog.id/geohr-api/group-sales/add
[PUT] https://oslog.id/geohr-api/group-sales/{id:[0-9]+}/edit
{
"name": null, //string
"description": null //string
}
```
## API WAYPOINT SALES
Search
```
[POST] https://oslog.id/geohr-api/waypoint-sales/monitoring?salesId=1
Payload
{
"paging": {"start": 0, "length": -1},
"columns": [
{"name":"wptime", "logic_operator": "range", "value": "2021-06-15 00:00:00", "value1": "2021-06-15 23:59:59", "operator": "and"}
],
"orders": {"columns": ["wptime"], "ascending": true}
}
```
Example Response (if waypoint is available)
```
{
"code": 200,
"data": {
"type": "FeatureCollection",
"features": [
{
"id": "m_sales.1",
"geometry_name": "the_geom",
"type": "Feature",
"properties": {
"id": "m_sales.1",
"group_sales": 7,
"username": "ibnuh",
"password": "7f2ababa423061c509f4923dd04b6cf1",
"session_login": "a5b5dff4-a7af-475c-9eb8-13f234d05472",
"name": "ibnu hamdani",
"phone_number": "083823134569",
"email": "ibnuhamdani234@gmail.com",
"address": "jl tenjo bogor",
"achieve": null,
"type_sales": "BTB",
"lat": -6.2623094,
"lon": 106.7880976,
"created_by": "admin",
"created_date": "2021-06-15T03:35:32.852925Z",
"modified_by": "@system",
"modified_date": "2021-06-16T07:24:31.227968Z",
"join": {
"group_sales_description": "Group Sales Wilayah Kebayoran baru",
"group_sales_name": "Kebayoran Baru"
}
},
"geometry": {
"type": "LineString",
"coordinates": [
[
106.7881649,
-6.2622531
],
...,
[
106.7881603,
-6.2622923
]
]
}
}
]
},
"executionTime": "6.957314ms",
"message": "OK",
"totalRecord": 1
}
```
Example Response (if waypoint is unavailable)
```
{
"code": 200,
"data": {
"type": "FeatureCollection",
"features": [
{
"id": "m_sales.2",
"geometry_name": "the_geom",
"type": "Feature",
"properties": {
"id": "m_sales.2",
"group_sales": 25,
"username": "jono",
"password": "jono123",
"session_login": null,
"name": "jono",
"phone_number": "0983838484",
"email": "jono@gmail.com",
"address": "jonoooo",
"achieve": null,
"type_sales": "BTB",
"lat": null,
"lon": null,
"created_by": "@system",
"created_date": "2021-06-16T04:06:23.743462Z",
"modified_by": "@system",
"modified_date": "2021-06-16T07:24:21.725833Z",
"join": {
"group_sales_description": "Group Sales Wilayah Cilandak",
"group_sales_name": "Cilandak"
}
},
"geometry": {
"type": "LineString",
"coordinates": []
}
}
]
},
"executionTime": "2.73392ms",
"message": "OK",
"totalRecord": 0
}
```
Payload Add Waypoint Sales
```
[POST] https://oslog.id/geohr-api/waypoint-sales/add
{
"sales": null, //int
"lat": null, //float
"lon": null, //float
"wptime": null, //time now
"speed": null, //int
"angle": null, //float
"satelite": null, //int
}
```
## API DAILY INFO
Response (still dummy)
```
{
"code":200,
"data": {
"at_trip":{"total": 50, "id": [1, 2, 25]},
"at_customer":"20",
"at_office":"30",
"present": "100",
"absent":"10",
"at_time":"2021-06-16T07:16:03.509928Z"
},
"executionTime":"1.494754ms",
"message":"OK"
}
```

476
CHANGELOG.md

@ -0,0 +1,476 @@
## [CoreUI](https://coreui.io/) for [react](./REACT.md) changelog
##### `v2.6.0`
- move to `reactstrap v8`. Breaking changes and deprecations, see: https://github.com/reactstrap/reactstrap/blob/master/CHANGELOG.md#800-2019-04-03
- fix(DefaultHeader): replace `AppHeaderDropdown` with `UncontrolledDropdown`
- refactor: add ie polyfills
###### dependencies update
- update: `@coreui/coreui` to `^2.1.12`
- update: `@coreui/coreui-plugin-chartjs-custom-tooltips` to `^1.3.1`
- update: `@coreui/react` to `^2.5.1`
- update: `core-js` to `^3.1.4`
- update: `enzyme` to `^3.10.0`
- update: `enzyme-adapter-react-16` to `^1.14.0`
- update: `react-router-config` to `^5.0.1`
- update: `react-router-dom` to `^5.0.1`
- update: `reactstrap` to `^8.0.0`
##### `v2.5.0`
- release for use with:
- react-router-dom `~5.0.0`
- @coreui/react `~2.5.0`
###### dependencies update
- update: `@coreui/react` to `~2.5.0`
- update: `react-router-config` to `^5.0.0`
- update: `react-router-dom` to `^5.0.0`
It turns out this is not such a breaking change, as it seemed at a glance.
Just update dependencies and you're good.
#### _migration guide v2.1 -> v2.5_ :boom:
- update `dependencies` in `package.json`
- [ ] `@coreui/react` to `~2.5.0`
- [ ] `react-router-dom` to `^5.0.0`
- [ ] `react-router-config` to `^5.0.0`
<del>
__BREAKING CHANGES__ :boom:
- use React Router `v5`
- drop 'Breadcrumb' in favour of `Breadcrumb2`
- drop 'SidebarNav' in favour of `SidebarNav2`
- __Breadcrumb2__: **mandatory** prop `router` 💥 see > [Breadcrumb](./src/Breadcrumb.md)
- __SidebarNav2__: **mandatory** prop `router` 💥 see > [SidebarNav](./src/SidebarNav.md)
React Router v5 uses the new React Context API, which is incompatible with version used in 4.3.
That's a breaking change. With a raw upgrade to v5, you can encounter an error message: `You should not render a <Route> outside a <Router>` or `You should not use <Link> outside a <Router>` etc... It means that Route, Link etc, can't find the correct context object because `Breadcrumb` and `SidebarNav` components have their own context object.
It's important to use the same instance of the `react-router-dom v5` library with template and coreui components. `@coreui/react` version `2.5.0` moves react-router-dom form dependencies to peerDependecies and takes the same library/module from the template/app instead. We have to pass `router` module object as a prop to `<AppSidebarNav>` and `<AppBreadcrumb>`
#### _migration guide v2.1 -> v2.5_ :boom:
1. update `dependencies` in `package.json`
- [ ] `@coreui/react` to `~2.5.0`
- [ ] `react-router-dom` to `^5.0.0`
- [ ] `react-router-config` to `^5.0.0`
2. modify `DefaultLayout.js`
- [ ] import react-router-dom module as an object
```
import * as router from 'react-router-dom';
```
- [ ] import new versions of components `AppBreadcrumb2` and `AppSidebarNav2` (alias is optional, just keep consistency with markup)
```jsx
import {
...
AppBreadcrumb2 as AppBreadcrumb,
AppSidebarNav2 as AppSidebarNav
...
} from '@coreui/react';
```
- [ ] inject `router` object as a prop to `<AppSidebarNav>` and `<AppBreadcrumb>`
```html
<AppSidebarNav navConfig={navigation} {...this.props} router={router}/>
```
```html
<AppBreadcrumb appRoutes={routes} router={router}/>
```
</del>
---
##### `v2.1.7`
- maintenance release for use with:
- react-router `v4.3.x`
- reactstrap `v7.x`
- @coreui/react `~2.1.7`
- chore: add `package-lock.json` with updated `tar` dependency
- chore: fix `test:cov` script
- fix(Popovers): add `trigger="legacy" delay={0}` (breaking change in reactstrap)
###### dependencies update
- update: `@coreui/react` to `~2.1.7`
- update: `@coreui/coreui-plugin-chartjs-custom-tooltips` to `^1.3.0`
- update: `enzyme-adapter-react-16` to `^1.13.0`
- update: `node-sass` to `^4.12.0`
- update: `react` to `^16.8.6`
- update: `react-app-polyfill` to `^1.0.1`
- update: `react-chartjs-2` to `^2.7.6`
- update: `react-dom` to `^16.8.6`
- update: `react-test-renderer` to `^16.8.6`
- update: `react-scripts` to `^3.0.1`
##### `v2.1.6`
- fix(App): remove redundant react-loadable - thanks @sergeyt
- fix(routes) remove circular dependency - thanks @sergeyt
- refactor(App): change to render in Route
- fix(routes): add Home to routes - breadcrumb issue
- refactor(DefaultHeader): move to ReactRouter `NavLink`
- refactor(Forms): move to `InputGroupButtonDropdown` where applicable
###### dependencies update
- update: `@coreui/coreui` to `^2.1.9`
- update: `@coreui/react` to `~2.1.5`
- update: `chart.js` to `^2.8.0`
- update: `enzyme-adapter-react-16` to `^1.11.2`
- update: `react` to `^16.8.5`
- update: `react-app-polyfill` to `^0.2.2`
- update: `react-dom` to `^16.8.5`
- update: `react-router-config` to `^4.4.0-beta.8`
- update: `react-router-dom` to `~4.3.1`
- update: `react-test-renderer` to `^16.8.5`
- update: `react-scripts` to `^2.1.8`
##### `v2.1.5`
- fix: iOS 9 Safari sidebar toggle force issue `@coreui/react@2.1.5`
###### dependencies update
- update: `@coreui/react` to `^2.1.5`
- update: `enzyme-adapter-react-16` to `^1.10.0`
- update: `flag-icon-css` to `^3.3.0`
- update: `react` to `^16.8.4`
- update: `react-dom` to `^16.8.4`
- update: `react-test-renderer` to `^16.8.4`
##### `v2.1.4`
- maintenance release: fixes #151 #145
###### dependencies update
- update: `@coreui/coreui` to `^2.1.7`
- update: `@coreui/react` to `^2.1.4`
- update: `bootstrap` to `^4.3.1`
- update: `core-js` to `^2.6.5`
- update: `enzyme` to `^3.9.0`
- update: `enzyme-adapter-react-16` to `^1.9.1`
- update: `prop-types` to `^15.7.2`
- update: `react` to `^16.8.2`
- update: `react-app-polyfill` to `^0.2.1`
- update: `react-dom` to `^16.8.2`
- update: `react-test-renderer` to `^16.8.2`
- update: `reactstrap` to `^7.1.0`
- update: `react-scripts` to `2.1.5`
##### `v2.1.3`
- fix(Collapse): add `mb-0` to accordion cards
- fix(ButtonGroups): misplaced dropdownOpen
- chore: update `@coreui/coreui` to `^2.1.5`
- chore: update `@coreui/react` to `^2.1.3`
- chore: update `bootstrap` to `^4.2.1`
- chore: update `core-js` to `^2.6.1`
- chore: update `enzyme` to `^3.8.0`
- chore: update `enzyme-adapter-react-16` to `^1.7.1`
- chore: update `node-sass` to `^4.11.0`
- chore: update `react` to `^16.7.0`
- chore: update `react-app-polyfill` to `^0.2.0`
- chore: update `react-chartjs-2` to `^2.7.4`
- chore: update `react-dom` to `^16.7.0`
- chore: update `react-test-renderer` to `^16.7.0`
- chore: update `reactstrap` to `^7.0.2`
- chore: update `react-scripts` to `2.1.3`
##### `v2.1.2`
- fix(scss): floating footer ie11 issue
- chore: update `@coreui/react` to `^2.1.1`
##### `v2.1.1`
- refactor(App.js): code splitting with `react-loadable` (waiting for release of `react-router-dom`)
- refactor(routes.js): code splitting with `React.lazy`, remove `react-loadable`
- refactor(DefaultLayout): code splitting with `React.lazy` Aside, Footer, Header, routes
- refactor(Dashboard): tweak lazy and Suspense for Widget03
- refactor(Login): add router link to `Register` button
- refactor(Register): add margins to social-media buttons
- chore: disable eslint warning for href="#" attribute
- chore: update `@coreui/coreui` to `^2.1.1`
- chore: update `enzyme-adapter-react-16` to `1.7.0`
- chore: update `react` to `16.6.3`
- chore: update `react-dom` to `16.6.3`
- chore: update `react-test-renderer` to `16.6.3`
##### `v2.1.0`
- feat(SidebarNav): navLink `attributes` - optional JS object with valid JS API naming:
- valid attributes: `rel`, `target`, `hidden`, `disabled`, etc...
- starting with `@coreui/coreui`, `@coreui/react` version `2.1.0` and up
- closes #106
- item example(`./src/_nav.js`):
```js
[
{
name: 'Disabled',
url: '/disabled',
icon: 'icon-ban',
attributes: { disabled: true },
},
{
name: 'Try CoreUI PRO',
url: 'https://coreui.io/pro/react/',
icon: 'cui-layers icons',
variant: 'danger',
attributes: { target: '_blank', rel: "noopener" },
}
]
```
- fix(Cards): `card-header-actions` added to `CardHeader` for `rtl` support
- feat(Dashboard): new `Suspense` example with Widget03
- chore: update `@coreui/coreui` to `2.1.0`
- chore: update `@coreui/react` to `2.1.0`
- chore: update `node-sass` to `4.10.0`
- chore: update `react` to `16.6.1`
- chore: update `react-dom` to `16.6.1`
- chore: update `react-test-renderer` to `16.6.1`
##### `v2.0.14`
- chore: update `@coreui/coreui` to `2.0.25`
- chore: update `chart.js` to `2.7.3`
- chore: update `flag-icon-css` to `3.2.1`
- chore: update `node-sass` to `4.9.4`
- chore: update `react` to `16.6.0`
- chore: update `react-dom` to `16.6.0`
- chore: update `react-router-config` to `4.4.0-beta.6`
- chore: update `react-test-renderer` to `16.6.0`
- chore: update `react-scripts` to `2.1.1`
##### `v2.0.13`
- refactor: migration to [Create React App 2.0](https://reactjs.org/blog/2018/10/01/create-react-app-v2.html) cleanup
- cleanup `package.json` scripts
- remove `babel-jest` dependency
- remove `node-sass-chokidar` dependency
- remove `npm-run-all` dependency
- move `App.js` import styles to `App.scss`
- replace imports from `node_modules/` with `~` prefix
- chore: remove unused `src/scss/vendors/charts.js/` directory
- chore: update `@coreui/coreui` to `^2.0.15`
- chore: update `@coreui/react` to `^2.0.9`
##### `v2.0.12`
fixes some issues with `rtl`, `ie11`, `sidebar-minimized` behaviour and `aside` responsiveness
- fix(DefaultAside): `ListGroup` with `tag="div"` works better with `rtl`
- fix(DefaultLayout): `AppAside` remove deprecated `hidden` prop
- chore: update `@coreui/react` to `^2.0.8`
- chore: update `reactsrtrap` to `^6.5.0`
- chore: update `react-scripts` to `^2.0.4`
- chore: `enzyme` to `3.7.0`
- chore: `enzyme-adapter-react-16` to `1.6.0`
##### `v2.0.11`
- chore: update `@coreui/react` to `^2.0.7`
- chore: migration to [Create React App 2.0](https://reactjs.org/blog/2018/10/01/create-react-app-v2.html)
- chore: update `react-scripts` to `^2.0.3`
- chore: update `node-sass-chokidar` to `^1.3.3`
- chore: add `node-sass v4.9.3`
- chore: add `react-app-polyfill v0.1.3`
- chore: add `eslintConfig` in `package.json`
- chore: add `browserslist` in `package.json`
- chore: update `manifest.json`
- refactor(index.js): add `react-app-polyfill` for `ie9-11` support
- refactor(index.js): migration to `serviceWorker.js`
###### Migrating from CRA 1.x to 2.x:
affected files:
- `package.json` -> dependencies update
- `src/index.js` -> move to `serviceWorker`, add `react-app-polyfill` for `ie9-11` support when needed
In most cases bumping the `react-scripts` version in `package.json` and running `npm install` in this folder should be enough, but it’s good to consult the [changelog](https://github.com/facebook/create-react-app/blob/master/CHANGELOG.md#migrating-from-1x-to-203) for potential breaking changes.
---
##### `v2.0.10`
- chore: update `@coreui/coreui` to `^2.0.14`
- chore: update `@coreui/react` to `^2.0.6`
- chore: update `enzyme` to `^3.6.0`
- chore: update `enzyme-adapter-react-16` to `^1.5.0`
- chore: update `flag-icon-css` to `^3.2.0`
- chore: update `react` to `^16.5.2`
- chore: update `react-dom` to `^16.5.2`
- chore: update `react-router-config` to `^4.4.0-beta.1`
- chore: update `react-test-renderer` to `^16.5.2`
- chore: update `babel-jest` to `^23.6.0`
##### `v2.0.9`
- chore: update `@coreui/icons` to `0.3.0`
- refactor(CoreUIIcons): move to `@coreui/icons v0.3.0`
- chore: update `enzyme` to `3.5.0`
- chore: update `enzyme-adapter-react-16` to `1.3.1`
- chore: update `react-loadable` to `5.5.0`
- chore: update `reactstrap` to `6.4.0`
- chore: update `react-scripts` to `1.1.5`
##### `v2.0.8`
- fix(User): add missing unique key prop
- fix(Login): add missing form and autoComplete
- fix(Register): add missing form and autoComplete
- chore: update `@coreui/react` to `2.0.5`
- chore: update `bootstrap` to `4.1.3`
- chore: update `reactstrap` to `6.3.1`
- chore: update `babel-jest` to `23.4.2`
##### `v2.0.5`
- feat(router): Users/User Breadcrumb example with `/users/:id`
- chore: update `@coreui/react` to `2.0.4`,
- chore: update `prop-types` to `15.6.2`
- chore: update `react` to `16.4.1`
- chore: update `react-dom` to `16.4.1`
- chore: update `react-test-renderer` to `16.4.1`
- chore: update `npm-run-all` to `4.1.3`
- chore: add `.env` file
##### `v2.0.4`
- feat(Forms): FormFeedback valid, toggleFade
- refactor(Cards): toggleFade
- chore: update `@coreui/coreui` to `2.0.2`,
- chore: update `@coreui/react` to `2.0.1`,
- chore: update `classnames` to `2.2.6`,
- chore: update `core-js` to `2.5.7`,
- chore: update `react` to `16.4.0`,
- chore: update `react-dom` to `16.4.0`,
- chore: update `react-router-dom` to `4.3.1`,
- chore: update `react-test-renderer` to `16.4.0`,
- chore: update `reactstrap` to `6.1.0`,
- chore: update `babel-jest` to `23.0.1`,
##### `v2.0.3`
- refactor: disable `ServiceWorker` by default
- fix(routes): mismatched `SimpleLineIcons` dynamic import
- refactor: CoreUI Icons `v0.2.0`
- chore: update`babel-jest` to `v22.4.4`
##### `v2.0.2`
- chore: update `@coreui/react` to `v2.0.0`,
##### `v2.0.1`
- refactor: code splitting via dynamic import
- refactor: switches view rearrange
- fix: update component names in package.json
- chore: update `node-sass-chokidar` to `v1.3.0`
- chore(release): dependencies update
##### `v2.0.0-rc.1`
- feat: new CoreUI Icons set
##### `v2.0.0-beta.2`
- feat: CoreUI custom tooltips plugin for chart.js
##### `v2.0.0-beta.1`
- refactor(Switches): move to AppSwitch component
- fix: typo
##### `v2.0.0-beta`
- update to `@coreui/react: ^2.0.0-beta`
##### `v2.0.0-alpha.3`
- refactor(Colors): view layout, minor temp tweaks
- refactor(FullAside): - ListGroup (deprecate callout)
- refactor(Full*): containers minor fixes
- refactor(Dropdowns): minor fixes
- refactor(Forms): `card-header-actions`
- feat(Forms): `<Input type="date">`
- feat(Forms): `FormFeedback`
- feat(Collapses): Accordion, Custom Accordion
- feat(ListGroup): with TabPanes
- refactor(PaginationItem): `tag="button"`
- refactor(BrandButtons): spacing
- refactor:(Buttons): view layout
##### `v2.0.0-alpha.2`
- refactor: FullHeader `<AppHeaderDropdown direction="down">` (required prop `direction`)
- refactor: ButtonDropdowns `<Dropdown direction="up">` (deprecate 'dropup')
- refactor: Dashboard legend badge pill
- refactor: SocialButtons to BrandButtons `btn-brand`
- refactor: Buttons spacing `mr-1`
- update: reactstrap to `5.0.0`
- update: react, react-dom to `16.3.1`
- update: node-sass-chokidar to `1.1.0`
- update: prop-types to `15.5.8`
- update: react-scripts to `1.1.4`
##### `v2.0.0-alpha.1`
- refactor: separation of concerns - (CoreUI template vs CoreUI components) prepare to use CoreUI as dependency
- refactor: project structure change
- refactor: moved to [Create-React-App](CRA.md)
- chore: moved to [Semantic Versioning](https://semver.org/)
##### `v1.0.10`
- refactor: `<InputGroupAddon addonType="prepend">`
- refactor: `<InputGroupAddon addonType="append">`
- refactor: `<InputGroupText>`
- refactor: remove `<InputGroupButton>`
- update: reactstrap to `5.0.0-beta`
- update: dependencies
###### `v1.0.9`
- refactor: Sidebar structure change
###### `v1.0.8`
- refactor: Dashboard radio buttons, new `onRadioBtnClick()` method
- update: react to `16.2.0`
- update: Bootstrap `4.0.0-beta.3`
- update: dependencies
- feature: some Bootstrap4 components added
- fix: rollback to webpack-dev-server `2.9.7`
- temp tweaks(b4 beta3): `InputGroupAddon` and `InputGroupButton`
- refactor(checkboxes, radios): temp tweaks
- feat: mobile sidebar link click closes the sidebar
- fix: .nav-tabs .nav-link `cursor: pointer`
###### `v1.0.6`
- update: react to `^16.1.1`
- update: reactstrap to `^5.0.0-alpha.4`
- refactor: deprecated reactstrap `NavDropdown` change to `Dropdown` with `nav` prop
- refactor: use prop `bsSize` instead of the `size` to bootstrap's input sizing
- update: dependencies
###### `v1.0.5`
- feature: Sidebar add divider.class
- refactor: Sidebar
- moved to react: `^16.1.0`
- chore: dependencies update
###### `v1.0.4`
- refactor: scss
###### `v1.0.3`
- update: bootstrap to `4.0.0-beta.2`
###### `v1.0.2`
- `HeaderDropdown` component example extracted out of `Header`
###### `v1.0.1`
- moved to react: `^16.0.0`
- moved to reactstrap: `^5.0.0-alpha.3`
- moved to react-text-mask-hoc: `^0.10.4`
- moved from deprecated CardBlock to `CardBody` reactstrap component
- moved to `NavDropdown` in `Header` component
- fix for app-header navbar-nav dropdown-menu-right
- fix typo in Tables component PaginationItem
###### `v1.0.0`
- Sidebar component:
- item with optional class (_nav.js)
- nav link with optional variant (_nav.js)
- external urls allowed (_nav.js)
- optional SidebarFooter, SidebarHeader, SidebarForm components
- SidebarMinimizer component
- .brand-minimized
- .sidebar-minimized,
- Header component - sidebarMinimize
- react-transition-group downgrade to v1 : (modals and alerts reactstrap:v4.8 issue)
###### `2017.08.24`
- webpack.config env.prod
- Dashboard .dropdown-menu-right temp.scss hotfix (full)
- callout.scss .chart-wrapper hotfix (full)
###### `2017.08.11`
- Bootstrap 4 beta
- Dashboard component (full):
- line chart for social box
- sparkline chart for callout
###### `2017.08.01`
- Sidebar component:
- title item with optional wrapper and class (_nav.js)
- nav link item with optional badge
- code refactoring
###### `2017.07.31`
- moved to [reactstrap](https://reactstrap.github.io/)
- moved to [webpack](https://webpack.js.org/) (dropping gulp)
- data driven Sidebar component (_nav.js)

172
CONTRIBUTING.md

@ -0,0 +1,172 @@
# Contributing to CoreUI Free React Admin Template
Looking to contribute something to CoreUI Free React Admin Template? **Here's how you can help.**
Please take a moment to review this document in order to make the contribution process easy and effective for everyone involved.
Following these guidelines helps to communicate that you respect the time of the developers managing and developing this open source project. In return, they should reciprocate that respect in addressing your issue or assessing patches and features.
## Using the issue tracker
The [issue tracker](https://github.com/coreui/coreui-free-react-admin-template/issues) is the preferred channel for [bug reports](#bug-reports), [features requests](#feature-requests) and [submitting pull requests](#pull-requests), but please respect the following restrictions:
* Please **do not** use the issue tracker for personal support requests.
* Please **do not** post comments consisting solely of "+1" or ":thumbsup:".
Use [GitHub's "reactions" feature](https://github.com/blog/2119-add-reactions-to-pull-requests-issues-and-comments)
instead.
* Please **do not** open issues or pull requests regarding the code in [`@coreui/coreui`](https://github.com/coreui/coreui-react) (open them in their respective repositories).
## Bug reports
A bug is a _demonstrable problem_ that is caused by the code in the repository.
Good bug reports are extremely helpful, so thanks!
Guidelines for bug reports:
0. **Validate and lint your code** &mdash; to ensure your problem isn't caused by a simple error in your own code.
1. **Use the GitHub issue search** &mdash; check if the issue has already been reported.
2. **Check if the issue has been fixed** &mdash; try to reproduce it using the latest `master` or development branch in the repository.
3. **Isolate the problem** &mdash; ideally create a [reduced test case](https://css-tricks.com/reduced-test-cases/) and a live example. [This JS Bin](http://jsbin.com/lefey/1/edit?html,output) is a helpful template.
A good bug report shouldn't leave others needing to chase you up for more
information. Please try to be as detailed as possible in your report. What is
your environment? What steps will reproduce the issue? What browser(s) and OS
experience the problem? Do other browsers show the bug differently? What
would you expect to be the outcome? All these details will help people to fix
any potential bugs.
Example:
> Short and descriptive example bug report title
>
> A summary of the issue and the browser/OS environment in which it occurs. If
> suitable, include the steps required to reproduce the bug.
>
> 1. This is the first step
> 2. This is the second step
> 3. Further steps, etc.
>
> `<url>` - a link to the reduced test case
>
> Any other information you want to share that is relevant to the issue being
> reported. This might include the lines of code that you have identified as
> causing the bug, and potential solutions (and your opinions on their
> merits).
## Feature requests
Feature requests are welcome. Before opening a feature request, please take a moment to find out whether your idea
fits with the scope and aims of the project. It's up to *you* to make a strong
case to convince the project's developers of the merits of this feature. Please
provide as much detail and context as possible.
## Pull requests
Good pull requests—patches, improvements, new features—are a fantastic
help. They should remain focused in scope and avoid containing unrelated
commits.
**Please ask first** before embarking on any significant pull request (e.g.
implementing features, refactoring code, porting to a different language),
otherwise you risk spending a lot of time working on something that the
project's developers might not want to merge into the project.
Adhering to the following process is the best way to get your work
included in the project:
1. [Fork](https://help.github.com/fork-a-repo/) the project, clone your fork,
and configure the remotes:
```bash
# Clone your fork of the repo into the current directory
git clone https://github.com/<your-username>/free-react-admin-template.git
# Navigate to the newly cloned directory
cd free-react-admin-template
# Assign the original repo to a remote called "upstream"
git remote add upstream https://github.com/coreui/coreui-free-react-admin-template.git
```
2. If you cloned a while ago, get the latest changes from upstream:
```bash
git checkout master
git pull upstream master
```
3. Create a new topic branch (off the main project development branch) to
contain your feature, change, or fix:
```bash
git checkout -b <topic-branch-name>
```
4. Commit your changes in logical chunks. Please adhere to these [git commit
message guidelines](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html)
or your code is unlikely to be merged into the main project. Use Git's
[interactive rebase](https://help.github.com/articles/interactive-rebase)
feature to tidy up your commits before making them public.
5. Locally merge (or rebase) the upstream development branch into your topic branch:
```bash
git pull [--rebase] upstream master
```
6. Push your topic branch up to your fork:
```bash
git push origin <topic-branch-name>
```
7. [Open a Pull Request](https://help.github.com/articles/using-pull-requests/) with a clear title and description against the `master` branch.
**IMPORTANT**: By submitting a patch, you agree to allow the project owners to license your work under the terms of the [MIT License](LICENSE).
### Semantic Git commit messages
Inspired by Sparkbox's awesome article on [semantic commit messages](http://seesparkbox.com/foundry/semantic_commit_messages). Please use following commit message format.
* chore (updating npm tasks etc; no production code change) -> ```git test -m 'chore: commit-message-here'```
* docs (changes to documentation) -> ```git commit -m 'docs: commit-message-here'```
* feat (new feature) -> ```git commit -m 'feat: commit-message-here'```
* fix (bug fix) -> ```git commit -m 'fix: commit-message-here'```
* refactor (refactoring production code) -> ```git commit -m 'refactor: commit-message-here'```
* style (formatting, missing semi colons, etc; no code change) -> ```git commit -m 'style: commit-message-here'```
* test (adding missing tests, refactoring tests; no production code change) -> ```git test -m 'refactor: commit-message-here'```
## Code guidelines
### HTML
[Adhere to the Code Guide.](http://codeguide.co/#html)
- Use tags and elements appropriate for an HTML5 doctype (e.g., self-closing tags).
- Use CDNs and HTTPS for third-party JS when possible. We don't use protocol-relative URLs in this case because they break when viewing the page locally via `file://`.
- Use [WAI-ARIA](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA) attributes in documentation examples to promote accessibility.
### CSS
[Adhere to the Code Guide.](http://codeguide.co/#css)
- When feasible, default color palettes should comply with [WCAG color contrast guidelines](http://www.w3.org/TR/WCAG20/#visual-audio-contrast).
- Except in rare cases, don't remove default `:focus` styles (via e.g. `outline: none;`) without providing alternative styles. See [this A11Y Project post](http://a11yproject.com/posts/never-remove-css-outlines) for more details.
### JS
- No semicolons (in client-side JS)
- 2 spaces (no tabs)
- strict mode
- "Attractive"
- Don't use [jQuery event alias convenience methods](https://github.com/jquery/jquery/blob/master/src/event/alias.js) (such as `$().focus()`). Instead, use [`$().trigger(eventType, ...)`](http://api.jquery.com/trigger/) or [`$().on(eventType, ...)`](http://api.jquery.com/on/), depending on whether you're firing an event or listening for an event. (For example, `$().trigger('focus')` or `$().on('focus', function (event) { /* handle focus event */ })`) We do this to be compatible with custom builds of jQuery where the event aliases module has been excluded.
## License
By contributing your code, you agree to license your contribution under the [MIT License](LICENSE).

2473
CRA.md

File diff suppressed because it is too large Load Diff

20
ISSUE_TEMPLATE.md

@ -0,0 +1,20 @@
Before opening an issue:
- [Search for duplicate or closed issues](https://github.com/coreui/coreui-free-react-admin-template/issues?utf8=%E2%9C%93&q=is%3Aissue)
- Prepare a [reduced test case](https://css-tricks.com/reduced-test-cases/) for any bugs
- Read the [contributing guidelines](https://github.com/coreui/coreui-free-react-admin-template/blob/master/CONTRIBUTING.md)
When asking general "how to" questions:
- Please do not open an issue here
When reporting a bug, include:
- Operating system and version (Windows, Mac OS X, Android, iOS, Win10 Mobile)
- Browser and version (Chrome, Firefox, Safari, IE, MS Edge, Opera 15+, Android Browser)
- Reduced test cases and potential fixes using [CodePen](https://codepen.io/) or [JS Bin](https://jsbin.com/)
When suggesting a feature, include:
- As much detail as possible for what we should add and why it's important to CoreUI Admin Template
- Relevant links to prior art, screenshots, or live demos whenever possible

21
LICENSE

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2018 creativeLabs Łukasz Holeczek.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

41
REACT.md

@ -0,0 +1,41 @@
# CoreUI React version
## Intro
This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app)
It uses Sass (with .scss). The styles are loaded at the template level with `node-sass-chokidar` css preprocessor
Dependencies are handled by **npm**.
## Directories
```
CoreUI-React#v2.0.0
├── public/ (static files)
│ ├── assets/ (assets)
│ ├── favicon.ico
│ └── index.html (html temlpate)
├── src/ (project root)
│ ├── containers/ (container source)
│ ├── scss/ (scss/css source)
│ ├── views/ (views source)
│ ├── App.js
│ ├── App.test.js
│ ├── index.js
│ ├── _nav.js (sidebar config)
│ └── routes.js (routes config)
└── package.json
```
## Usage
`npm i` - to install dependencies
## Sctipts
`npm start` for developing (it runs webpack-dev-server)
`npm run build` to run a dev build
## See also
[Create-React-App](CRA.md)
[Changelog](./CHANGELOG.md)
[Readme](./README.md)

57
README.md

@ -0,0 +1,57 @@
## GeoHR Installation
``` bash
# clone the repo
$ git clone https://git.oslog.id/iu/GeoHR-website.git
# go into app's directory
$ cd GeoHR-website
# install app's dependencies
$ npm install
# fix dependency
$ npm fix audit
# start project
$ npm start
```
## API Documentation
Here is the [API Documentation](https://git.oslog.id/iu/GeoHR-website/src/branch/master/API_GeoHR_docs.md).
## GeoHR Build to Production
``` bash
# build the project
$ npm run build
# zip the files inside build folder -> name it as build.zip
# copy the zip file to server
$ scp -rP 2001 build/build.zip dev@202.47.70.196:/var/www/html/geohr
# login to dev@202.47.70.196
$ ssh dev@202.47.70.196 -p 2001
# go to geohr folder
$ cd /var/www/html/geohr
# unzip the build.zip
$ unzip build.zip
# if prompt shown, choose [A] to replace all existing files
[dev@oscarp geohr]$ unzip build.zip
Archive: build.zip
replace favicon.ico? [y]es, [n]o, [A]ll, [N]one, [r]ename: A
inflating: favicon.ico
...
# remove build.zip file
$ rm -rf build.zip
# DONE !
# Open siopas.co.id/geohr
# Don't forget to shift+reload on browser
```

177
README_COREUI_TEMPLATE.md

@ -0,0 +1,177 @@
[![@coreui coreui](https://img.shields.io/badge/@coreui%20-coreui-lightgrey.svg?style=flat-square)](https://github.com/coreui/coreui)
[![npm package][npm-coreui-badge]][npm-coreui]
[![NPM downloads][npm-coreui-download]][npm-coreui]
[![@coreui react](https://img.shields.io/badge/@coreui%20-react-lightgrey.svg?style=flat-square)](https://github.com/coreui/react)
[![npm package][npm-coreui-react-badge]][npm-coreui-react]
[![NPM downloads][npm-coreui-react-download]][npm-coreui-react]
[npm-coreui]: https://www.npmjs.com/package/@coreui/coreui
[npm-coreui-badge]: https://img.shields.io/npm/v/@coreui/coreui.png?style=flat-square
[npm-coreui-download]: https://img.shields.io/npm/dm/@coreui/coreui.svg?style=flat-square
[npm-coreui-react]: https://www.npmjs.com/package/@coreui/react
[npm-coreui-react-badge]: https://img.shields.io/npm/v/@coreui/react.png?style=flat-square
[npm-coreui-react-download]: https://img.shields.io/npm/dm/@coreui/react.svg?style=flat-square
# CoreUI Free React Admin Template v2 [![Tweet](https://img.shields.io/twitter/url/http/shields.io.svg?style=social&logo=twitter)](https://twitter.com/intent/tweet?text=CoreUI%20-%20Free%20React%20Admin%20Template%20&url=https://coreui.io/react/&hashtags=bootstrap,admin,template,dashboard,panel,free,angular,react,vue)
Please help us on [Product Hunt](https://www.producthunt.com/posts/coreui-open-source-bootstrap-4-admin-template-with-angular-2-react-js-vue-js-support) and [Designer News](https://www.designernews.co/stories/81127). Thanks in advance!
Curious why I decided to create CoreUI? Please read this article: [Jack of all trades, master of none. Why Bootstrap Admin Templates suck.](https://medium.com/@lukaszholeczek/jack-of-all-trades-master-of-none-5ea53ef8a1f#.7eqx1bcd8)
CoreUI is an Open Source Bootstrap Admin Template. But CoreUI is not just another Admin Template. It goes way beyond hitherto admin templates thanks to transparent code and file structure. And if that's not enough, let’s just add that CoreUI consists bunch of unique features and over 1000 high quality icons.
CoreUI is based on Bootstrap 4 and offers 6 versions: [HTML5 AJAX](https://github.com/coreui/free-bootstrap-admin-template-ajax), [HTML5](https://github.com/coreui/free-angular-admin-template), [Angular 2+](https://github.com/coreui/free-angular-admin-template), [React.js](https://github.com/coreui/free-react-admin-template) & [Vue.js](https://github.com/coreui/free-vue-admin-template), [.NET Core 2](https://github.com/coreui/free-dotnet-admin-template).
CoreUI is meant to be the UX game changer. Pure & transparent code is devoid of redundant components, so the app is light enough to offer ultimate user experience. This means mobile devices also, where the navigation is just as easy and intuitive as on a desktop or laptop. The CoreUI Layout API lets you customize your project for almost any device – be it Mobile, Web or WebApp – CoreUI covers them all!
## Table of Contents
* [Versions](#versions)
* [CoreUI Pro](#coreui-pro)
* [Admin Templates built on top of CoreUI Pro](#admin-templates-built-on-top-of-coreui-pro)
* [Installation](#installation)
* [Usage](#usage)
* [What's included](#whats-included)
* [Documentation](#documentation)
* [Contributing](#contributing)
* [Versioning](#versioning)
* [Creators](#creators)
* [Community](#community)
* [Community Projects](#community-projects)
* [License](#license)
* [Support CoreUI Development](#support-coreui-development)
## Versions
* [CoreUI Free Bootstrap Admin Template](https://github.com/coreui/coreui-free-bootstrap-admin-template)
* [CoreUI Free Bootstrap Admin Template (Ajax)](https://github.com/coreui/coreui-free-bootstrap-admin-template-ajax)
* [CoreUI Free Angular 2+ Admin Template](https://github.com/coreui/coreui-free-angular-admin-template)
* 🚧 CoreUI Free .NET Core 2 Admin Template (Available Soon)
* [CoreUI Free React.js Admin Template](https://github.com/coreui/coreui-free-react-admin-template)
* [CoreUI Free Vue.js Admin Template](https://github.com/coreui/coreui-free-vue-admin-template)
## CoreUI Pro
* 💪 [CoreUI Pro Bootstrap Admin Template](https://coreui.io/pro/)
* 💪 [CoreUI Pro Bootstrap Admin Template (Ajax)](https://coreui.io/pro/)
* 💪 [CoreUI Pro Angular Admin Template](https://coreui.io/pro/angular)
* 💪 [CoreUI Pro React Admin Template](https://coreui.io/pro/react)
* 💪 [CoreUI Pro Vue Admin Template](https://coreui.io/pro/vue)
## Admin Templates built on top of CoreUI Pro
| CoreUI Pro | Prime | Root | Alba | Leaf |
| --- | --- | --- | --- | --- |
| [![CoreUI Pro React Admin Template](https://coreui.io/assets/img/example-coureui.jpg)](https://coreui.io/pro/react/) | [![Prime React Admin Template](https://genesisui.com/assets/img/templates/prime1280.jpg)](https://genesisui.com/admin-templates/reactjs/prime/?support=1) | [![Root React Admin Template](https://genesisui.com/assets/img/templates/root1280.jpg)](https://genesisui.com/admin-templates/reactjs/root/?support=1) | [![Alba React Admin Template](https://genesisui.com/assets/img/templates/alba1280.jpg)](https://genesisui.com/admin-templates/reactjs/alba/?support=1) | [![Leaf React Admin Template](https://genesisui.com/assets/img/templates/leaf1280.jpg)](https://genesisui.com/admin-templates/reactjs/leaf/?support=1)
## Installation
``` bash
# clone the repo
$ git clone https://github.com/coreui/coreui-free-react-admin-template.git my-project
# go into app's directory
$ cd my-project
# install app's dependencies
$ npm install
```
## Create React App
This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app)
see also:
[User Guide](CRA.md)
### Basic usage
``` bash
# dev server with hot reload at http://localhost:3000
$ npm start
```
Navigate to [http://localhost:3000](http://localhost:3000). The app will automatically reload if you change any of the source files.
### Build
Run `build` to build the project. The build artifacts will be stored in the `build/` directory.
```bash
# build for production with minification
$ npm run build
```
## What's included
Within the download you'll find the following directories and files, logically grouping common assets and providing both compiled and minified variations. You'll see something like this:
```
CoreUI-React#v2.0.0
├── public/ #static files
│ ├── assets/ #assets
│ └── index.html #html template
├── src/ #project root
│ ├── containers/ #container source
│ ├── scss/ #user scss/css source
│ ├── views/ #views source
│ ├── App.js
│ ├── App.test.js
│ ├── index.js
│ ├── _nav.js #sidebar config
│ └── routes.js #routes config
└── package.json
```
## Documentation
The documentation for the CoreUI Admin Template is hosted at our website [CoreUI for React](https://coreui.io/react/)
## Contributing
Please read through our [contributing guidelines](https://github.com/coreui/coreui-free-react-admin-template/blob/master/CONTRIBUTING.md). Included are directions for opening issues, coding standards, and notes on development.
Editor preferences are available in the [editor config](https://github.com/coreui/coreui-free-react-admin-template/blob/master/.editorconfig) for easy use in common text editors. Read more and download plugins at <http://editorconfig.org>.
## Versioning
For transparency into our release cycle and in striving to maintain backward compatibility, CoreUI Free Admin Template is maintained under [the Semantic Versioning guidelines](http://semver.org/).
See [the Releases section of our project](https://github.com/coreui/coreui-free-react-admin-template/releases) for changelogs for each release version.
## Creators
**Łukasz Holeczek**
* <https://twitter.com/lukaszholeczek>
* <https://github.com/mrholek>
**Andrzej Kopański**
* <https://github.com/xidedix>
## Community
Get updates on CoreUI's development and chat with the project maintainers and community members.
- Follow [@core_ui on Twitter](https://twitter.com/core_ui).
- Read and subscribe to [CoreUI Blog](https://coreui.ui/blog/).
### Community Projects
Some of projects created by community but not maintained by CoreUI team.
* [NuxtJS + Vue CoreUI](https://github.com/muhibbudins/nuxt-coreui)
* [Colmena](https://github.com/colmena/colmena)
* [mvelosop/AspNetCore2CoreUI](https://github.com/mvelosop/AspNetCore2CoreUI)
## Copyright and license
copyright 2018 creativeLabs Łukasz Holeczek. Code released under [the MIT license](LICENSE).
There is only one limitation you can't can’t re-distribute the CoreUI as stock. You can’t do this if you modify the CoreUI. In past we faced some problems with persons who tried to sell CoreUI based templates.
## Support CoreUI Development
CoreUI is an MIT licensed open source project and completely free to use. However, the amount of effort needed to maintain and develop new features for the project is not sustainable without proper financial backing. You can support development by donating on [PayPal](https://www.paypal.me/holeczek), buying [CoreUI Pro Version](https://coreui.io/pro) or buying one of our [premium admin templates](https://genesisui.com/?support=1).
As of now I am exploring the possibility of working on CoreUI fulltime - if you are a business that is building core products using CoreUI, I am also open to conversations regarding custom sponsorship / consulting arrangements. Get in touch on [Twitter](https://twitter.com/lukaszholeczek).

BIN
docs/WhatsApp Image 2022-07-07 at 11.53.46 AM.jpeg

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

137
package.json

@ -0,0 +1,137 @@
{
"name": "simpro-web",
"version": "0.0.1",
"description": "Sistem Informasi Manajemen Proyek",
"author": "Ardhi",
"homepage": ".",
"copyright": "Copyright Integrasia Utama",
"license": "MIT",
"private": true,
"repository": {
"type": "http",
"url": "https://git.oslog.id/iu/simpro-website.git"
},
"dependencies": {
"@coreui/coreui": "^2.1.12",
"@coreui/coreui-plugin-chartjs-custom-tooltips": "^1.3.1",
"@coreui/icons": "0.3.0",
"@coreui/react": "^2.5.1",
"@dabeng/react-orgchart": "^1.0.0",
"@iconify/icons-ant-design": "^1.0.6",
"@iconify/icons-fa-solid": "^1.0.6",
"@iconify/icons-fe": "^1.0.3",
"@iconify/icons-geo": "^1.0.3",
"@iconify/icons-ion": "^1.0.7",
"@iconify/icons-mdi": "^1.0.57",
"@iconify/icons-simple-line-icons": "^1.0.1",
"@iconify/icons-uil": "^1.0.6",
"@iconify/react": "^1.1.1",
"@nicholasadamou/react-iframe": "^1.0.3",
"@terrestris/react-geo": "^12.0.0",
"@tinymce/tinymce-react": "^3.13.0",
"alasql": "^1.7.3",
"antd": "^4.16.13",
"axios": "^0.21.1",
"bootstrap": "^4.3.1",
"chart.js": "^2.8.0",
"chartjs-plugin-datalabels": "^1.0.0",
"chartjs-plugin-zoom": "^0.7.7",
"classnames": "^2.2.6",
"compressorjs": "^1.0.7",
"core-js": "^3.1.4",
"dhtmlx-gantt": "^7.1.7",
"dom-to-image": "^2.6.0",
"enzyme": "^3.10.0",
"enzyme-adapter-react-16": "^1.14.0",
"faker": "^6.6.6",
"flag-icon-css": "^3.3.0",
"font-awesome": "^4.7.0",
"history": "^5.2.0",
"interactjs": "^1.10.11",
"leaflet": "^1.7.1",
"leaflet-defaulticon-compatibility": "^0.1.1",
"leaflet-draw": "^1.0.4",
"moment": "^2.24.0",
"node-sass": "^4.12.0",
"numeral": "^2.0.6",
"ol": "^5.3.3",
"plotly.js": "^1.45.3",
"prop-types": "^15.7.2",
"re-resizable": "^6.9.0",
"react": "^16.14.0",
"react-app-polyfill": "^1.0.1",
"react-awesome-query-builder": "^4.3.0",
"react-bootstrap-sweetalert": "^5.1.9",
"react-bootstrap-table-next": "^3.3.3",
"react-bootstrap-table2-editor": "^1.4.0",
"react-bootstrap-table2-paginator": "^2.1.0",
"react-bootstrap-table2-toolkit": "^2.1.1",
"react-calendar-timeline": "^0.27.0",
"react-chartjs-2": "^2.7.6",
"react-color": "^2.17.3",
"react-content-loader": "^6.0.3",
"react-dom": "^16.14.0",
"react-grid-layout": "^1.2.5",
"react-leaflet": "^3.2.0",
"react-leaflet-draw": "^0.19.8",
"react-loader-spinner": "^3.1.5",
"react-notifications": "^1.7.2",
"react-openlayers": "^0.2.1",
"react-plotly.js": "^2.4.0",
"react-rnd": "^10.1.3",
"react-router-config": "^5.0.1",
"react-router-dom": "^5.0.1",
"react-select": "^4.3.1",
"react-slick": "^0.28.1",
"react-test-renderer": "^16.8.6",
"react-toastify": "^5.5.0",
"react-top-loading-bar": "^1.2.0",
"reactstrap": "^8.0.0",
"redux": "^4.0.5",
"script-case": "^1.0.0",
"simple-line-icons": "^2.4.1",
"slick-carousel": "^1.8.1",
"underscore": "^1.13.1",
"xlsx": "^0.17.0"
},
"devDependencies": {
"@babel/core": "^7.14.5",
"@faker-js/faker": "^6.0.0",
"babel-plugin-module-resolver": "^4.1.0",
"clean-webpack-plugin": "^3.0.0",
"react-scripts": "^3.0.1",
"webpack-sources": "1.0.1"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts --max_old_space_size=8096 build",
"test": "react-scripts test",
"test:cov": "npm test -- --coverage --watchAll=false",
"test:debug": "react-scripts --inspect-brk test --runInBand",
"eject": "react-scripts eject"
},
"bugs": {
"url": "https://git.oslog.id/iu/simpro-website/issues"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": [
">0.2%",
"not dead",
"not ie <= 9",
"not op_mini all"
],
"jest": {
"collectCoverageFrom": [
"src/**/*.{js,jsx}",
"!**/*index.js",
"!src/serviceWorker.js",
"!src/polyfill.js"
]
},
"engines": {
"node": ">=8.10",
"npm": ">=6"
}
}

0
public/assets/.gitkeep

BIN
public/assets/img/avatars/1.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
public/assets/img/avatars/2.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
public/assets/img/avatars/3.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
public/assets/img/avatars/4.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

BIN
public/assets/img/avatars/5.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
public/assets/img/avatars/6.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
public/assets/img/avatars/7.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

BIN
public/assets/img/avatars/8.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
public/assets/img/favicon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

BIN
public/assets/img/favicon_bmd_denpasar.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

BIN
public/assets/img/favicon_old.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

101
public/index.html

@ -0,0 +1,101 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="OSPRO">
<meta name="author" content="Integrasia Utama">
<meta name="keyword" content="OSPRO,Integrasia,OSLOG,Asset,WebGIS,Aplikasi,Tracking System">
<title>OSPRO</title>
<!--
manifest.json provides metadata used when your web app is added to the
homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
<link rel="shortcut icon" href="%PUBLIC_URL%/simpro-icon.ico">
<!-- <link rel="shortcut icon" href="%PUBLIC_URL%/favicon_bmd_denpasar.ico"> -->
<link rel="stylesheet" href="https://unpkg.com/@coreui/icons@1.0.0/css/all.min.css">
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css"
integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A=="
crossorigin="" />
<link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/material-design-iconic-font/2.2.0/css/material-design-iconic-font.min.css">
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-118965717-3"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag() {
dataLayer.push(arguments);
}
gtag('js', new Date());
// Shared ID
gtag('config', 'UA-118965717-3');
// React.js ID
gtag('config', 'UA-118965717-6');
</script>
<script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"
integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA=="
crossorigin=""></script>
</head>
<!-- BODY options, add following classes to body to change options
// Header options
1. '.header-fixed' - Fixed Header
// Brand options
1. '.brand-minimized' - Minimized brand (Only symbol)
// Sidebar options
1. '.sidebar-fixed' - Fixed Sidebar
2. '.sidebar-hidden' - Hidden Sidebar
3. '.sidebar-off-canvas' - Off Canvas Sidebar
4. '.sidebar-minimized' - Minimized Sidebar (Only icons)
5. '.sidebar-compact' - Compact Sidebar
// Aside options
1. '.aside-menu-fixed' - Fixed Aside Menu
2. '.aside-menu-hidden' - Hidden Aside Menu
3. '.aside-menu-off-canvas' - Off Canvas Aside Menu
// Breadcrumb options
1. '.breadcrumb-fixed' - Fixed Breadcrumb
// Footer options
1. '.footer-fixed' - Fixed footer
-->
<body>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<div id="root">
</div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>

15
public/manifest.json

@ -0,0 +1,15 @@
{
"short_name": "GEOHR",
"name": "GEOHR",
"icons": [
{
"src": "./assets/img/favicon.png",
"sizes": "100x100",
"type": "image/png"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}

BIN
public/simpro-icon.ico

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

46
src/App.js

@ -0,0 +1,46 @@
import React, { Component } from 'react';
import { HashRouter, Route, Switch } from 'react-router-dom';
import './App.scss';
import 'react-notifications/lib/notifications.css';
// import 'react-bootstrap-table-next/dist/react-bootstrap-table2.min.css';
// import 'react-bootstrap-table-next/dist/react-bootstrap-table-next.min.js';
// import 'react-bootstrap-table2-paginator/dist/react-bootstrap-table2-paginator.min.css';
const loading = () => <div className="animated fadeIn pt-3 text-center">Loading...</div>;
// Containers
const DefaultLayout = React.lazy(() => import('./containers/DefaultLayout'));
// Pages
const Login = React.lazy(() => import('./views/Pages/Login'));
const Register = React.lazy(() => import('./views/Pages/Register'));
const Page403 = React.lazy(() => import('./views/Pages/Page403'));
const Page404 = React.lazy(() => import('./views/Pages/Page404'));
const Page500 = React.lazy(() => import('./views/Pages/Page500'));
const SiopasMap = React.lazy(() => import('./views/Map'));
class App extends Component {
render() {
return (
<HashRouter>
<React.Suspense fallback={loading()}>
<Switch>
<Route exact path="/login" name="Login Page" render={props => <Login {...props}/>} />
{/* <Route exact path="/home" name="Home" render={props => <DefaultLayout {...props}/>} /> */}
<Route exact path="/register" name="Register Page" render={props => <Register {...props}/>} />
<Route exact path="/404" name="Page 404" render={props => <Page404 {...props}/>} />
<Route exact path="/403" name="Page 403" render={props => <Page403 {...props}/>} />
<Route exact path="/500" name="Page 500" render={props => <Page500 {...props}/>} />
<Route exact path="/map/view" name="Map" render={props => <SiopasMap {...props}/>} />
{/*<Route exact path="/layerswitcher" name="Layer Switcher" render={props => <LayerSwitcherExample {...props}/>} />*/}
{/*<Route exact path="/muidt" name="Mui Datatable Example" render={props => <MuiDatatablesExample {...props}/>} />*/}
<Route path="/" name="Home" render={props => <DefaultLayout {...props}/>} />
</Switch>
</React.Suspense>
</HashRouter>
);
}
}
export default App;

11
src/App.scss

@ -0,0 +1,11 @@
// Styles
// CoreUI Icons Set
@import '~@coreui/icons/css/coreui-icons.css';
// Import Flag Icons Set
@import '~flag-icon-css/css/flag-icon.min.css';
// Import Font Awesome Icons Set
@import '~font-awesome/css/font-awesome.min.css';
// Import Simple Line Icons Set
@import '~simple-line-icons/css/simple-line-icons.css';
// Import Main styles for this application
@import './scss/style.scss';

9
src/App.test.js

@ -0,0 +1,9 @@
import React from 'react';
import {shallow} from 'enzyme/build';
import App from './App';
it('mounts without crashing', () => {
const wrapper = shallow(<App />);
wrapper.unmount()
});

151
src/_nav.js

@ -0,0 +1,151 @@
let dashboardUrl = '';
let menu = {};
if (localStorage.getItem('u_group') === "kominfo") {
dashboardUrl = '/dashboard-kominfo';
menu = {
items: [
{
name: 'Dashboard',
url: dashboardUrl,
icon: 'icon-speedometer',
},
{
name: 'Map',
url: '/map/view',
icon: 'icon-map',
}
]
}
}
else {
dashboardUrl = '/dashboard';
menu = {
items: [
{
name: 'Dashboard',
url: dashboardUrl,
icon: 'icon-speedometer',
},
// {
// name: 'Dashboard B2C',
// url: './dashboardb2c',
// icon: 'icon-speedometer',
// },
// {
// name: 'Users',
// url: '/users',
// icon: 'icon-user',
// },
// {
// name: 'Offices',
// url: '/offices',
// icon: 'cil-home',
// },
// {
// name: 'Group Sales',
// url: '/group-sales',
// icon: 'cil-sitemap',
// },
// {
// name: 'Sales',
// url: '/sales',
// icon: 'icon-user',
// },
// {
// name: 'Office Hours',
// url: '/office-hours',
// icon: 'cil-alarm',
// },
// {
// name: 'Customer',
// url: '/customer',
// icon: 'cil-home',
// },
// {
// name: 'Layers',
// url: '/map/layers',
// icon: 'icon-layers',
// },
{
name: 'Peta',
url: '/map/view',
icon: 'icon-map',
},
// new
{
name: 'Karyawan',
url: '/karyawan',
icon: 'icon-user',
},
// {
// name: 'Divisi Karyawan',
// url: '/divisi-karyawan',
// icon: 'cil-sitemap',
// },
// {
// name: 'Jam Kerja',
// url: '/office-hours',
// icon: 'cil-alarm',
// },
{
name: 'Presensi',
url: '/presensi',
icon: 'fa fa-calendar-check-o',
},
{
name: 'Absensi',
url: '/absensi',
icon: 'fa fa-calendar-times-o'
},
{
name: 'Laporan Tugas Karyawan',
url: '/laporan-tugas-karyawan',
icon: 'cil-task',
},
// {
// name: 'Izin',
// url: '/izin',
// icon: 'cil-media-pause',
// },
// {
// name: 'Broadcast',
// url: '/broadcast',
// icon: 'cil-bullhorn',
// },
{
name: 'Tombol Darurat',
url: '/panic-button',
icon: 'fa fa-dot-circle-o ',
},
// {
// name: 'Reimbuse',
// url: '/reimbuse',
// icon: 'cil-money',
// },
// {
// name: 'Visit Customer',
// url: '/visit-customer',
// icon: 'cil-location-pin',
// },
{
name: 'Menu',
url: '/menu',
icon: 'cil-menu',
},
{
name: 'Roles',
url: '/roles',
icon: 'cil-people',
},
{
name: 'Lembur',
url: '/lembur',
icon: 'fa fa-clock-o',
},
],
};
}
export default menu;

16
src/assets/css/customscroll.css

@ -0,0 +1,16 @@
.custom-scroll::-webkit-scrollbar-track {
border-radius: 10px;
background-color: #F5F5F5;
}
.custom-scroll::-webkit-scrollbar {
width: 10px;
height: 10px;
background-color: #F5F5F5;
}
.custom-scroll::-webkit-scrollbar-thumb {
border-radius: 5px;
-webkit-box-shadow: 0 0 3px rgba(0,0,0,0.3);
background-color: #eaeaea;
}

3275
src/assets/db/bmd_denpasar_2018_27012020.sql

File diff suppressed because it is too large Load Diff

3044
src/assets/db/bmd_denpasar_27012020.sql

File diff suppressed because it is too large Load Diff

13
src/assets/docs/layer_legend.txt

@ -0,0 +1,13 @@
====================================================================================================================
Layer Legend
Author: Ardhi
Description: This documentation is an example of a guidance to know how to get a legend graphic of a layer
Created on: 29th January 2020
Full documentation here:
https://docs.geoserver.org/latest/en/user/services/wms/get_legend_graphic/index.html
I use this library: https://terrestris.github.io/react-geo/docs/latest/index.html#section-legend
====================================================================================================================
URL: http://192.168.99.110/geoserver/wms?request=GetLegendGraphic&format=image%2Fpng&width=20&height=20&layer=bmd_denpasar:test_bmd_1&transparent=true&legend_options=fontColor:0xFFFFFF;fontAntiAliasing:true;fontSize:14;fontStyle:bold;
Method: GET
Response: The image of layer symbol

208
src/assets/docs/layer_styles.txt

@ -0,0 +1,208 @@
====================================================================================================================
Layer Styles
Author: Ardhi
Description: This documentation is an example of a guidance to know how to style a layer,
a payload example using geoserver SLD file
Created on: 28th January 2020
Full documentation here:
https://docs.geoserver.org/stable/en/user/styling/index.html
https://docs.geoserver.org/stable/en/user/styling/sld/index.html
====================================================================================================================
Type: Point (using Symbolizer, ex: star)
---------------------
URL: http://192.168.99.110/geoserver/wms?SERVICE=WMS&VERSION=1.1.1&REQUEST=GetStyles&LAYERS=bmd_denpasar:test_bmd_2_point
Method: GET
Response:
<?xml version="1.0" encoding="UTF-8"?><sld:StyledLayerDescriptor xmlns="http://www.opengis.net/sld" xmlns:sld="http://www.opengis.net/sld" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" version="1.0.0">
<sld:NamedLayer>
<sld:Name>bmd_denpasar:test_bmd_2_point</sld:Name>
<sld:UserStyle>
<sld:Name>point</sld:Name>
<sld:Title>Default Point</sld:Title>
<sld:IsDefault>1</sld:IsDefault>
<sld:Abstract>A sample style that draws a point</sld:Abstract>
<sld:FeatureTypeStyle>
<sld:Name>name</sld:Name>
<sld:Rule>
<sld:Name>rule1</sld:Name>
<sld:Title>Target</sld:Title>
<sld:Abstract>A 6 pixel square with a red fill and no stroke</sld:Abstract>
<sld:PointSymbolizer>
<sld:Graphic>
<sld:Mark>
<sld:WellKnownName>star</sld:WellKnownName>
<sld:Fill>
<sld:CssParameter name="fill">#11CCF1</sld:CssParameter>
</sld:Fill>
<sld:Stroke/>
</sld:Mark>
<sld:Size>15</sld:Size>
</sld:Graphic>
</sld:PointSymbolizer>
</sld:Rule>
</sld:FeatureTypeStyle>
</sld:UserStyle>
</sld:NamedLayer>
</sld:StyledLayerDescriptor>
Type: MultiPoint (using FillColor)
---------------------
URL: http://192.168.99.110/geoserver/wms?SERVICE=WMS&VERSION=1.1.1&REQUEST=GetStyles&LAYERS=bmd_denpasar:point_tanah_sekolah0
Method: GET
Response:
<?xml version="1.0" encoding="UTF-8"?><sld:StyledLayerDescriptor xmlns="http://www.opengis.net/sld" xmlns:sld="http://www.opengis.net/sld" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" version="1.0.0">
<sld:NamedLayer>
<sld:Name>bmd_denpasar:point_tanah_sekolah0</sld:Name>
<sld:UserStyle>
<sld:Name>bmd_denpasar_point_tanah_sekolah1</sld:Name>
<sld:Title>azure square point style</sld:Title>
<sld:IsDefault>1</sld:IsDefault>
<sld:FeatureTypeStyle>
<sld:Name>name</sld:Name>
<sld:Rule>
<sld:Title>azure point</sld:Title>
<sld:PointSymbolizer>
<sld:Graphic>
<sld:Mark>
<sld:Fill>
<sld:CssParameter name="fill">#0033cc</sld:CssParameter>
</sld:Fill>
</sld:Mark>
<sld:Size>6</sld:Size>
</sld:Graphic>
</sld:PointSymbolizer>
</sld:Rule>
</sld:FeatureTypeStyle>
</sld:UserStyle>
</sld:NamedLayer>
</sld:StyledLayerDescriptor>
Type: LineString
---------------------
URL: http://192.168.99.110/geoserver/wms?SERVICE=WMS&VERSION=1.1.1&REQUEST=GetStyles&LAYERS=bmd_denpasar:test_bmd_line_1
Method: GET
Response:
<?xml version="1.0" encoding="UTF-8"?><sld:StyledLayerDescriptor xmlns="http://www.opengis.net/sld" xmlns:sld="http://www.opengis.net/sld" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" version="1.0.0">
<sld:NamedLayer>
<sld:Name>bmd_denpasar:test_bmd_line_1</sld:Name>
<sld:UserStyle>
<sld:Name>line</sld:Name>
<sld:Title>Default Line</sld:Title>
<sld:IsDefault>1</sld:IsDefault>
<sld:Abstract>A sample style that draws a line</sld:Abstract>
<sld:FeatureTypeStyle>
<sld:Name>name</sld:Name>
<sld:Rule>
<sld:Name>rule1</sld:Name>
<sld:Title>Blue Line</sld:Title>
<sld:Abstract>A solid blue line with a 1 pixel width</sld:Abstract>
<sld:LineSymbolizer>
<sld:Stroke>
<sld:CssParameter name="stroke">#0000FF</sld:CssParameter>
</sld:Stroke>
</sld:LineSymbolizer>
</sld:Rule>
</sld:FeatureTypeStyle>
</sld:UserStyle>
</sld:NamedLayer>
</sld:StyledLayerDescriptor>
Type: MultiLineString
---------------------
URL: http://192.168.99.110/geoserver/wms?SERVICE=WMS&VERSION=1.1.1&REQUEST=GetStyles&LAYERS=bmd_denpasar:test_multilinestring1
Method: GET
Response:
<?xml version="1.0" encoding="UTF-8"?><sld:StyledLayerDescriptor xmlns="http://www.opengis.net/sld" xmlns:sld="http://www.opengis.net/sld" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" version="1.0.0">
<sld:NamedLayer>
<sld:Name>bmd_denpasar:test_multilinestring1</sld:Name>
<sld:UserStyle>
<sld:Name>line</sld:Name>
<sld:Title>Default Line</sld:Title>
<sld:IsDefault>1</sld:IsDefault>
<sld:Abstract>A sample style that draws a line</sld:Abstract>
<sld:FeatureTypeStyle>
<sld:Name>name</sld:Name>
<sld:Rule>
<sld:Name>rule1</sld:Name>
<sld:Title>Blue Line</sld:Title>
<sld:Abstract>A solid blue line with a 1 pixel width</sld:Abstract>
<sld:LineSymbolizer>
<sld:Stroke>
<sld:CssParameter name="stroke">#0000FF</sld:CssParameter>
</sld:Stroke>
</sld:LineSymbolizer>
</sld:Rule>
</sld:FeatureTypeStyle>
</sld:UserStyle>
</sld:NamedLayer>
</sld:StyledLayerDescriptor>
Type: Polygon
---------------------
URL: http://192.168.99.110/geoserver/wms?SERVICE=WMS&VERSION=1.1.1&REQUEST=GetStyles&LAYERS=bmd_denpasar:test_bmd_1
Method: GET
Response:
<?xml version="1.0" encoding="UTF-8"?><sld:StyledLayerDescriptor xmlns="http://www.opengis.net/sld" xmlns:sld="http://www.opengis.net/sld" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" version="1.0.0">
<sld:NamedLayer>
<sld:Name>bmd_denpasar:test_bmd_1</sld:Name>
<sld:UserStyle>
<sld:Name>polygon</sld:Name>
<sld:Title>Default Polygon</sld:Title>
<sld:IsDefault>1</sld:IsDefault>
<sld:Abstract>A sample style that draws a polygon</sld:Abstract>
<sld:FeatureTypeStyle>
<sld:Name>name</sld:Name>
<sld:Rule>
<sld:Name>rule1</sld:Name>
<sld:Title>Gray Polygon with Black Outline</sld:Title>
<sld:Abstract>A polygon with a gray fill and a 1 pixel black outline</sld:Abstract>
<sld:PolygonSymbolizer>
<sld:Fill>
<sld:CssParameter name="fill">#E72020</sld:CssParameter>
<sld:CssParameter name="fill-opacity">0.2</sld:CssParameter>
</sld:Fill>
<sld:Stroke/>
</sld:PolygonSymbolizer>
</sld:Rule>
</sld:FeatureTypeStyle>
</sld:UserStyle>
</sld:NamedLayer>
</sld:StyledLayerDescriptor>
Type: MultiPolygon
---------------------
URL: http://192.168.99.110/geoserver/wms?SERVICE=WMS&VERSION=1.1.1&REQUEST=GetStyles&LAYERS=bmd_denpasar:test_multipolygon1
Method: GET
Response:
<?xml version="1.0" encoding="UTF-8"?><sld:StyledLayerDescriptor xmlns="http://www.opengis.net/sld" xmlns:sld="http://www.opengis.net/sld" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc" version="1.0.0">
<sld:NamedLayer>
<sld:Name>bmd_denpasar:test_multipolygon1</sld:Name>
<sld:UserStyle>
<sld:Name>polygon</sld:Name>
<sld:Title>Default Polygon</sld:Title>
<sld:IsDefault>1</sld:IsDefault>
<sld:Abstract>A sample style that draws a polygon</sld:Abstract>
<sld:FeatureTypeStyle>
<sld:Name>name</sld:Name>
<sld:Rule>
<sld:Name>rule1</sld:Name>
<sld:Title>Gray Polygon with Black Outline</sld:Title>
<sld:Abstract>A polygon with a gray fill and a 1 pixel black outline</sld:Abstract>
<sld:PolygonSymbolizer>
<sld:Fill>
<sld:CssParameter name="fill">#E72020</sld:CssParameter>
<sld:CssParameter name="fill-opacity">0.2</sld:CssParameter>
</sld:Fill>
<sld:Stroke/>
</sld:PolygonSymbolizer>
</sld:Rule>
</sld:FeatureTypeStyle>
</sld:UserStyle>
</sld:NamedLayer>
</sld:StyledLayerDescriptor>

643
src/assets/docs/wfs_example.txt

@ -0,0 +1,643 @@
====================================================================================================================
WFS Example
Author: Ardhi
Description: This documentation is an example of a guidance to know how geometry are saved in geoserver,
how to show table, a payload example, to update or delete geometry using geoserver rest API
Created on: 25th January 2020
====================================================================================================================
Create New Feature
-------------------
URL: http://192.168.99.110/geoserver/wfs/WfsDispatcher
Method: POST
Request Payload:
- layer name
- geom type (multi / single)
- map projection
- coordinates
- other feature atrributes (fields)
Examples:
(Point)
<?xml version="1.0" encoding="UTF-8"?>
<wfs:Transaction handle="Added 1 feature to '' via MapLoom." service="WFS" version="1.0.0" xmlns:wfs="http://www.opengis.net/wfs" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/wfs.xsd">
<wfs:Insert handle="Added 1 feature to '' via MapLoom.">
<feature:test_bmd_2_point xmlns:feature="http://siopas.co.id/bmd-denpasar">
<feature:the_geom>
<gml:Point srsName="EPSG:3857" xmlns:gml="http://www.opengis.net/gml">
<gml:coordinates cs="," decimal="." ts=" ">11886499.833369536,-693527.4813667177</gml:coordinates>
</gml:Point>
</feature:the_geom>
<feature:nama_point>point1</feature:nama_point>
</feature:test_bmd_2_point>
</wfs:Insert>
</wfs:Transaction>
Response:
<?xml version="1.0" encoding="UTF-8"?>
<wfs:WFS_TransactionResponse version="1.0.0" xmlns:ogc="http://www.opengis.net/ogc" xmlns:wfs="http://www.opengis.net/wfs" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://192.168.99.110:80/geoserver/schemas/wfs/1.0.0/WFS-transaction.xsd">
<wfs:InsertResult handle="Added 1 feature to '' via MapLoom.">
<ogc:FeatureId fid="test_bmd_2_point.2"/>
</wfs:InsertResult>
<wfs:TransactionResult handle="Added 1 feature to '' via MapLoom.">
<wfs:Status>
<wfs:SUCCESS/>
</wfs:Status>
</wfs:TransactionResult>
</wfs:WFS_TransactionResponse>
(MultiPoint)
<?xml version="1.0" encoding="UTF-8"?>
<wfs:Transaction handle="Added 1 feature to '' via MapLoom." service="WFS" version="1.0.0" xmlns:wfs="http://www.opengis.net/wfs" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/wfs.xsd">
<wfs:Insert handle="Added 1 feature to '' via MapLoom.">
<feature:test_multipoint1 xmlns:feature="http://siopas.co.id/bmd-denpasar">
<feature:the_geom>
<gml:MultiPoint srsName="EPSG:3857" xmlns:gml="http://www.opengis.net/gml">
<gml:pointMember>
<gml:Point>
<gml:coordinates cs="," decimal="." ts=" ">11892025.868385417,-694976.24551184</gml:coordinates>
</gml:Point>
</gml:pointMember>
<gml:pointMember>
<gml:Point>
<gml:coordinates cs="," decimal="." ts=" ">11893350.776915178,-694453.9258029916</gml:coordinates>
</gml:Point>
</gml:pointMember>
<gml:pointMember>
<gml:Point>
<gml:coordinates cs="," decimal="." ts=" ">11895096.089113038,-695969.9269091613</gml:coordinates>
</gml:Point>
</gml:pointMember>
</gml:MultiPoint>
</feature:the_geom>
<feature:nama_titik>area rawan bencana</feature:nama_titik>
</feature:test_multipoint1>
</wfs:Insert>
</wfs:Transaction>Response:
<?xml version="1.0" encoding="UTF-8"?><wfs:WFS_TransactionResponse version="1.0.0" xmlns:wfs="http://www.opengis.net/wfs" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://192.168.99.110:80/geoserver/schemas/wfs/1.0.0/WFS-transaction.xsd"><wfs:InsertResult handle="Added 1 feature to '' via MapLoom."><ogc:FeatureId fid="test_multipoint1.2"/></wfs:InsertResult> <wfs:TransactionResult handle="Added 1 feature to '' via MapLoom."> <wfs:Status> <wfs:SUCCESS/> </wfs:Status> </wfs:TransactionResult></wfs:WFS_TransactionResponse>
(LineString)
<?xml version="1.0" encoding="UTF-8"?>
<wfs:Transaction handle="Added 1 feature to '' via MapLoom." service="WFS" version="1.0.0" xmlns:wfs="http://www.opengis.net/wfs" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/wfs.xsd">
<wfs:Insert handle="Added 1 feature to '' via MapLoom.">
<feature:test_bmd_line_1 xmlns:feature="http://siopas.co.id/bmd-denpasar">
<feature:the_geom>
<gml:LineString srsName="EPSG:3857" xmlns:gml="http://www.opengis.net/gml">
<gml:coordinates cs="," decimal="." ts=" ">11886123.154847158,-693341.4126344601 11886223.617927274,-693431.829327727 11886527.877188448,-693645.671983231 11886525.006817233,-693496.4126800604 11886424.543824714,-693446.1812275994 11886384.358627707,-693416.0423298439 11886370.00685923,-693345.7181912824</gml:coordinates>
</gml:LineString>
</feature:the_geom>
<feature:nama_jalan>jalan cinta</feature:nama_jalan>
</feature:test_bmd_line_1>
</wfs:Insert>
</wfs:Transaction>
Response:
<?xml version="1.0" encoding="UTF-8"?><wfs:WFS_TransactionResponse version="1.0.0" xmlns:wfs="http://www.opengis.net/wfs" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://192.168.99.110:80/geoserver/schemas/wfs/1.0.0/WFS-transaction.xsd"><wfs:InsertResult handle="Added 1 feature to '' via MapLoom."><ogc:FeatureId fid="test_bmd_line_1.1"/></wfs:InsertResult> <wfs:TransactionResult handle="Added 1 feature to '' via MapLoom."> <wfs:Status> <wfs:SUCCESS/> </wfs:Status> </wfs:TransactionResult></wfs:WFS_TransactionResponse>
(MultiLineString)
<?xml version="1.0" encoding="UTF-8"?>
<wfs:Transaction handle="Added 1 feature to '' via MapLoom." service="WFS" version="1.0.0" xmlns:wfs="http://www.opengis.net/wfs" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/wfs.xsd">
<wfs:Insert handle="Added 1 feature to '' via MapLoom.">
<feature:test_multilinestring1 xmlns:feature="http://siopas.co.id/bmd-denpasar">
<feature:the_geom>
<gml:MultiLineString srsName="EPSG:3857" xmlns:gml="http://www.opengis.net/gml">
<gml:lineMember>
<gml:LineString>
<gml:coordinates cs="," decimal="." ts=" ">11889089.199553609,-694806.789552831 11889515.599038912,-694806.789552831 11889982.886502603,-695028.7507504856 11890397.603453713,-695314.9642818893 11890607.882651944,-695817.2977438518</gml:coordinates>
</gml:LineString>
</gml:lineMember>
<gml:lineMember>
<gml:LineString>
<gml:coordinates cs="," decimal="." ts=" ">11889001.58322468,-694941.1344097083 11888989.901047,-695297.4406506772 11889141.769713346,-695624.5418039591 11889235.22677827,-696015.8945779663 11889223.544600591,-696173.6039766396</gml:coordinates>
</gml:LineString>
</gml:lineMember>
</gml:MultiLineString>
</feature:the_geom>
<feature:nama_jalan>jalan cinta</feature:nama_jalan>
</feature:test_multilinestring1>
</wfs:Insert>
</wfs:Transaction>
Response:
<?xml version="1.0" encoding="UTF-8"?><wfs:WFS_TransactionResponse version="1.0.0" xmlns:wfs="http://www.opengis.net/wfs" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://192.168.99.110:80/geoserver/schemas/wfs/1.0.0/WFS-transaction.xsd"><wfs:InsertResult handle="Added 1 feature to '' via MapLoom."><ogc:FeatureId fid="test_multilinestring1.2"/></wfs:InsertResult> <wfs:TransactionResult handle="Added 1 feature to '' via MapLoom."> <wfs:Status> <wfs:SUCCESS/> </wfs:Status> </wfs:TransactionResult></wfs:WFS_TransactionResponse>
(Polygon)
<?xml version="1.0" encoding="UTF-8"?>
<wfs:Transaction handle="Added 1 feature to '' via MapLoom." service="WFS" version="1.0.0" xmlns:wfs="http://www.opengis.net/wfs" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/wfs.xsd">
<wfs:Insert handle="Added 1 feature to '' via MapLoom.">
<feature:test_bmd_1 xmlns:feature="http://siopas.co.id/bmd-denpasar">
<feature:the_geom>
<gml:Polygon srsName="EPSG:3857" xmlns:gml="http://www.opengis.net/gml">
<gml:outerBoundaryIs>
<gml:LinearRing>
<gml:coordinates cs="," decimal="." ts=" ">11885890.360625308,-693614.4345447493 11886066.325063715,-693607.6666826681 11886047.016727008,-693545.3625436059 11885890.360625308,-693556.9077170598 11885891.754008677,-693576.0169747006 11885881.005051253,-693576.0169747006 11885890.360625308,-693614.4345447493</gml:coordinates>
</gml:LinearRing>
</gml:outerBoundaryIs>
</gml:Polygon>
</feature:the_geom>
<feature:nama_area>makam al falah</feature:nama_area>
<feature:status_area>baik</feature:status_area>
<feature:penggunaan>tempat pemakaman</feature:penggunaan>
</feature:test_bmd_1>
</wfs:Insert>
</wfs:Transaction>
Response:
<?xml version="1.0" encoding="UTF-8"?><wfs:WFS_TransactionResponse version="1.0.0" xmlns:wfs="http://www.opengis.net/wfs" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://192.168.99.110:80/geoserver/schemas/wfs/1.0.0/WFS-transaction.xsd"><wfs:InsertResult handle="Added 1 feature to '' via MapLoom."><ogc:FeatureId fid="test_bmd_1.2"/></wfs:InsertResult> <wfs:TransactionResult handle="Added 1 feature to '' via MapLoom."> <wfs:Status> <wfs:SUCCESS/> </wfs:Status> </wfs:TransactionResult></wfs:WFS_TransactionResponse>
(MultiPolygon)
<?xml version="1.0" encoding="UTF-8"?>
<wfs:Transaction handle="Added 1 feature to '' via MapLoom." service="WFS" version="1.0.0" xmlns:wfs="http://www.opengis.net/wfs" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/wfs.xsd">
<wfs:Insert handle="Added 1 feature to '' via MapLoom.">
<feature:test_multipolygon1 xmlns:feature="http://siopas.co.id/bmd-denpasar">
<feature:the_geom>
<gml:MultiPolygon srsName="EPSG:3857" xmlns:gml="http://www.opengis.net/gml">
<gml:polygonMember>
<gml:Polygon>
<gml:outerBoundaryIs>
<gml:LinearRing>
<gml:coordinates cs="," decimal="." ts=" ">11886589.213954791,-694367.2474235861 11886875.42730794,-694519.1158225475 11887167.481749926,-694495.7515563164 11887161.640661087,-694805.3290865673 11886729.400086945,-694787.805820048 11886612.57831015,-694700.1894874518 11886589.213954791,-694367.2474235861</gml:coordinates>
</gml:LinearRing>
</gml:outerBoundaryIs>
</gml:Polygon>
</gml:polygonMember>
<gml:polygonMember>
<gml:Polygon>
<gml:outerBoundaryIs>
<gml:LinearRing>
<gml:coordinates cs="," decimal="." ts=" ">11886314.682992412,-694449.02275473 11886343.88843661,-694852.0578846727 11885800.667174513,-694822.852262218 11885765.620641476,-694449.02275473 11886314.682992412,-694449.02275473</gml:coordinates>
</gml:LinearRing>
</gml:outerBoundaryIs>
</gml:Polygon>
</gml:polygonMember>
</gml:MultiPolygon>
</feature:the_geom>
<feature:nama_area>kos-kosan Ibu Jamil</feature:nama_area>
</feature:test_multipolygon1>
</wfs:Insert>
</wfs:Transaction>
Response:
<?xml version="1.0" encoding="UTF-8"?><wfs:WFS_TransactionResponse version="1.0.0" xmlns:wfs="http://www.opengis.net/wfs" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://192.168.99.110:80/geoserver/schemas/wfs/1.0.0/WFS-transaction.xsd"><wfs:InsertResult handle="Added 1 feature to '' via MapLoom."><ogc:FeatureId fid="test_multipolygon1.1"/></wfs:InsertResult> <wfs:TransactionResult handle="Added 1 feature to '' via MapLoom."> <wfs:Status> <wfs:SUCCESS/> </wfs:Status> </wfs:TransactionResult></wfs:WFS_TransactionResponse>
Edit Geometry
---------------------
URL: http://192.168.99.110/geoserver/wfs/WfsDispatcher
Method: POST
Request Payload:
<?xml version="1.0" encoding="UTF-8"?>
<wfs:Transaction handle="Modified 1 feature in '' via MapLoom." service="WFS" version="1.0.0" xmlns:wfs="http://www.opengis.net/wfs" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/wfs.xsd">
<wfs:Update handle="Modified 1 feature in '' via MapLoom." typeName="geonode:test12" xmlns:feature="http://www.geonode.org/">
<wfs:Property>
<wfs:Name>the_geom</wfs:Name>
<wfs:Value>
<gml:Polygon srsName="EPSG:3857" xmlns:gml="http://www.opengis.net/gml">
<gml:outerBoundaryIs>
<gml:LinearRing>
<gml:coordinates cs="," decimal="." ts=" ">11901975.891860606,-698153.9913410997 11901566.635257043,-699013.9079201279 11902842.178206988,-699160.4120491266 11902674.97220021,-698612.6135096712 11901975.891860606,-698153.9913410997</gml:coordinates>
</gml:LinearRing>
</gml:outerBoundaryIs>
</gml:Polygon>
</wfs:Value>
</wfs:Property>
<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">
<ogc:FeatureId fid="test12.3"/>
</ogc:Filter>
</wfs:Update>
</wfs:Transaction>
IF GEOM IS NULL, THEN RESPONSE IS ERROR:
<?xml version="1.0" encoding="UTF-8"?><wfs:WFS_TransactionResponse version="1.0.0" xmlns:wfs="http://www.opengis.net/wfs" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://192.168.99.110:80/geoserver/schemas/wfs/1.0.0/WFS-transaction.xsd"><wfs:InsertResult><ogc:FeatureId fid="none"/></wfs:InsertResult> <wfs:TransactionResult handle="Added 1 feature to '' via MapLoom."> <wfs:Status> <wfs:FAILED/> </wfs:Status> <wfs:Message>Error performing insert: java.lang.String cannot be cast to com.vividsolutions.jts.geom.Geometry</wfs:Message> </wfs:TransactionResult></wfs:WFS_TransactionResponse>
Edit Attributes / Edit Feature
---------------------
URL: http://192.168.99.110/geoserver/wfs/WfsDispatcher
Method: POST
Request Payload:
<?xml version="1.0" encoding="UTF-8"?>
<wfs:Transaction handle="Modified 1 feature in '' via MapLoom." service="WFS" version="1.0.0" xmlns:wfs="http://www.opengis.net/wfs" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/wfs.xsd">
<wfs:Update handle="Modified 1 feature in '' via MapLoom." typeName="geonode:test12" xmlns:feature="http://www.geonode.org/">
<wfs:Property>
<wfs:Name>nama_area</wfs:Name>
<wfs:Value>bandara3_edit</wfs:Value>
</wfs:Property>
<wfs:Property>
<wfs:Name>status_area</wfs:Name>
<wfs:Value>0</wfs:Value>
</wfs:Property>
<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">
<ogc:FeatureId fid="test12.3"/>
</ogc:Filter>
</wfs:Update>
</wfs:Transaction>
Show Table
--------------------
URL: http://192.168.99.110/geoserver/wfs/WfsDispatcher
Method: POST
Request Payload:
<?xml version="1.0" encoding="UTF-8"?>
<wfs:GetFeature maxFeatures="25" outputFormat="JSON" service="WFS" startIndex="0" version="1.1.0" xmlns:ogc="http://www.opengis.net/ogc" xmlns:wfs="http://www.opengis.net/wfs" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/wfs.xsd">
<wfs:Query srsName="EPSG:4326" typeName="geonode:test12"/>
</wfs:GetFeature>
===================================================
Projection: EPSG:4326 (test_bmd_1 layer / polygon)
===================================================
Create New Feature
--------------------
URL: http://192.168.99.110/geoserver/wfs/WfsDispatcher
Method: POST
Request Payload:
<?xml version="1.0" encoding="UTF-8"?>
<wfs:Transaction handle="Added 1 feature to '' via MapLoom." service="WFS" version="1.0.0" xmlns:wfs="http://www.opengis.net/wfs" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/wfs.xsd">
<wfs:Insert handle="Added 1 feature to '' via MapLoom.">
<feature:test_bmd_1 xmlns:feature="http://siopas.co.id/bmd-denpasar">
<feature:the_geom>
<gml:Polygon srsName="EPSG:3857" xmlns:gml="http://www.opengis.net/gml">
<gml:outerBoundaryIs>
<gml:LinearRing>
<gml:coordinates cs="," decimal="." ts=" ">11912150.70602516,-696067.2297045494 11912208.034207555,-696640.5074453525 11913341.849953607,-696440.5964197303 11913195.345645027,-695809.9910147788 11912150.70602516,-696067.2297045494</gml:coordinates>
</gml:LinearRing>
</gml:outerBoundaryIs>
</gml:Polygon>
</feature:the_geom>
<feature:nama_area>feature1_bmd</feature:nama_area>
<feature:status_area>digunakan</feature:status_area>
<feature:penggunaan>mall</feature:penggunaan>
</feature:test_bmd_1>
</wfs:Insert>
</wfs:Transaction>
Response:
<?xml version="1.0" encoding="UTF-8"?>
<wfs:WFS_TransactionResponse version="1.0.0" xmlns:ogc="http://www.opengis.net/ogc" xmlns:wfs="http://www.opengis.net/wfs" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://192.168.99.110:80/geoserver/schemas/wfs/1.0.0/WFS-transaction.xsd">
<wfs:InsertResult handle="Added 1 feature to '' via MapLoom.">
<ogc:FeatureId fid="test_bmd_1.1"/>
</wfs:InsertResult>
<wfs:TransactionResult handle="Added 1 feature to '' via MapLoom.">
<wfs:Status>
<wfs:SUCCESS/>
</wfs:Status>
</wfs:TransactionResult>
</wfs:WFS_TransactionResponse>
Edit Geometry
--------------------
URL: http://192.168.99.110/geoserver/wfs/WfsDispatcher
Method: POST
Request Payload:
<?xml version="1.0" encoding="UTF-8"?>
<wfs:Transaction handle="Modified 1 feature in '' via MapLoom." service="WFS" version="1.0.0" xmlns:wfs="http://www.opengis.net/wfs" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/wfs.xsd">
<wfs:Update handle="Modified 1 feature in '' via MapLoom." typeName="bmd_denpasar:test_bmd_1" xmlns:feature="http://siopas.co.id/bmd-denpasar">
<wfs:Property>
<wfs:Name>the_geom</wfs:Name>
<wfs:Value>
<gml:Polygon srsName="EPSG:3857" xmlns:gml="http://www.opengis.net/gml">
<gml:outerBoundaryIs>
<gml:LinearRing>
<gml:coordinates cs="," decimal="." ts=" ">11912443.71484449,-695572.7177419447 11912169.81548497,-696120.5165581756 11912876.858017681,-696470.8527538674 11913150.757377198,-695929.4239817676 11912443.71484449,-695572.7177419447</gml:coordinates>
</gml:LinearRing>
</gml:outerBoundaryIs>
</gml:Polygon>
</wfs:Value>
</wfs:Property>
<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">
<ogc:FeatureId fid="test_bmd_1.1"/>
</ogc:Filter>
</wfs:Update>
</wfs:Transaction>
Response:
<?xml version="1.0" encoding="UTF-8"?>
<wfs:WFS_TransactionResponse version="1.0.0" xmlns:ogc="http://www.opengis.net/ogc" xmlns:wfs="http://www.opengis.net/wfs" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://192.168.99.110:80/geoserver/schemas/wfs/1.0.0/WFS-transaction.xsd">
<wfs:InsertResult>
<ogc:FeatureId fid="none"/>
</wfs:InsertResult>
<wfs:TransactionResult handle="Modified 1 feature in '' via MapLoom.">
<wfs:Status>
<wfs:SUCCESS/>
</wfs:Status>
</wfs:TransactionResult>
</wfs:WFS_TransactionResponse>
Edit Attributes / Edit Feature
-------------------------------
URL: http://192.168.99.110/geoserver/wfs/WfsDispatcher
Method: POST
Request Payload:
<?xml version="1.0" encoding="UTF-8"?>
<wfs:Transaction handle="Modified 1 feature in '' via MapLoom." service="WFS" version="1.0.0" xmlns:wfs="http://www.opengis.net/wfs" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/wfs.xsd">
<wfs:Update handle="Modified 1 feature in '' via MapLoom." typeName="bmd_denpasar:test_bmd_1" xmlns:feature="http://siopas.co.id/bmd-denpasar">
<wfs:Property>
<wfs:Name>nama_area</wfs:Name>
<wfs:Value>feature1_bmd_edit</wfs:Value>
</wfs:Property>
<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">
<ogc:FeatureId fid="test_bmd_1.1"/>
</ogc:Filter>
</wfs:Update>
</wfs:Transaction>
Response:
<?xml version="1.0" encoding="UTF-8"?>
<wfs:WFS_TransactionResponse version="1.0.0" xmlns:ogc="http://www.opengis.net/ogc" xmlns:wfs="http://www.opengis.net/wfs" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://192.168.99.110:80/geoserver/schemas/wfs/1.0.0/WFS-transaction.xsd">
<wfs:InsertResult>
<ogc:FeatureId fid="none"/>
</wfs:InsertResult>
<wfs:TransactionResult handle="Modified 1 feature in '' via MapLoom.">
<wfs:Status>
<wfs:SUCCESS/>
</wfs:Status>
</wfs:TransactionResult>
</wfs:WFS_TransactionResponse>
Show Table
------------------
URL: http://192.168.99.110/geoserver/wfs/WfsDispatcher
Method: POST
Request Payload:
<?xml version="1.0" encoding="UTF-8"?>
<wfs:GetFeature maxFeatures="25" outputFormat="JSON" service="WFS" startIndex="0" version="1.1.0" xmlns:ogc="http://www.opengis.net/ogc" xmlns:wfs="http://www.opengis.net/wfs" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/wfs.xsd">
<wfs:Query srsName="EPSG:4326" typeName="bmd_denpasar:test_bmd_1"/>
</wfs:GetFeature>
Response:
{
"crs": {
"properties": {
"name": "urn:ogc:def:crs:EPSG::4326"
},
"type": "name"
},
"features": [
{
"geometry": {
"coordinates": [
[
[
107.01130260258336,
-6.236087122949689
],
[
107.0088421227737,
-6.240978942036793
],
[
107.01519359391025,
-6.244107404753763
],
[
107.0176540737199,
-6.2392724990064
],
[
107.01130260258336,
-6.236087122949689
]
]
],
"type": "Polygon"
},
"geometry_name": "the_geom",
"id": "test_bmd_1.1",
"properties": {
"nama_area": "feature1_bmd_edit",
"penggunaan": "mall",
"status_area": "digunakan"
},
"type": "Feature"
}
],
"totalFeatures": 1,
"type": "FeatureCollection"
}
Delete Feature
-------------------------------
URL: http://192.168.99.110/geoserver/wfs/WfsDispatcher
Method: POST
Request Payload:
<?xml version="1.0" encoding="UTF-8"?>
<wfs:Transaction handle="Removed 1 feature from '' via MapLoom." service="WFS" version="1.0.0" xmlns:wfs="http://www.opengis.net/wfs" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/wfs.xsd">
<wfs:Delete handle="Removed 1 feature from '' via MapLoom." typeName="bmd_denpasar:test_bmd_1" xmlns:feature="http://siopas.co.id/bmd-denpasar">
<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">
<ogc:FeatureId fid="test_bmd_1.1"/>
</ogc:Filter>
</wfs:Delete>
</wfs:Transaction>
Response:
<?xml version="1.0" encoding="UTF-8"?>
<wfs:WFS_TransactionResponse version="1.0.0" xmlns:ogc="http://www.opengis.net/ogc" xmlns:wfs="http://www.opengis.net/wfs" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://192.168.99.110:80/geoserver/schemas/wfs/1.0.0/WFS-transaction.xsd">
<wfs:InsertResult>
<ogc:FeatureId fid="none"/>
</wfs:InsertResult>
<wfs:TransactionResult handle="Removed 1 feature from '' via MapLoom.">
<wfs:Status>
<wfs:SUCCESS/>
</wfs:Status>
</wfs:TransactionResult>
</wfs:WFS_TransactionResponse>
======================================================
Projection: EPSG:4326 (test_bmd_2_point layer / point)
======================================================
Create New Feature:
--------------------
URL: http://192.168.99.110/geoserver/wfs/WfsDispatcher
Method: POST
Request Payload:
<?xml version="1.0" encoding="UTF-8"?>
<wfs:Transaction handle="Added 1 feature to '' via MapLoom." service="WFS" version="1.0.0" xmlns:wfs="http://www.opengis.net/wfs" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/wfs.xsd">
<wfs:Insert handle="Added 1 feature to '' via MapLoom.">
<feature:test_bmd_2_point xmlns:feature="http://siopas.co.id/bmd-denpasar">
<feature:the_geom>
<gml:Point srsName="EPSG:3857" xmlns:gml="http://www.opengis.net/gml">
<gml:coordinates cs="," decimal="." ts=" ">12602498.558283165,-869310.3742524114</gml:coordinates>
</gml:Point>
</feature:the_geom>
<feature:nama_point>test_bmd_2_point1</feature:nama_point>
</feature:test_bmd_2_point>
</wfs:Insert>
</wfs:Transaction>
Response:
<?xml version="1.0" encoding="UTF-8"?>
<wfs:WFS_TransactionResponse version="1.0.0" xmlns:ogc="http://www.opengis.net/ogc" xmlns:wfs="http://www.opengis.net/wfs" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://192.168.99.110:80/geoserver/schemas/wfs/1.0.0/WFS-transaction.xsd">
<wfs:InsertResult handle="Added 1 feature to '' via MapLoom.">
<ogc:FeatureId fid="test_bmd_2_point.1"/>
</wfs:InsertResult>
<wfs:TransactionResult handle="Added 1 feature to '' via MapLoom.">
<wfs:Status>
<wfs:SUCCESS/>
</wfs:Status>
</wfs:TransactionResult>
</wfs:WFS_TransactionResponse>
Edit Geometry
-----------------
URL: http://192.168.99.110/geoserver/wfs/WfsDispatcher
Method: POST
Request Payload:
<?xml version="1.0" encoding="UTF-8"?>
<wfs:Transaction handle="Modified 1 feature in '' via MapLoom." service="WFS" version="1.0.0" xmlns:wfs="http://www.opengis.net/wfs" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/wfs.xsd">
<wfs:Update handle="Modified 1 feature in '' via MapLoom." typeName="bmd_denpasar:test_bmd_2_point" xmlns:feature="http://siopas.co.id/bmd-denpasar">
<wfs:Property>
<wfs:Name>the_geom</wfs:Name>
<wfs:Value>
<gml:Point srsName="EPSG:3857" xmlns:gml="http://www.opengis.net/gml">
<gml:coordinates cs="," decimal="." ts=" ">12630296.161275087,-871501.5712076114</gml:coordinates>
</gml:Point>
</wfs:Value>
</wfs:Property>
<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">
<ogc:FeatureId fid="test_bmd_2_point.1"/>
</ogc:Filter>
</wfs:Update>
</wfs:Transaction>
Response:
<?xml version="1.0" encoding="UTF-8"?>
<wfs:WFS_TransactionResponse version="1.0.0" xmlns:ogc="http://www.opengis.net/ogc" xmlns:wfs="http://www.opengis.net/wfs" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://192.168.99.110:80/geoserver/schemas/wfs/1.0.0/WFS-transaction.xsd">
<wfs:InsertResult>
<ogc:FeatureId fid="none"/>
</wfs:InsertResult>
<wfs:TransactionResult handle="Modified 1 feature in '' via MapLoom.">
<wfs:Status>
<wfs:SUCCESS/>
</wfs:Status>
</wfs:TransactionResult>
</wfs:WFS_TransactionResponse>
Edit Feature / Attributes
-------------------------------
URL: http://192.168.99.110/geoserver/wfs/WfsDispatcher
Method: POST
Request Payload:
<?xml version="1.0" encoding="UTF-8"?>
<wfs:Transaction handle="Modified 1 feature in '' via MapLoom." service="WFS" version="1.0.0" xmlns:wfs="http://www.opengis.net/wfs" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/wfs.xsd">
<wfs:Update handle="Modified 1 feature in '' via MapLoom." typeName="bmd_denpasar:test_bmd_2_point" xmlns:feature="http://siopas.co.id/bmd-denpasar">
<wfs:Property>
<wfs:Name>nama_point</wfs:Name>
<wfs:Value>test_bmd_2_point1_edit</wfs:Value>
</wfs:Property>
<wfs:Property>
<wfs:Name>the_geom</wfs:Name>
<wfs:Value>
<gml:Point srsName="EPSG:3857" xmlns:gml="http://www.opengis.net/gml">
<gml:coordinates cs="," decimal="." ts=" ">12630296.161687493,-871501.571241029</gml:coordinates>
</gml:Point>
</wfs:Value>
</wfs:Property>
<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">
<ogc:FeatureId fid="test_bmd_2_point.1"/>
</ogc:Filter>
</wfs:Update>
</wfs:Transaction>
Response:
<?xml version="1.0" encoding="UTF-8"?>
<wfs:WFS_TransactionResponse version="1.0.0" xmlns:ogc="http://www.opengis.net/ogc" xmlns:wfs="http://www.opengis.net/wfs" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://192.168.99.110:80/geoserver/schemas/wfs/1.0.0/WFS-transaction.xsd">
<wfs:InsertResult>
<ogc:FeatureId fid="none"/>
</wfs:InsertResult>
<wfs:TransactionResult handle="Modified 1 feature in '' via MapLoom.">
<wfs:Status>
<wfs:SUCCESS/>
</wfs:Status>
</wfs:TransactionResult>
</wfs:WFS_TransactionResponse>
Show Table
-------------------------------
URL: http://192.168.99.110/geoserver/wfs/WfsDispatcher
Method: POST
Request Payload:
<?xml version="1.0" encoding="UTF-8"?>
<wfs:GetFeature maxFeatures="25" outputFormat="JSON" service="WFS" startIndex="0" version="1.1.0" xmlns:ogc="http://www.opengis.net/ogc" xmlns:wfs="http://www.opengis.net/wfs" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/wfs.xsd">
<wfs:Query srsName="EPSG:4326" typeName="bmd_denpasar:test_bmd_2_point"/>
</wfs:GetFeature>
Response:
{
"crs": {
"properties": {
"name": "urn:ogc:def:crs:EPSG::4326"
},
"type": "name"
},
"features": [
{
"geometry": {
"coordinates": [
113.45988085000002,
-7.804583949999995
],
"type": "Point"
},
"geometry_name": "the_geom",
"id": "test_bmd_2_point.1",
"properties": {
"nama_point": "test_bmd_2_point1_edit"
},
"type": "Feature"
}
],
"totalFeatures": 1,
"type": "FeatureCollection"
}
Map on click (to get features)
--------------------------------
URL: http://192.168.99.110/geoserver/wms?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetFeatureInfo&FORMAT=image%2Fpng&TRANSPARENT=true&QUERY_LAYERS=bmd_denpasar%3Atest_bmd_2_point&LAYERS=bmd_denpasar%3Atest_bmd_2_point&tiled=true&_dc=1574761400330&INFO_FORMAT=application%2Fjson&FEATURE_COUNT=5&I=177&J=70&WIDTH=256&HEIGHT=256&CRS=EPSG%3A3857&STYLES=&BBOX=12601714.231207296%2C-900122.445086237%2C12640849.989689307%2C-860986.6866042268
Method: GET
Query String Parameters:
SERVICE: WMS
VERSION: 1.3.0
REQUEST: GetFeatureInfo
FORMAT: image/png
TRANSPARENT: true
QUERY_LAYERS: bmd_denpasar:test_bmd_2_point
LAYERS: bmd_denpasar:test_bmd_2_point
tiled: true
_dc: 1574761400330
INFO_FORMAT: application/json
FEATURE_COUNT: 5
I: 177
J: 70
WIDTH: 256
HEIGHT: 256
CRS: EPSG:3857
STYLES:
BBOX: 12601714.231207296,-900122.445086237,12640849.989689307,-860986.6866042268
Delete Feature
-------------------------------
URL: http://192.168.99.110/geoserver/wfs/WfsDispatcher
Method: POST
Request Payload:
<?xml version="1.0" encoding="UTF-8"?>
<wfs:Transaction handle="Removed 1 feature from '' via MapLoom." service="WFS" version="1.0.0" xmlns:wfs="http://www.opengis.net/wfs" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/wfs.xsd">
<wfs:Delete handle="Removed 1 feature from '' via MapLoom." typeName="bmd_denpasar:test_bmd_2_point" xmlns:feature="http://siopas.co.id/bmd-denpasar">
<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">
<ogc:FeatureId fid="test_bmd_2_point.1"/>
</ogc:Filter>
</wfs:Delete>
</wfs:Transaction>
Response:
<?xml version="1.0" encoding="UTF-8"?>
<wfs:WFS_TransactionResponse version="1.0.0" xmlns:ogc="http://www.opengis.net/ogc" xmlns:wfs="http://www.opengis.net/wfs" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wfs http://192.168.99.110:80/geoserver/schemas/wfs/1.0.0/WFS-transaction.xsd">
<wfs:InsertResult>
<ogc:FeatureId fid="none"/>
</wfs:InsertResult>
<wfs:TransactionResult handle="Removed 1 feature from '' via MapLoom.">
<wfs:Status>
<wfs:SUCCESS/>
</wfs:Status>
</wfs:TransactionResult>
</wfs:WFS_TransactionResponse>

BIN
src/assets/img/avatars/user.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

BIN
src/assets/img/base_map/bali.PNG

Binary file not shown.

After

Width:  |  Height:  |  Size: 297 KiB

BIN
src/assets/img/base_map/bali_citra.PNG

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 MiB

BIN
src/assets/img/base_map/esri.PNG

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

BIN
src/assets/img/base_map/google.PNG

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

BIN
src/assets/img/base_map/google_street.PNG

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

BIN
src/assets/img/base_map/iu_map.PNG

Binary file not shown.

After

Width:  |  Height:  |  Size: 346 KiB

BIN
src/assets/img/base_map/osm.PNG

Binary file not shown.

After

Width:  |  Height:  |  Size: 515 KiB

BIN
src/assets/img/base_map/osm_light.PNG

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 KiB

44
src/assets/img/brand/logo.svg

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 17.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Warstwa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="707.1px" height="200px" viewBox="0 0 707.1 200" enable-background="new 0 0 707.1 200" xml:space="preserve">
<polygon fill="#61DAFB" points="0,150 0,50 86.6,0 173.2,50 173.2,150 86.6,200 "/>
<polygon fill="#FFFFFF" points="86.6,133.3 57.7,116.7 57.7,83.3 86.6,66.7 115.5,83.3 144.3,66.7 86.6,33.3 28.9,66.7 28.9,133.3
86.6,166.7 144.3,133.3 115.5,116.7 "/>
<polygon opacity="0.04" stroke="#FFFFFF" stroke-miterlimit="10" enable-background="new " points="0,50 86.6,100 86.6,0 "/>
<polygon opacity="0.04" stroke="#FFFFFF" stroke-miterlimit="10" enable-background="new " points="0,150 86.6,200 86.6,100 "/>
<polygon opacity="0.08" stroke="#FFFFFF" stroke-miterlimit="10" enable-background="new " points="86.6,100 173.2,150 173.2,50
"/>
<polygon fill-opacity="0" points="86.6,100 0,50 0,150 "/>
<polygon opacity="0.08" stroke="#FFFFFF" stroke-miterlimit="10" enable-background="new " points="173.2,150 86.6,100 86.6,200
"/>
<polygon opacity="0.08" stroke="#FFFFFF" stroke-miterlimit="10" enable-background="new " points="173.2,50 86.6,0 86.6,100 "/>
<g>
<path fill="#333333" d="M290.4,127.3c1,0,1.8,0.4,2.6,1.1l7.2,7.8c-4,4.9-8.8,8.7-14.6,11.3c-5.8,2.6-12.7,3.9-20.8,3.9
c-7.2,0-13.8-1.2-19.5-3.7c-5.8-2.5-10.7-5.9-14.8-10.3c-4.1-4.4-7.2-9.7-9.4-15.8c-2.2-6.1-3.3-12.8-3.3-20
c0-7.3,1.2-14.1,3.6-20.1c2.4-6.1,5.8-11.4,10.3-15.8c4.4-4.4,9.7-7.8,15.8-10.3s12.9-3.7,20.4-3.7c7.2,0,13.6,1.2,19,3.5
s10.1,5.4,13.9,9.2l-6.1,8.4c-0.4,0.5-0.8,1-1.4,1.4s-1.3,0.6-2.3,0.6s-2.1-0.4-3.2-1.2s-2.5-1.7-4.1-2.6c-1.7-0.9-3.8-1.8-6.3-2.6
c-2.5-0.8-5.8-1.2-9.7-1.2c-4.6,0-8.8,0.8-12.7,2.4c-3.8,1.6-7.2,3.9-9.9,6.9s-4.9,6.6-6.5,10.8c-1.6,4.3-2.3,9-2.3,14.3
c0,5.5,0.8,10.4,2.3,14.6c1.6,4.3,3.7,7.9,6.3,10.8c2.7,2.9,5.8,5.2,9.4,6.7c3.6,1.6,7.5,2.3,11.6,2.3c2.5,0,4.7-0.1,6.7-0.4
c2-0.3,3.8-0.7,5.5-1.3s3.3-1.3,4.8-2.3c1.5-0.9,3-2.1,4.5-3.4c0.4-0.4,0.9-0.7,1.4-1C289.3,127.4,289.9,127.3,290.4,127.3z"/>
<path fill="#333333" d="M407.5,101.5c0,7.2-1.2,13.8-3.6,19.9s-5.7,11.4-10.1,15.8c-4.3,4.5-9.5,7.9-15.6,10.4s-12.8,3.7-20.2,3.7
c-7.4,0-14.1-1.2-20.2-3.7s-11.3-6-15.7-10.4c-4.3-4.5-7.7-9.7-10.1-15.8c-2.4-6.1-3.6-12.7-3.6-19.9c0-7.2,1.2-13.8,3.6-19.9
s5.7-11.4,10.1-15.8c4.3-4.5,9.6-7.9,15.7-10.4s12.8-3.7,20.2-3.7c7.4,0,14.1,1.3,20.2,3.8s11.3,6,15.6,10.4
c4.3,4.4,7.7,9.7,10.1,15.8C406.3,87.7,407.5,94.3,407.5,101.5z M388.9,101.5c0-5.4-0.7-10.2-2.1-14.4c-1.4-4.3-3.5-7.9-6.1-10.8
c-2.7-3-5.9-5.2-9.7-6.8c-3.8-1.6-8.1-2.4-12.9-2.4s-9.1,0.8-12.9,2.4s-7.1,3.8-9.8,6.8c-2.7,3-4.7,6.6-6.2,10.8
c-1.4,4.3-2.2,9.1-2.2,14.4c0,5.4,0.7,10.2,2.2,14.4c1.4,4.3,3.5,7.9,6.2,10.8s5.9,5.2,9.8,6.8c3.8,1.6,8.1,2.4,12.9,2.4
s9.1-0.8,12.9-2.4c3.8-1.6,7-3.8,9.7-6.8c2.7-2.9,4.7-6.5,6.1-10.8C388.2,111.7,388.9,106.9,388.9,101.5z"/>
<path fill="#333333" d="M440.6,112.2v38.1h-18.2V52.7h29.8c6.7,0,12.4,0.7,17.1,2.1c4.7,1.4,8.6,3.3,11.7,5.8
c3,2.5,5.3,5.4,6.7,8.9c1.4,3.4,2.1,7.2,2.1,11.4c0,3.3-0.5,6.4-1.5,9.3s-2.4,5.6-4.2,8c-1.8,2.4-4.1,4.5-6.8,6.3
c-2.7,1.8-5.7,3.2-9.1,4.3c2.3,1.3,4.3,3.2,5.9,5.6l24.4,36h-16.3c-1.6,0-2.9-0.3-4-0.9c-1.1-0.6-2-1.5-2.8-2.7l-20.5-31.3
c-0.8-1.2-1.6-2-2.5-2.5s-2.3-0.7-4.1-0.7h-7.7V112.2z M440.6,99.1h11.3c3.4,0,6.4-0.4,8.9-1.3s4.6-2,6.3-3.5
c1.6-1.5,2.9-3.3,3.7-5.4c0.8-2.1,1.2-4.3,1.2-6.8c0-4.9-1.6-8.8-4.9-11.4c-3.3-2.7-8.2-4-15-4h-11.6v32.4H440.6z"/>
<path fill="#333333" d="M571.8,52.7v14.4h-43.3v27.1h34.1v14h-34.1v27.6h43.3v14.5h-61.6V52.7H571.8z"/>
<path fill="#61DAFB" d="M626.8,135.7c3.5,0,6.6-0.6,9.4-1.8c2.8-1.2,5.1-2.8,7-4.9c1.9-2.1,3.4-4.7,4.4-7.7s1.5-6.4,1.5-10.1V52.7
h18.2v58.5c0,5.8-0.9,11.2-2.8,16.1c-1.9,4.9-4.6,9.2-8.1,12.8c-3.5,3.6-7.8,6.4-12.8,8.4s-10.6,3-16.9,3s-11.9-1-16.9-3
s-9.2-4.8-12.7-8.4c-3.5-3.6-6.2-7.8-8-12.8c-1.9-4.9-2.8-10.3-2.8-16.1V52.7h18.2v58.4c0,3.7,0.5,7.1,1.5,10.1s2.5,5.6,4.4,7.7
s4.2,3.8,7,5C620.1,135.1,623.3,135.7,626.8,135.7z"/>
<path fill="#61DAFB" d="M706.2,150.3H688V52.7h18.2V150.3z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.2 KiB

BIN
src/assets/img/brand/logo_bmd_denpasar.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

BIN
src/assets/img/brand/logo_kominfo.jpeg

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

BIN
src/assets/img/brand/logo_siopas.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

BIN
src/assets/img/brand/logo_siopas_old.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

17
src/assets/img/brand/sygnet.svg

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 17.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Warstwa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="173.2px" height="200px" viewBox="0 0 173.2 200" enable-background="new 0 0 173.2 200" xml:space="preserve">
<polygon fill="#61DAFB" points="0,150 0,50 86.6,0 173.2,50 173.2,150 86.6,200 "/>
<polygon fill="#FFFFFF" points="86.6,133.3 57.7,116.7 57.7,83.3 86.6,66.7 115.5,83.3 144.3,66.7 86.6,33.3 28.9,66.7 28.9,133.3
86.6,166.7 144.3,133.3 115.5,116.7 "/>
<polygon opacity="0.04" stroke="#FFFFFF" stroke-miterlimit="10" enable-background="new " points="0,50 86.6,100 86.6,0 "/>
<polygon opacity="0.04" stroke="#FFFFFF" stroke-miterlimit="10" enable-background="new " points="0,150 86.6,200 86.6,100 "/>
<polygon opacity="0.08" stroke="#FFFFFF" stroke-miterlimit="10" enable-background="new " points="86.6,100 173.2,150 173.2,50
"/>
<polygon fill-opacity="0" points="86.6,100 0,50 0,150 "/>
<polygon opacity="0.08" stroke="#FFFFFF" stroke-miterlimit="10" enable-background="new " points="173.2,150 86.6,100 86.6,200
"/>
<polygon opacity="0.08" stroke="#FFFFFF" stroke-miterlimit="10" enable-background="new " points="173.2,50 86.6,0 86.6,100 "/>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
src/assets/img/image.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
src/assets/img/kominfo/dashboard.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 MiB

BIN
src/assets/img/kominfo/dashboard_kominfo_image_2G.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

BIN
src/assets/img/kominfo/dashboard_kominfo_image_3G.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

BIN
src/assets/img/kominfo/dashboard_kominfo_image_4G.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

BIN
src/assets/img/login/carousel1.jpeg

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

BIN
src/assets/img/login/carousel2.jpeg

Binary file not shown.

After

Width:  |  Height:  |  Size: 266 KiB

BIN
src/assets/img/login/carousel3.jpeg

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

BIN
src/assets/img/login/slide1.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 288 KiB

BIN
src/assets/img/login/slide2.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 216 KiB

BIN
src/assets/img/login/slide3.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 305 KiB

BIN
src/assets/img/login/slide4.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 234 KiB

BIN
src/assets/img/logo-surveyor-indonesia-2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

BIN
src/assets/img/logo-surveyor-indonesia.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 KiB

BIN
src/assets/img/logo_adyawinsa.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

BIN
src/assets/img/logo_kit.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

BIN
src/assets/img/logo_nawakara.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 KiB

BIN
src/assets/img/map/customer.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

BIN
src/assets/img/map/office.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

BIN
src/assets/img/map/officec.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
src/assets/img/map/pin2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
src/assets/img/map/pin_ori.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

BIN
src/assets/img/map/pin_route_green.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

BIN
src/assets/img/map/pin_route_red.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
src/assets/img/map/store.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

1064
src/assets/json/indonesia.json

File diff suppressed because it is too large Load Diff

9
src/components/AddFeature/AddFeature.css

@ -0,0 +1,9 @@
.add-input-container {
max-height: 300px;
overflow: auto;
}
.row-input {
margin-right: 0px !important;
margin-left: -10px !important;
}

141
src/components/AddFeature/AddFeature.js

@ -0,0 +1,141 @@
import React, { Component } from 'react';
import { Modal, ModalHeader, ModalBody, ModalFooter, Button,
UncontrolledTooltip, UncontrolledDropdown, DropdownToggle, DropdownMenu, DropdownItem,
Form, FormGroup, Label, Input, Row, Col } from 'reactstrap';
import { Icon } from '@iconify/react';
import removeCircle from '@iconify/icons-ion/remove-circle';
import './AddFeature.css';
import '../../assets/css/customscroll.css';
import { findWhere } from 'underscore';
import { createNewFeature } from '../../const/GeoserverFunc.js';
class AddFeature extends Component {
constructor(props) {
super(props);
this.state = {
// dataArr: null,
objToSave: null,
isReady: false
}
}
componentDidMount() {
const { columns, addFeatureValue } = this.props;
console.log('columns', columns);
let dataArr = [];
if (columns !== undefined) {
if (columns !== null) {
if (columns.length > 0) {
for (let i=0; i < columns.length; i++) {
// console.log('column_name', columns[i].column_name);
// let column_name = columns[i].column_name;
dataArr.push({
idx: i,
label: columns[i].column_name,
value: ''
})
}
}
}
}
console.log('dataArr', dataArr);
addFeatureValue.layer_attributes = dataArr;
console.log('addFeatureValue', addFeatureValue);
this.setState({ objToSave: addFeatureValue, isReady: true});
// this.setState({
// objToSave: this.props.addFeatureValue,
// dataArr: dataArr
// )};
}
renderInputs = () => {
const { objToSave } = this.state;
return objToSave.layer_attributes.map((item, index) => {
return (
<Row key={item.idx} className="row-input">
<Col xl={12} xs={12}>
<FormGroup>
<Label>{item.label}</Label>
<Input key={item.idx} type="text" name={item.label} placeholder="" value={item.value ? item.value : ''} onChange={this.handleChangeInputValue.bind(this, item.idx)} />
</FormGroup>
</Col>
</Row>
)
});
}
handleChangeInputValue = (idx, event) => {
event.preventDefault();
let value = event.target.value;
let { objToSave } = this.state;
let changedItem = findWhere(objToSave.layer_attributes, {idx: idx});
changedItem.value = value;
this.setState({objToSave: objToSave}, () => {
// console.log('objToSave now', this.state.objToSave);
});
}
saveFeature = async (e) => {
// let { addFeatureValue } = this.props;
e.preventDefault();
let { objToSave } = this.state;
console.log('objToSave', objToSave);
let response = await createNewFeature(objToSave);
console.log('saveFeature response', response);
if (response.success) {
alert(response.result);
this.props.toggleAddFeatureVisible();
this.props.closeDrawing();
this.props.finishDrawingAdd();
// window.location.reload();
}
else {
alert(response.result);
return;
}
}
render() {
const { objToSave, isReady } = this.state;
return(
<div>
<Modal isOpen={this.props.addFeatureVisible} toggle={this.props.toggleAddFeatureVisible}>
<ModalHeader toggle={this.props.toggleAddFeatureVisible}>{this.props.addFeatureTitle ? this.props.addFeatureTitle : 'Add Feature' }</ModalHeader>
<ModalBody>
{ isReady ?
<div className="add-input-container custom-scroll">
<Form onSubmit={(e) => this.saveFeature(e)}>
{ this.renderInputs() }
</Form>
</div>
: "Loading..."
}
{/*{objToSave.layer_attributes !== undefined ?
objToSave.layer_attributes !== null ?
<div className="add-input-container custom-scroll">
<Form>
{ this.renderInputs() }
</Form>
</div>
: 'Data is null'
: 'Data is undefined'
}*/}
</ModalBody>
<ModalFooter>
<Button color="success" onClick={(e) => this.saveFeature(e)}>Save</Button>
<Button color="secondary" onClick={this.props.toggleAddFeatureVisible}>Cancel</Button>
</ModalFooter>
</Modal>
</div>
)
}
}
export default AddFeature;

6
src/components/AddFeature/package.json

@ -0,0 +1,6 @@
{
"name": "AddFeature",
"version": "0.0.0",
"private": true,
"main": "./AddFeature.js"
}

101
src/components/AdmTree/AdmTree.css

@ -0,0 +1,101 @@
.adm-tree {
font-size: 12px;
}
.adm-tree-checkbox-container {
margin-left: 10px;
margin-bottom: 5px;
margin-top: 5px;
}
#adm-tree-container {
font-size: 12px;
/*height: 220px;*/
height: 440px;
overflow: auto;
padding: 0px !important;
}
.checkbox-opt {
font-size: 11px;
padding: 0px !important;
}
.ant-tree-child-tree > li:first-child {
padding-top: 0px !important;
}
.ant-tree li {
margin: 0;
padding: 0px 0 !important;
white-space: nowrap;
list-style: none;
outline: 0;
}
.adm-tree-checkbox-opt-container {
padding-left: 0px !important
}
.adm-dropdown-container {
z-index: 50;
position: absolute;
max-height: 350px;
border-radius: 5px;
background-color: rgba(0,0,0,0.5);
/*background-color: #ebebeb;*/
color: #ffffff;
/*color: #000000;*/
}
.adm-dropdown-title {
font-size: 14px;
margin-top: 0px;
margin-left: 10px;
margin-bottom: 5px;
font-weight: bold;
width: 200px;
}
.adm-dropdown-close {
float: right;
font-size: 18px;
font-weight: bold;
margin-left: 0px;
margin-right: 10px;
margin-top: -5px;
cursor: pointer;
}
.adm-dropdown-body {
max-height: 200px;
overflow: auto;
margin: 5px;
text-align: left;
}
.adm-dropdown-list {
cursor: pointer;
font-size: 14px;
padding: 5px;
margin-left: 0px;
text-align: left;
}
.adm-dropdown-icon {
margin-right: 5px;
}
.adm-dropdown-list:hover {
background-color: rgba(0,0,0,0.25);
}
.filter-coverage-container {
margin-left: 25px;
margin-top: 5px;
margin-bottom: 5px;
margin-right: 25px;
color: blue;
cursor: pointer;
/*float: right;*/
}

734
src/components/AdmTree/AdmTree.js

@ -0,0 +1,734 @@
import React, { Component, Fragment } from 'react';
import { Form, FormGroup, Label, Input, Row, Col, ListGroup, ListGroupItem } from 'reactstrap';
// Dropdown, DropdownToggle, DropdownMenu, DropdownItem } from 'reactstrap';
import { Tree, Input as SearchInput, Menu, Dropdown } from 'antd';
import { API_KOMINFO_GET_PROV, API_KOMINFO_GET_KABKOT, API_KOMINFO_GET_KEC, API_KOMINFO_GET_DESA } from '../../const/ApiConst.js';
import Loader from 'react-loader-spinner'
import "react-loader-spinner/dist/loader/css/react-spinner-loader.css"
import './AdmTree.css'
import '../../assets/css/customscroll.css'
import { findWhere } from 'underscore';
import { opt2G, opt3G, opt4G, netQuality2G, netQuality3G, netQuality4G, bts, mukim } from '../../const/Kominfo.js';
import { ToastContainer, toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
// npm install --save-dev @iconify/react @iconify/icons-mdi
import { Icon, InlineIcon } from '@iconify/react';
import mapMarker from '@iconify/icons-mdi/map-marker';
const { TreeNode } = Tree;
const { Search } = SearchInput;
const menu = (
<Menu>
<Menu.Item key="1">1st menu item</Menu.Item>
<Menu.Item key="2">2nd menu item</Menu.Item>
<Menu.Item key="3">3rd menu item</Menu.Item>
</Menu>
);
class AdmTree extends Component {
constructor(props) {
super(props);
this.state = {
treeData: [],
checkedKeys: [],
isReady: false,
admDropdownOpen: false,
admDropdownVisible: false,
allCheckNodes: [],
rightClickNodeTreeItem: {
pageX: "",
pageY: "",
id: "",
dropdownTitle: ""
},
searchAdmValue: ""
}
}
componentDidMount() {
this.getProv();
}
getProv = async () => {
const param = {
method: 'GET',
header: JSON.stringify({'Content-Type': 'application/json'}),
}
try {
const result = await fetch(API_KOMINFO_GET_PROV, param).then(response => response.json()).then(res => res)
// console.log(result);
if (result.data){
let treeData = [];
let checkedKeys = [];
let allProv = [];
let checkNodes = [];
for(let i=0; i < result.data.length; i++) {
treeData.push({
title: result.data[i].PROV,
key: i,
group: 'prov'
});
checkedKeys.push(i);
allProv.push(i);
let checkNode_ = {
props: {
dataRef: {
title: result.data[i].PROV,
key: i,
group: 'prov'
}
}
}
checkNodes.push(checkNode_);
}
this.setState({
// treeData: treeData,
// checkedKeys: checkedKeys,
allProv: allProv,
allCheckNodes: checkNodes,
isReady: true});
// console.log('checkNodes', checkNodes);
this.props.initAdmTree(treeData, checkNodes);
this.props.setCheckKeysAdm(checkedKeys);
this.props.setAllProv(allProv, true);
this.props.setToggleCheckAllValue(true);
} else {
}
} catch(err) {
console.log(err);
// alert(err.message.toString());
toast.warn(err.message.toString());
}
}
getChild = async (title, group, prov, kabkot, kec, childKey) => {
let URL = '';
let childGroup = '';
let childTitle = '';
let bodyParam = {};
if (group == 'prov') { // buat nyari kabkot
URL = API_KOMINFO_GET_KABKOT;
childGroup = 'kabkot';
childTitle = 'KAB_KOT';
bodyParam = {
[group]: title
};
}
else if (group == 'kabkot') { // buat nyari kecamatan
URL = API_KOMINFO_GET_KEC;
childGroup = 'kec';
childTitle = 'KEC';
bodyParam = {
[group]: title,
prov: prov
};
}
else if (group == 'kec') { // buat nyari desa
URL = API_KOMINFO_GET_DESA;
childGroup = 'desa';
childTitle = 'KEL_DES';
bodyParam = {
[group]: title,
prov: prov,
kabkot, kabkot
};
}
const param = {
method: 'POST',
header: JSON.stringify({'Content-Type': 'application/json'}),
body: JSON.stringify(bodyParam)
}
try {
console.log(URL);
const result = await fetch(URL, param).then(response => response.json()).then(res => res)
console.log(result);
if (result.data){
let treeData = [];
if (group == 'prov') { // buat nyari kabkot
for(let i=0; i < result.data.length; i++) {
treeData.push({
title: result.data[i][childTitle],
key: childKey+'-'+i,
group: childGroup,
prov: result.data[i].PROV,
kabkot: result.data[i].KAB_KOT
});
}
}
else if (group == 'kabkot') { // buat nyari kecamatan
for(let i=0; i < result.data.length; i++) {
treeData.push({
title: result.data[i][childTitle],
key: childKey+'-'+i,
group: childGroup,
prov: result.data[i].PROV,
kabkot: result.data[i].KAB_KOT,
kec: result.data[i].KEC
});
}
}
else if (group == 'kec') { // buat nyari desa
for(let i=0; i < result.data.length; i++) {
treeData.push({
title: result.data[i][childTitle],
key: childKey+'-'+i,
group: childGroup,
prov: result.data[i].PROV,
kabkot: result.data[i].KAB_KOT,
kec: result.data[i].KEC,
desa: result.data[i].KEL_DES
});
}
}
// this.setState({treeData: treeData, isReady: true});
// console.log('getChild func', treeData);
return treeData;
} else {
}
} catch(err) {
console.log(err);
// alert(err.message.toString());
toast.warn(err.message.toString());
}
}
/*onLoadData = treeNode =>
new Promise(resolve => {
if (treeNode.props.children) {
resolve();
return;
}
setTimeout(() => {
console.log('treeNode', treeNode);
let title = treeNode.props.dataRef.title;
let group = treeNode.props.dataRef.group;
let childKey = treeNode.props.eventKey;
let getChild = this.getChild(title, group, childKey);
console.log('getChild',getChild);
treeNode.props.dataRef.children = [
{ title: 'Child Node', key: `${treeNode.props.eventKey}-0` },
{ title: 'Child Node', key: `${treeNode.props.eventKey}-1` },
];
this.setState({
treeData: [...this.state.treeData],
});
resolve();
}, 1000);
});*/
onLoadData = async (treeNode) => {
console.log('onLoadData treeNode',treeNode);
if (treeNode.props.children) {
return;
}
let title = treeNode.props.dataRef.title;
let group = treeNode.props.dataRef.group;
let childKey = treeNode.props.eventKey;
let getChild = null;
// let getChild = await this.getChild(title, group, prov, kabkot, kec, childKey);
if (group == 'prov') {
getChild = await this.getChild(title, group, group, null, null, childKey);
}
else if (group == 'kabkot') {
let prov = treeNode.props.dataRef.prov;
getChild = await this.getChild(title, group, prov, group, null, childKey);
}
else if (group == 'kec') {
let prov = treeNode.props.dataRef.prov;
let kabkot = treeNode.props.dataRef.kabkot;
getChild = await this.getChild(title, group, prov, kabkot, group, childKey);
}
// let getChild = await this.getChild(title, group, childKey);
console.log('getChild',getChild);
if (getChild.length > 0) {
let treeDataChild = [];
let treeDataChildKeys = [];
if (group == 'prov') { // buat nyari kabkot
this.props.setExpandedTree('prov');
for (let i=0; i < getChild.length; i++) {
treeDataChild.push({
title: getChild[i].title,
key: getChild[i].key,
group: getChild[i].group,
prov: getChild[i].prov,
kabkot: getChild[i].kabkot
});
}
}
else if (group == 'kabkot') { // buat nyari kec
this.props.setExpandedTree('kab');
for (let i=0; i < getChild.length; i++) {
treeDataChild.push({
title: getChild[i].title,
key: getChild[i].key,
group: getChild[i].group,
prov: getChild[i].prov,
kabkot: getChild[i].kabkot,
kec: getChild[i].kec
});
}
}
else if (group == 'kec') { // buat nyari desa / kel_des
this.props.setExpandedTree('kec');
for (let i=0; i < getChild.length; i++) {
treeDataChild.push({
title: getChild[i].title,
key: getChild[i].key,
group: getChild[i].group,
prov: getChild[i].prov,
kabkot: getChild[i].kabkot,
kec: getChild[i].kec,
desa: getChild[i].desa,
isLeaf: true
});
}
}
if (treeNode.props.checked) {
for (let i=0; i < getChild.length; i++) {
treeDataChildKeys.push(getChild[i].key);
}
this.props.setAdmTreeData(treeNode, treeDataChild);
this.props.appendCheckedKeysAdm(treeDataChildKeys, treeNode.props.children)
}
else {
this.props.setAdmTreeData(treeNode, treeDataChild);
this.props.appendCheckedKeysAdm(treeDataChildKeys, [])
}
}
}
onInitData = (loadedKeys, e) => {
console.log('onInitData', e);
}
onCheckAdmTree = (checkedKeys, e) => {
console.log('onCheckAdmTree', checkedKeys);
console.log('onCheckAdmTree checkedNodes', e.checkedNodes);
this.props.setCheckKeysAdm(checkedKeys);
this.props.setCheckNodesAdm(e.checkedNodes);
// this.setState({ checkedKeysAdm, checkedNodesAdm: e.checkedNodes }, () => {
// let getCheckedValue = this.getCheckedValue();
// console.log('getCheckedValue', getCheckedValue);
// });
};
onCheckAllAdmTree = () => {
/*const { checkedKeys, allProv } = this.state;
const totalProv = 34;
if (checkedKeys.length > 0) {
this.setState({checkedKeys: [], toggleCheckAllValue: false})
}
else if (checkedKeys.length == 0) {
this.setState({checkedKeys: allProv, toggleCheckAllValue: true})
}*/
const { checkedKeysAdm, checkedKeysAdmTemp, toggleCheckAllValue, allProv } = this.props;
const { allCheckNodes } = this.state;
this.props.setToggleCheckAllValue(!toggleCheckAllValue);
}
onCheckOpt = (checkedKeys, e) => {
const { mode } = this.props;
this.props.setCheckKeysOpt(mode, checkedKeys);
}
onCheckQty = (checkedKeys) => {
const { mode } = this.props;
this.props.setCheckKeysQty(mode, checkedKeys);
}
onCheckBts = (checkedKeys) => {
this.props.setCheckKeysBts(checkedKeys);
}
/*onRightClickAdmTree = (callback) => {
console.log('onRightClickAdmTree', callback);
this.admDropdownToggle();
}*/
// tree right-click events on the list
onRightClickAdmTree = e => {
e.event.persist()
console.log('onRightClickAdmTree', e);
this.setState({
rightClickNodeTreeItem: {
pageX: e.event.pageX,
pageY: e.event.pageY,
id: e.node.props.dataRef.key,
dropdownTitle: e.node.props.dataRef.title
}
});
};
closeAdmDropdown = () => {
this.setState({
rightClickNodeTreeItem: {
pageX: "",
pageY: "",
id: "",
dropdownTitle: ""
}
})
}
getNodeTreeRightClickMenu = () => {
const { pageX, pageY, id, dropdownTitle } = { ...this.state.rightClickNodeTreeItem };
// const tmpStyle = {
// position: "absolute",
// left: `${pageX - 220}px`,
// top: `${pageY - 102}px`
// };
const tmpStyle = {
position:"absolute",
left: `${pageX - 50}px`,
top: `${pageY - 80}px`,
zIndex:10000,
width:"200px",
background:"#ededed",
borderRadius:"5px"
}
const menu = (
<div style={tmpStyle}>
<div className="adm-dropdown-container">
<span className="adm-dropdown-close" onClick={this.closeAdmDropdown}>x</span>
<div className="adm-dropdown-title">{ dropdownTitle }</div>
<div className="adm-dropdown-body custom-scroll">
<div className="adm-dropdown-list" onClick={this.goToLocation()}><Icon icon={mapMarker} className="adm-dropdown-icon" />Go to map</div>
</div>
</div>
</div>
);
return this.state.rightClickNodeTreeItem.dropdownTitle == "" ? "" : menu;
};
getCheckedValue = () => {
const { treeData, checkedKeys } = this.state;
let checkedData = [];
for(let i=0; i < checkedKeys.length; i++) {
let item = findWhere(treeData, {key: parseInt(checkedKeys[i])});
checkedData.push(item);
}
return checkedData;
}
renderCheckboxOpt = () => {
let checkboxes = [];
const { mode, checkedKeys2GOpt, checkedKeys3GOpt, checkedKeys4GOpt} = this.props;
if (mode == '2G') {
// checkboxes = opt2G;
return (
<Tree
className="checkbox-opt"
checkable={true}
checkedKeys={checkedKeys2GOpt}
onCheck={(checkedKeys2GOpt, e) => this.onCheckOpt(checkedKeys2GOpt, e)}
>
{this.renderTreeNodes(opt2G)}
</Tree>
)
}
else if (mode == '3G') {
// checkboxes = opt3G;
return (
<Tree
className="checkbox-opt"
checkable={true}
checkedKeys={checkedKeys3GOpt}
onCheck={(checkedKeys3GOpt) => this.onCheckOpt(checkedKeys3GOpt)}
>
{this.renderTreeNodes(opt3G)}
</Tree>
)
}
else {
// checkboxes = opt4G;
return (
<Tree
className="checkbox-opt"
checkable={true}
checkedKeys={checkedKeys4GOpt}
onCheck={(checkedKeys4GOpt) => this.onCheckOpt(checkedKeys4GOpt)}
>
{this.renderTreeNodes(opt4G)}
</Tree>
)
}
}
onExpand = expandedKeys => {
// console.log('onExpand', expandedKeys);
const {closeChart} = this.props
console.log("length", expandedKeys.length)
console.log("closeChart", closeChart)
if(expandedKeys.length === 1){
if(closeChart) {
document.getElementById('adm-tree-container').style.height = '320px'
} else {
document.getElementById('adm-tree-container').style.height = '120px'
}
} else {
if(closeChart) {
document.getElementById('adm-tree-container').style.height = '440px'
} else {
document.getElementById('adm-tree-container').style.height = '220px'
}
}
};
renderCheckboxQuality = () => {
let checkboxes = [];
const { mode, checkedKeys2GQty, checkedKeys3GQty, checkedKeys4GQty } = this.props;
if (mode == '2G') {
// checkboxes = netQuality2G;
return (
<Tree
className="checkbox-opt"
checkable={true}
checkedKeys={checkedKeys2GQty}
onCheck={(checkedKeys2GQty) => this.onCheckQty(checkedKeys2GQty)}
>
{this.renderTreeNodes(netQuality2G)}
</Tree>
)
}
else if (mode == '3G') {
// checkboxes = netQuality3G;
return (
<Tree
className="checkbox-opt"
checkable={true}
checkedKeys={checkedKeys3GQty}
onCheck={(checkedKeys3GQty) => this.onCheckQty(checkedKeys3GQty)}
>
{this.renderTreeNodes(netQuality3G)}
</Tree>
)
}
else {
// checkboxes = netQuality4G;
return (
<Tree
className="checkbox-opt"
checkable={true}
checkedKeys={checkedKeys4GQty}
onCheck={(checkedKeys4GQty) => this.onCheckQty(checkedKeys4GQty)}
>
{this.renderTreeNodes(netQuality4G)}
</Tree>
)
}
}
renderCheckboxBts = () => {
const { checkedKeysBts } = this.props;
return (
<Tree
className="checkbox-opt"
checkable={true}
checkedKeys={checkedKeysBts}
onCheck={(checkedKeysBts) => this.onCheckBts(checkedKeysBts)}
>
{this.renderTreeNodes(bts)}
</Tree>
)
}
/*renderTreeNodes = data =>
data.map(item => {
if (item.children) {
return (
<TreeNode title={item.title} key={item.key} dataRef={item}>
{this.renderTreeNodes(item.children)}
</TreeNode>
);
}
return <TreeNode key={item.key} {...item} dataRef={item} />;
})*/
renderTreeNodes = data =>
data.map(item => {
if (item.children) {
return (
<TreeNode title={item.title} key={item.key} dataRef={item}>
{this.renderTreeNodes(item.children)}
</TreeNode>
);
}
return (
<TreeNode key={item.key} {...item} dataRef={item} />
);
})
admDropdownToggle = () => {
// this.setState({admDropdownOpen: !this.state.admDropdownOpen})
this.setState({admDropdownVisible: !this.state.admDropdownVisible});
}
admMenu = () => {
const menu = (
<Menu>
<Menu.Item key="1">1st menu item</Menu.Item>
<Menu.Item key="2">2nd menu item</Menu.Item>
<Menu.Item key="3">3rd menu item</Menu.Item>
</Menu>
);
return menu;
}
goToLocation = () => {
}
onChangeSearchAdm = (e) => {
const { value } = e.target;
this.setState({searchAdmValue: value}, () => console.log('searchAdmValue:', this.state.searchAdmValue));
}
renderCheckboxMukim = () => {
const { checkedKeysMukim } = this.props;
return (
<Tree
className="checkbox-opt"
checkable={true}
checkedKeys={checkedKeysMukim}
onCheck={(checkedKeysMukim) => this.onCheckMukim(checkedKeysMukim)}
>
{this.renderTreeNodes(mukim)}
</Tree>
)
}
onCheckMukim = (checkedKeys) => {
this.props.setCheckKeysMukim(checkedKeys);
}
renderFilterCoverage = () => {
return <div className="filter-coverage-container" onClick={() => this.filterCoverage()}>Filter Coverage</div>
}
filterCoverage = () => {
this.props.toggleModalOptions();
}
render() {
const { isReady, checkedKeys, admDropdownOpen, admDropdownVisible, searchAdmValue } = this.state;
const { admTreeData, checkedKeysAdm, toggleCheckAllValue } = this.props;
if (!isReady) {
return (<div className="loader-container">
<Loader
type="TailSpin"
color="#36D7B7"
height={100}
width={100}
/>
</div>)
}
return (
<Fragment>
{/*This is future kominfo feature*/}
<Row>
<Col xs="12" sm="12" md="6" lg="6">
{ this.renderCheckboxMukim() }
</Col>
<Col xs="12" sm="12" md="6" lg="6" className="not-left-col">
{ this.renderCheckboxBts() }
</Col>
</Row>
{/*end This is future kominfo feature*/}
<Row>
<Col xs="12" sm="12" md="6" lg="6">
{ this.renderCheckboxOpt() }
</Col>
<Col xs="12" sm="12" md="6" lg="6" className="not-left-col">
{ this.renderCheckboxQuality() }
</Col>
</Row>
{/*<div className="adm-tree-checkbox-quality-container">
{ this.renderCheckboxQuality() }
</div>*/}
{/*<Row>
<Col xs="12" sm="12" md="12" lg="12">
{ this.renderCheckboxBts() }
</Col>
</Row>*/}
{/*This is future kominfo feature*/}
<Row>
<Col xs="12" sm="12" md="12" lg="12">
{ this.renderFilterCoverage() }
</Col>
</Row>
{/*end This is future kominfo feature*/}
<div className="adm-tree-checkbox-container">
{/*This is future kominfo feature*/}
<Search style={{ marginBottom: 8 }} placeholder="Search" onChange={this.onChangeSearchAdm} />
{/*end This is future kominfo feature*/}
<Form>
<FormGroup check inline>
<Label check>
<Input type="checkbox" checked={toggleCheckAllValue} onClick={() => this.onCheckAllAdmTree()}/> Toggle Select All Wilayah
</Label>
</FormGroup>
</Form>
</div>
<div id="adm-tree-container" className="custom-scroll">
<Tree
className="adm-tree"
loadData={this.onLoadData}
checkable={true}
checkedKeys={checkedKeysAdm}
onCheck={(checkedKeys, e) => this.onCheckAdmTree(checkedKeys, e)}
onRightClick={this.onRightClickAdmTree}
onSelect={this.closeAdmDropdown}
>
{/*<Dropdown overlay={this.admMenu} trigger={['contextMenu']} visible={admDropdownVisible} onVisibleChange={() => this.admDropdownToggle()}>*/}
{this.renderTreeNodes(admTreeData)}
{/*</Dropdown>*/}
</Tree>
{this.getNodeTreeRightClickMenu()}
</div>
</Fragment>
)
}
}
export default AdmTree;

544
src/components/AdmTree/AdmTree_backup.js

@ -0,0 +1,544 @@
import React, { Component, Fragment } from 'react';
import { Form, FormGroup, Label, Input, Row, Col } from 'reactstrap';
import { Tree, Input as SearchInput } from 'antd';
import { API_KOMINFO_GET_PROV, API_KOMINFO_GET_KABKOT, API_KOMINFO_GET_KEC, API_KOMINFO_GET_DESA } from '../../const/ApiConst.js';
import Loader from 'react-loader-spinner'
import "react-loader-spinner/dist/loader/css/react-spinner-loader.css"
import './AdmTree.css'
import '../../assets/css/customscroll.css'
import { findWhere } from 'underscore';
import { opt2G, opt3G, opt4G, netQuality2G, netQuality3G, netQuality4G } from '../../const/Kominfo.js';
import { ToastContainer, toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
const { TreeNode } = Tree;
const { Search } = SearchInput;
class AdmTree extends Component {
constructor(props) {
super(props);
this.state = {
treeData: [],
checkedKeys: [],
isReady: false
}
}
componentDidMount() {
this.getProv();
}
getProv = async () => {
const param = {
method: 'GET',
header: JSON.stringify({'Content-Type': 'application/json'}),
}
try {
const result = await fetch(API_KOMINFO_GET_PROV, param).then(response => response.json()).then(res => res)
// console.log(result);
if (result.data){
let treeData = [];
let checkedKeys = [];
let allProv = [];
let checkNodes = [];
for(let i=0; i < result.data.length; i++) {
treeData.push({
title: result.data[i].PROV,
key: i,
group: 'prov'
});
checkedKeys.push(i);
allProv.push(i);
let checkNode_ = {
props: {
dataRef: {
title: result.data[i].PROV,
key: i,
group: 'prov'
}
}
}
checkNodes.push(checkNode_);
}
this.setState({
// treeData: treeData,
// checkedKeys: checkedKeys,
allProv: allProv,
isReady: true});
// console.log('checkNodes', checkNodes);
this.props.initAdmTree(treeData, checkNodes);
this.props.setCheckKeysAdm(checkedKeys);
this.props.setAllProv(allProv, true);
this.props.setToggleCheckAllValue(true);
} else {
}
} catch(err) {
console.log(err);
// alert(err.message.toString());
toast.warn(err.message.toString());
}
}
getChild = async (title, group, prov, kabkot, kec, childKey) => {
let URL = '';
let childGroup = '';
let childTitle = '';
let bodyParam = {};
if (group == 'prov') { // buat nyari kabkot
URL = API_KOMINFO_GET_KABKOT;
childGroup = 'kabkot';
childTitle = 'KAB_KOT';
bodyParam = {
[group]: title
};
}
else if (group == 'kabkot') { // buat nyari kecamatan
URL = API_KOMINFO_GET_KEC;
childGroup = 'kec';
childTitle = 'KEC';
bodyParam = {
[group]: title,
prov: prov
};
}
else if (group == 'kec') { // buat nyari desa
URL = API_KOMINFO_GET_DESA;
childGroup = 'desa';
childTitle = 'KEL_DES';
bodyParam = {
[group]: title,
prov: prov,
kabkot, kabkot
};
}
const param = {
method: 'POST',
header: JSON.stringify({'Content-Type': 'application/json'}),
body: JSON.stringify(bodyParam)
}
try {
console.log(URL);
const result = await fetch(URL, param).then(response => response.json()).then(res => res)
console.log(result);
if (result.data){
let treeData = [];
if (group == 'prov') { // buat nyari kabkot
for(let i=0; i < result.data.length; i++) {
treeData.push({
title: result.data[i][childTitle],
key: childKey+'-'+i,
group: childGroup,
prov: result.data[i].PROV,
kabkot: result.data[i].KAB_KOT
});
}
}
else if (group == 'kabkot') { // buat nyari kecamatan
for(let i=0; i < result.data.length; i++) {
treeData.push({
title: result.data[i][childTitle],
key: childKey+'-'+i,
group: childGroup,
prov: result.data[i].PROV,
kabkot: result.data[i].KAB_KOT,
kec: result.data[i].KEC
});
}
}
else if (group == 'kec') { // buat nyari desa
for(let i=0; i < result.data.length; i++) {
treeData.push({
title: result.data[i][childTitle],
key: childKey+'-'+i,
group: childGroup,
prov: result.data[i].PROV,
kabkot: result.data[i].KAB_KOT,
kec: result.data[i].KEC,
desa: result.data[i].KEL_DES
});
}
}
// this.setState({treeData: treeData, isReady: true});
// console.log('getChild func', treeData);
return treeData;
} else {
}
} catch(err) {
console.log(err);
// alert(err.message.toString());
toast.warn(err.message.toString());
}
}
/*onLoadData = treeNode =>
new Promise(resolve => {
if (treeNode.props.children) {
resolve();
return;
}
setTimeout(() => {
console.log('treeNode', treeNode);
let title = treeNode.props.dataRef.title;
let group = treeNode.props.dataRef.group;
let childKey = treeNode.props.eventKey;
let getChild = this.getChild(title, group, childKey);
console.log('getChild',getChild);
treeNode.props.dataRef.children = [
{ title: 'Child Node', key: `${treeNode.props.eventKey}-0` },
{ title: 'Child Node', key: `${treeNode.props.eventKey}-1` },
];
this.setState({
treeData: [...this.state.treeData],
});
resolve();
}, 1000);
});*/
onLoadData = async (treeNode) => {
console.log('onLoadData treeNode',treeNode);
if (treeNode.props.children) {
return;
}
let title = treeNode.props.dataRef.title;
let group = treeNode.props.dataRef.group;
let childKey = treeNode.props.eventKey;
let getChild = null;
// let getChild = await this.getChild(title, group, prov, kabkot, kec, childKey);
if (group == 'prov') {
getChild = await this.getChild(title, group, group, null, null, childKey);
}
else if (group == 'kabkot') {
let prov = treeNode.props.dataRef.prov;
getChild = await this.getChild(title, group, prov, group, null, childKey);
}
else if (group == 'kec') {
let prov = treeNode.props.dataRef.prov;
let kabkot = treeNode.props.dataRef.kabkot;
getChild = await this.getChild(title, group, prov, kabkot, group, childKey);
}
// let getChild = await this.getChild(title, group, childKey);
console.log('getChild',getChild);
if (getChild.length > 0) {
let treeDataChild = [];
let treeDataChildKeys = [];
if (group == 'prov') { // buat nyari kabkot
this.props.setExpandedTree('prov');
for (let i=0; i < getChild.length; i++) {
treeDataChild.push({
title: getChild[i].title,
key: getChild[i].key,
group: getChild[i].group,
prov: getChild[i].prov,
kabkot: getChild[i].kabkot
});
}
}
else if (group == 'kabkot') { // buat nyari kec
this.props.setExpandedTree('kab');
for (let i=0; i < getChild.length; i++) {
treeDataChild.push({
title: getChild[i].title,
key: getChild[i].key,
group: getChild[i].group,
prov: getChild[i].prov,
kabkot: getChild[i].kabkot,
kec: getChild[i].kec
});
}
}
else if (group == 'kec') { // buat nyari desa / kel_des
this.props.setExpandedTree('kec');
for (let i=0; i < getChild.length; i++) {
treeDataChild.push({
title: getChild[i].title,
key: getChild[i].key,
group: getChild[i].group,
prov: getChild[i].prov,
kabkot: getChild[i].kabkot,
kec: getChild[i].kec,
desa: getChild[i].desa,
isLeaf: true
});
}
}
if (treeNode.props.checked) {
for (let i=0; i < getChild.length; i++) {
treeDataChildKeys.push(getChild[i].key);
}
this.props.setAdmTreeData(treeNode, treeDataChild);
this.props.appendCheckedKeysAdm(treeDataChildKeys, treeNode.props.children)
}
else {
this.props.setAdmTreeData(treeNode, treeDataChild);
this.props.appendCheckedKeysAdm(treeDataChildKeys, [])
}
}
}
onInitData = (loadedKeys, e) => {
console.log('onInitData', e);
}
onCheckAdmTree = (checkedKeys, e) => {
console.log('onCheckAdmTree', checkedKeys);
console.log('onCheckAdmTree checkedNodes', e.checkedNodes);
this.props.setCheckKeysAdm(checkedKeys);
this.props.setCheckNodesAdm(e.checkedNodes);
// this.setState({ checkedKeysAdm, checkedNodesAdm: e.checkedNodes }, () => {
// let getCheckedValue = this.getCheckedValue();
// console.log('getCheckedValue', getCheckedValue);
// });
};
onCheckAllAdmTree = () => {
/*const { checkedKeys, allProv } = this.state;
const totalProv = 34;
if (checkedKeys.length > 0) {
this.setState({checkedKeys: [], toggleCheckAllValue: false})
}
else if (checkedKeys.length == 0) {
this.setState({checkedKeys: allProv, toggleCheckAllValue: true})
}*/
const { checkedKeysAdm, checkedKeysAdmTemp, toggleCheckAllValue, allProv } = this.props;
this.props.setToggleCheckAllValue(!toggleCheckAllValue);
}
onCheckOpt = (checkedKeys, e) => {
const { mode } = this.props;
this.props.setCheckKeysOpt(mode, checkedKeys);
}
onCheckQty = (checkedKeys) => {
const { mode } = this.props;
this.props.setCheckKeysQty(mode, checkedKeys);
}
onRightClickAdmTree = (callback) => {
console.log('onRightClickAdmTree', callback);
}
getCheckedValue = () => {
const { treeData, checkedKeys } = this.state;
let checkedData = [];
for(let i=0; i < checkedKeys.length; i++) {
let item = findWhere(treeData, {key: parseInt(checkedKeys[i])});
checkedData.push(item);
}
return checkedData;
}
renderCheckboxOpt = () => {
let checkboxes = [];
const { mode, checkedKeys2GOpt, checkedKeys3GOpt, checkedKeys4GOpt} = this.props;
if (mode == '2G') {
// checkboxes = opt2G;
return (
<Tree
className="checkbox-opt"
checkable={true}
checkedKeys={checkedKeys2GOpt}
onCheck={(checkedKeys2GOpt, e) => this.onCheckOpt(checkedKeys2GOpt, e)}
>
{this.renderTreeNodes(opt2G)}
</Tree>
)
}
else if (mode == '3G') {
// checkboxes = opt3G;
return (
<Tree
className="checkbox-opt"
checkable={true}
checkedKeys={checkedKeys3GOpt}
onCheck={(checkedKeys3GOpt) => this.onCheckOpt(checkedKeys3GOpt)}
>
{this.renderTreeNodes(opt3G)}
</Tree>
)
}
else {
// checkboxes = opt4G;
return (
<Tree
className="checkbox-opt"
checkable={true}
checkedKeys={checkedKeys4GOpt}
onCheck={(checkedKeys4GOpt) => this.onCheckOpt(checkedKeys4GOpt)}
>
{this.renderTreeNodes(opt4G)}
</Tree>
)
}
/*return (
<Tree
className="checkbox-opt"
checkable={true}
checkedKeys={checkedKeysOpt}
onCheck={(checkedKeysOpt) => this.onCheckOpt(checkedKeysOpt)}
>
{this.renderTreeNodes(checkboxes)}
</Tree>
)*/
}
onExpand = expandedKeys => {
// console.log('onExpand', expandedKeys);
const {closeChart} = this.props
console.log("length", expandedKeys.length)
console.log("closeChart", closeChart)
if(expandedKeys.length === 1){
if(closeChart) {
document.getElementById('adm-tree-container').style.height = '320px'
} else {
document.getElementById('adm-tree-container').style.height = '120px'
}
} else {
if(closeChart) {
document.getElementById('adm-tree-container').style.height = '440px'
} else {
document.getElementById('adm-tree-container').style.height = '220px'
}
}
};
renderCheckboxQuality = () => {
let checkboxes = [];
const { mode, checkedKeys2GQty, checkedKeys3GQty, checkedKeys4GQty } = this.props;
if (mode == '2G') {
// checkboxes = netQuality2G;
return (
<Tree
className="checkbox-opt"
checkable={true}
checkedKeys={checkedKeys2GQty}
onCheck={(checkedKeys2GQty) => this.onCheckQty(checkedKeys2GQty)}
>
{this.renderTreeNodes(netQuality2G)}
</Tree>
)
}
else if (mode == '3G') {
// checkboxes = netQuality3G;
return (
<Tree
className="checkbox-opt"
checkable={true}
checkedKeys={checkedKeys3GQty}
onCheck={(checkedKeys3GQty) => this.onCheckQty(checkedKeys3GQty)}
>
{this.renderTreeNodes(netQuality3G)}
</Tree>
)
}
else {
// checkboxes = netQuality4G;
return (
<Tree
className="checkbox-opt"
checkable={true}
checkedKeys={checkedKeys4GQty}
onCheck={(checkedKeys4GQty) => this.onCheckQty(checkedKeys4GQty)}
>
{this.renderTreeNodes(netQuality4G)}
</Tree>
)
}
}
renderTreeNodes = data =>
data.map(item => {
if (item.children) {
return (
<TreeNode title={item.title} key={item.key} dataRef={item}>
{this.renderTreeNodes(item.children)}
</TreeNode>
);
}
return <TreeNode key={item.key} {...item} dataRef={item} />;
})
render() {
const { isReady, checkedKeys } = this.state;
const { admTreeData, checkedKeysAdm, toggleCheckAllValue } = this.props;
if (!isReady) {
return (<div className="loader-container">
<Loader
type="TailSpin"
color="#36D7B7"
height={100}
width={100}
/>
</div>)
}
return (
<Fragment>
<Row>
<Col xs="12" sm="12" md="6" lg="6">
{ this.renderCheckboxOpt() }
</Col>
<Col xs="12" sm="12" md="6" lg="6" className="not-left-col">
{ this.renderCheckboxQuality() }
</Col>
</Row>
{/*<div className="adm-tree-checkbox-quality-container">
{ this.renderCheckboxQuality() }
</div>*/}
<div className="adm-tree-checkbox-container">
<Form>
<FormGroup check inline>
<Label check>
<Input type="checkbox" checked={toggleCheckAllValue} onClick={() => this.onCheckAllAdmTree()}/> Toggle Select All Wilayah
</Label>
</FormGroup>
</Form>
</div>
<div id="adm-tree-container" className="custom-scroll">
<Tree
className="adm-tree"
loadData={this.onLoadData}
checkable={true}
checkedKeys={checkedKeysAdm}
onCheck={(checkedKeys, e) => this.onCheckAdmTree(checkedKeys, e)}
onRightClick={(callback) => this.onRightClickAdmTree(callback)}
>
{this.renderTreeNodes(admTreeData)}
</Tree>
</div>
</Fragment>
)
}
}
export default AdmTree;

136
src/components/AdmTree/example.js

@ -0,0 +1,136 @@
import React from 'react';
import ReactDOM from 'react-dom';
import 'antd/dist/antd.css';
import { Tree, Input } from 'antd';
const { Search } = Input;
const x = 3;
const y = 2;
const z = 1;
const gData = [];
const generateData = (_level, _preKey, _tns) => {
const preKey = _preKey || '0';
const tns = _tns || gData;
const children = [];
for (let i = 0; i < x; i++) {
const key = `${preKey}-${i}`;
tns.push({ title: key, key });
if (i < y) {
children.push(key);
}
}
if (_level < 0) {
return tns;
}
const level = _level - 1;
children.forEach((key, index) => {
tns[index].children = [];
return generateData(level, key, tns[index].children);
});
};
generateData(z);
const dataList = [];
const generateList = data => {
for (let i = 0; i < data.length; i++) {
const node = data[i];
const { key } = node;
dataList.push({ key, title: key });
if (node.children) {
generateList(node.children);
}
}
};
generateList(gData);
const getParentKey = (key, tree) => {
let parentKey;
for (let i = 0; i < tree.length; i++) {
const node = tree[i];
if (node.children) {
if (node.children.some(item => item.key === key)) {
parentKey = node.key;
} else if (getParentKey(key, node.children)) {
parentKey = getParentKey(key, node.children);
}
}
}
return parentKey;
};
class SearchTree extends React.Component {
state = {
expandedKeys: [],
searchValue: '',
autoExpandParent: true,
};
onExpand = expandedKeys => {
this.setState({
expandedKeys,
autoExpandParent: false,
});
};
onChange = e => {
const { value } = e.target;
const expandedKeys = dataList
.map(item => {
if (item.title.indexOf(value) > -1) {
return getParentKey(item.key, gData);
}
return null;
})
.filter((item, i, self) => item && self.indexOf(item) === i);
this.setState({
expandedKeys,
searchValue: value,
autoExpandParent: true,
});
};
render() {
const { searchValue, expandedKeys, autoExpandParent } = this.state;
const loop = data =>
data.map(item => {
const index = item.title.indexOf(searchValue);
const beforeStr = item.title.substr(0, index);
const afterStr = item.title.substr(index + searchValue.length);
const title =
index > -1 ? (
<span>
{beforeStr}
<span className="site-tree-search-value">{searchValue}</span>
{afterStr}
</span>
) : (
<span>{item.title}</span>
);
if (item.children) {
return { title, key: item.key, children: loop(item.children) };
}
return {
title,
key: item.key,
};
});
return (
<div>
<Search style={{ marginBottom: 8 }} placeholder="Search" onChange={this.onChange} />
<Tree
onExpand={this.onExpand}
expandedKeys={expandedKeys}
autoExpandParent={autoExpandParent}
treeData={loop(gData)}
/>
</div>
);
}
}
// ReactDOM.render(<SearchTree />, document.getElementById('container'));
export default SearchTree;

6
src/components/AdmTree/package.json

@ -0,0 +1,6 @@
{
"name": "AdmTree",
"version": "0.0.0",
"private": true,
"main": "./AdmTree.js"
}

74
src/components/BaseMap/BaseMap.css

@ -0,0 +1,74 @@
.basemap-container {
z-index: 50;
top: 60px;
right: 50px;
/*background-color: red;*/
/*padding: 100px;*/
position: absolute;
max-height: 350px;
border-radius: 5px;
background-color: rgba(0,0,0,0.5);
/*float: right;*/
color: #ffffff;
min-width: 180px;
justify-content: center;
}
.basemap-title {
font-size: 14px;
margin-top: 5px;
margin-left: 20px;
margin-bottom: 10px;
font-weight: bold;
}
.basemap-close {
float: right;
margin-right: 15px;
margin-top: -5px;
cursor: pointer;
}
.basemap-body {
max-height: 200px;
overflow: auto;
margin: 5px;
text-align: center;
}
.basemap-text-container {
display: block;
}
.basemap-graphic {
display: inline-block;
}
.basemap-text {
display: inline-block;
margin-left: 10px;
margin-right: 10px;
font-size: 12px;
}
.basemap-active {
border-color: #ffffff !important;
background-color: #ffffff !important;
}
.basemap-item {
display: inline-block;
padding: 10px;
border: solid;
border-radius: 5px;
margin: 2px;
cursor: pointer;
background-color: #d4d4d4;
margin-bottom: 10px;
text-align: center;
border-color: #d4d4d4;
}
.basemap-item-title {
color: #000000;
}

71
src/components/BaseMap/BaseMap.js

@ -0,0 +1,71 @@
import React, { Component } from 'react';
import './BaseMap.css';
import '../../assets/css/customscroll.css';
import { Row, Col } from 'reactstrap';
// import Legend from '@terrestris/react-geo/dist/Legend/Legend';
class BaseMap extends Component {
constructor(props) {
super(props);
this.state = {
activeBaseMap: ''
}
}
componentDidMount() {
this.getActiveBaseMap();
}
componentDidUpdate(prevState, prevProps) {
}
getActiveBaseMap = () => {
let activeBaseMap = '';
this.props.olmap.getLayers().forEach((layer, i) => {
if (layer.get('type') == 'base') {
console.log('activeBaseMap', layer.get('name'));
activeBaseMap = layer.get('name');
}
});
this.setState({activeBaseMap: activeBaseMap}, () => this.renderBaseMap());
}
changeBaseLayer = (layer) => {
this.setState({activeBaseMap: layer.get('name')}, () =>{
this.renderBaseMap();
this.props.changeBaseLayer(layer);
});
}
renderBaseMap = () => {
return this.props.baseLayers.map((item, index) => {
// console.log('activeBaseMap', this.state.activeBaseMap);
// console.log('layerName', item.get('name'));
// console.log('active?', this.state.activeBaseMap == item.get('name'));
return (
<div key={index} className={`basemap-item ${this.state.activeBaseMap == item.get('name') ? 'basemap-active' : ''}`} onClick={() => this.changeBaseLayer(item)}>
<img src={require(`../../assets/img/base_map/${item.get('imageName')}`)} alt={item.get('imageName')} width="75" height="50" /> <br />
<div className="basemap-item-title">{item.get('name')}</div>
</div>
)
})
}
render() {
const { toggleBaseMap } = this.props;
return (
<div className="basemap-container">
<div className="basemap-title">Change Base Map <span className="basemap-close" onClick={toggleBaseMap}>x</span></div>
<div className="basemap-body custom-scroll">
{ this.renderBaseMap() }
</div>
</div>
)
}
}
export default BaseMap;

6
src/components/BaseMap/package.json

@ -0,0 +1,6 @@
{
"name": "BaseMap",
"version": "0.0.0",
"private": true,
"main": "./BaseMap.js"
}

19
src/components/CreateNewLayer/CreateNewLayer.css

@ -0,0 +1,19 @@
.modal-dialog-newlayer {
width: 100%;
height: 100%;
}
.modal-content-newlayer {
width: 100%;
}
.modal-dialog-body {
max-height: 325px;
width: 100%;
overflow: auto;
}
.row-input {
margin-right: 0px !important;
margin-left: -10px !important;
}

348
src/components/CreateNewLayer/CreateNewLayer.js

@ -0,0 +1,348 @@
import React, { Component } from 'react';
import { Modal, ModalHeader, ModalBody, ModalFooter, Button, Row, Col, Form, FormGroup, Label, Input} from 'reactstrap';
import { Icon, InlineIcon } from '@iconify/react';
import removeCircle from '@iconify/icons-ion/remove-circle';
import { findWhere, without } from 'underscore';
import './CreateNewLayer.css';
import '../../assets/css/customscroll.css';
import { createNewLayer } from '../../const/GeoserverFunc.js';
class CreateNewLayer extends Component {
constructor(props) {
super(props);
this.state = {
layerName: '',
layerType: '',
columns: [],
disableCreateLayerButton: true
}
// this.handleChangeInputColumnName = this.handleChangeInputColumnName.bind(this);
// this.sendCreateNewLayer = this.sendCreateNewLayer.bind(this);
// this.checkBeforeSend = this.checkBeforeSend.bind(this);
}
componentDidMount() {
// console.log('CreateNewLayer resTableData', this.props.resTableData);
}
componentDidUpdate(prevProps, prevState) {
// this.checkBeforeSend();
// if (prevState.layerName !== this.state.layerName) {
// this.checkBeforeSend();
// }
// if (prevState.layerType !== this.state.layerType) {
// this.checkBeforeSend();
// }
// if (prevState.columns !== this.state.columns) {
// this.checkBeforeSend();
// }
}
addColumn = () => {
let { columns } = this.state;
let maxIdx = null;
let newIdx = null;
if (columns.length < 1) {
newIdx = 1;
}
else {
maxIdx = Math.max.apply(Math, columns.map((column) => column.idx));
console.log('maxIdx',maxIdx);
newIdx = maxIdx + 1;
}
let oneColumn = {
idx: newIdx,
column_name: "",
column_type: ""
}
this.setState({columns: [...columns, oneColumn]}, () => {
console.log(this.state.columns)
this.renderColumnAttribute();
});
}
renderColumnAttribute = () => {
let { columns } = this.state;
if (columns.length < 1) {
return null;
}
else {
return columns.map((item, index) => {
return (<Row key={item.idx} className="row-input">
<Col xl={5} xs={5}>
<FormGroup>
<Input type="text" name="column_name" id="column_name" placeholder="Input Column Name" value={item.column_name} onChange={this.handleChangeInputColumnName.bind(this, item.idx)} />
</FormGroup>
</Col>
<Col xl={5} xs={5}>
<FormGroup>
<Input type="select" name="column_type" id="column_type" value={item.column_type} onChange={this.handleChangeInputColumnType.bind(this, item.idx)}>
<option value="">Select column type</option>
<option value="integer">Integer</option>
<option value="character varying">Text</option>
<option value="double precision">Double</option>
</Input>
</FormGroup>
</Col>
<Col xl={2} xs={2}>
<FormGroup>
<Button color="danger" id="remove_column" size="sm" onClick={() => this.deleteColumn(item.idx)}><Icon icon={removeCircle} width={20} height={20} /></Button>
</FormGroup>
</Col>
</Row>)
})
// for (let i=0; i < columns.length; i++) {
// return (
// <Row key={columns.idx}>
// <Col xl={5} xs={5}>
// <FormGroup>
// <Input type="text" name="column_name" id="column_name" placeholder="Input Column Name" />
// </FormGroup>
// </Col>
// <Col xl={5} xs={5}>
// <FormGroup>
// <Input type="select" name="column_type" id="column_type">
// <option>Select column type</option>
// <option value="integer">Integer</option>
// <option value="text">Text</option>
// <option value="double">Double</option>
// </Input>
// </FormGroup>
// </Col>
// <Col xl={2} xs={2}>
// <FormGroup>
// <Button color="danger" id="remove_column" size="sm"><Icon icon={removeCircle} width={20} height={20} /></Button>
// </FormGroup>
// </Col>
// </Row>
// )
// }
}
}
deleteColumn = (idx) => {
console.log('deleteColumn', idx);
let { columns } = this.state;
console.log('columns', columns);
let deletedItem = findWhere(columns, {idx: idx});
console.log(deletedItem);
let afterRemove = without(columns, deletedItem);
console.log(console.log('afterRemove', afterRemove));
this.setState({columns: afterRemove});
}
handleChangeInputLayerName(event) {
// const validation = !/[0-9a-zA-Z-_]/.test(String.fromCharCode(event.which));
// console.log('validation', validation);
// const value = event.target.value.split(" ").join("");
let value = event.target.value;
// value = value.replace(/[^A-Za-z_]/gi, "");
// value = value.replace(/[^\w]/gi, "");
value = value.replace(/[^\w]/gi, "");
// if (validation) { return false; }
this.setState({layerName: value}, () => console.log('layerName', this.state.layerName));
}
handleChangeInputLayerType(event) {
const value = event.target.value.split(" ").join("");
this.setState({layerType: value}, () => console.log('layerType', this.state.layerType));
}
handleChangeInputColumnName(idx, event) {
// dicari state columns terus dicari idx nya, kemudian set text nya
let { columns } = this.state;
let changedItem = findWhere(columns, {idx: idx});
// let value = event.target.value.split(" ").join("");
let value = event.target.value;
// value = value.replace(/[^A-Za-z0-9_]/gi, "");
value = value.replace(/[^\w]/gi, "");
changedItem.column_name = value;
console.log('changedItem', changedItem);
this.setState({columns: columns});
console.log('columns', this.state.columns);
}
handleChangeInputColumnType(idx, event) {
let { columns } = this.state;
let changedItem = findWhere(columns, {idx: idx});
// let value = event.target.value.split(" ").join("");
let value = event.target.value;
changedItem.column_type = value;
console.log('changedItem', changedItem);
this.setState({columns: columns});
console.log('columns', this.state.columns);
}
preventSpace(e) {
// Prevent space in attribute name
// $('input[name^="column_name"]').on("keypress", function(e) {
// if(!/[0-9a-zA-Z-_]/.test(String.fromCharCode(e.which)))
// return false;
// });
console.log('event keypress',e);
// console.log(!/[0-9a-zA-Z-_]/.test(String.fromCharCode(e.which)));
// if(!/[0-9a-zA-Z-_]/.test(String.fromCharCode(e.which))) {
// return false;
// }
}
// checkBeforeSend = () => {
// // make sure no empty fields
// // enable disableCreateLayerButton if no empty fields
// const { layerName, layerType, columns, disableCreateLayerButton } = this.state;
// let toEnableValue = false;
// if (layerName !== "" && layerType !== "") {
// if (columns.length > 0) {
// for (let i = 0; i < columns.length; i++) {
// if (columns[i].column_name === "") {
// toEnableValue = false;
// // return false;
// }
// else if (columns[i].column_type === "") {
// toEnableValue = false;
// // return false;
// }
// else {
// toEnableValue = true;
// // return true;
// }
// }
// }
// else {
// toEnableValue = false;
// // return false;
// }
// }
// console.log('toEnableValue', toEnableValue);
// if (toEnableValue === true) {
// // this.setState({disableCreateLayerButton: toEnableValue});
// // this.enableCreateLayerButton();
// console.log('enabling create layer button....')
// }
// }
// enableCreateLayerButton = () => {
// // this.setState({disableCreateLayerButton: true});
// console.log('enabling create layer button....')
// }
sendCreateNewLayer = async () => {
const { layerName, layerType, columns } = this.state;
let reqPayload = {
layer_name: layerName,
layer_type: layerType,
columns: columns
}
if (layerName === '') {
alert("Please input the layer name");
return;
}
if (layerType === '') {
alert("Please input the layer type");
return;
}
if (columns.length < 1) {
alert("Please add at least one attribute column");
return;
}
if (columns.length > 0) {
for (let i = 0; i < columns.length; i++) {
if (columns[i].column_name === '') {
alert("Please make sure attibute column name is filled")
return;
}
if (columns[i].column_type === '') {
alert("Please make sure attibute column type is filled")
return;
}
}
}
let processCreateNewLayer = await createNewLayer(reqPayload);
console.log('sendCreateNewLayer',processCreateNewLayer);
alert("Success sending create new layer");
}
render() {
return (
<Modal isOpen={this.props.createNewLayerVisible} toggle={this.props.toggleCreateNewLayer} className="modal-dialog-newlayer" contentClassName="modal-content-newlayer">
<ModalHeader toggle={this.props.toggleCreateNewLayer}>{this.props.createNewLayerTitle ? this.props.createNewLayerTitle : 'Create New Layer'}</ModalHeader>
<ModalBody>
<div className="modal-dialog-body custom-scroll">
{/*<div className="modal-body-wrap">*/}
{/*<div className="row">*/}
{/*<div className="col-md-12">*/}
{/*<Row>
<Col xl={6} xs={6}>
</Col>
</Row>*/}
<Form>
<FormGroup>
<Label for="layer_name">Layer Name</Label>
<Input type="text" name="layer_name" id="layer_name" placeholder="Input Layer Name" value={this.state.layerName} onChange={this.handleChangeInputLayerName.bind(this)}/>
</FormGroup>
<FormGroup>
<Label for="layer_type">Layer Type</Label>
<Input type="select" name="layer_type" id="layer_type" value={this.state.layerType} onChange={this.handleChangeInputLayerType.bind(this)}>
<option value="">Select layer type</option>
<option value="point">Point</option>
<option value="linestring">LineString</option>
<option value="polygon">Polygon</option>
</Input>
</FormGroup>
</Form>
<FormGroup>
<Label for="attributes">Attributes</Label>
<Row className="row-input">
<Col xl={5} xs={5}>
<FormGroup>
<Label for="column_name">Column Name</Label>
</FormGroup>
</Col>
<Col xl={5} xs={5}>
<FormGroup>
<Label for="column_type">Column Type</Label>
</FormGroup>
</Col>
<Col xl={2} xs={2}>
<FormGroup>
<Label for="remove_column">{' '}</Label>
</FormGroup>
</Col>
</Row>
{ this.renderColumnAttribute() }
<Row className="row-input">
<Col xl={9} xs={9}></Col>
<Col xl={3} xs={3}>
<FormGroup>
<Button color="primary" id="add_column" size="sm" onClick={() => this.addColumn()}>Add Column</Button>
</FormGroup>
</Col>
</Row>
</FormGroup>
{/*</div>*/}
{/*</div>*/}
{/*</div>*/}
</div>
</ModalBody>
<ModalFooter>
{/*<Button color="success" onClick={this.sendCreateNewLayer} disabled={this.state.disableCreateLayerButton}>Create</Button>{' '}*/}
<Button color="success" onClick={() => this.sendCreateNewLayer()} >Create</Button>{' '}
<Button color="secondary" onClick={this.props.toggleCreateNewLayer}>Cancel</Button>
</ModalFooter>
</Modal>
)
}
}
export default CreateNewLayer;

6
src/components/CreateNewLayer/package.json

@ -0,0 +1,6 @@
{
"name": "CreateNewLayer",
"version": "0.0.0",
"private": true,
"main": "./CreateNewLayer.js"
}

25
src/components/CustomModal/CustomModal.js

@ -0,0 +1,25 @@
import React, { Component } from 'react';
import { Modal, ModalHeader, ModalBody, ModalFooter, Button,
UncontrolledTooltip, UncontrolledDropdown, DropdownToggle, DropdownMenu, DropdownItem } from 'reactstrap';
class CustomModal extends Component {
constructor(props) {
super(props)
}
render() {
return(
<Modal isOpen={this.props.mapTableModalVisible} toggle={this.props.toggleMapTable} className="modal-dialog-data" contentClassName="modal-content-data">
<ModalHeader toggle={this.props.toggleMapTable}>{this.props.mapTableTitle}</ModalHeader>
<ModalBody>
Lorem ipsum.....
</ModalBody>
<ModalFooter>
<Button color="secondary" onClick={this.props.toggleMapTable}>Cancel</Button>
</ModalFooter>
</Modal>
)
}
}
export default CustomModal;

6
src/components/CustomModal/package.json

@ -0,0 +1,6 @@
{
"name": "CustomModal",
"version": "0.0.0",
"private": true,
"main": "./CustomModal.js"
}

52
src/components/DailyInfo/DailyInfo.css

@ -0,0 +1,52 @@
.daily-info-container {
margin-top: -10px;
}
.daily-info-container-empty {
/*z-index: 9999;*/
/*position: fixed;*/
/*height: 200px;*/
}
.daily-info-group-container {
margin-bottom: -10px;
}
.daily-info-group-title {
font-weight: 700;
}
.daily-info-list {
width: 100%;
display: inline-block;
padding-left: 10px;
padding-right: 5px;
padding-top: 7px;
padding-bottom: 7px;
margin-bottom: 5px;
border-radius: 10px;
background-color: #f2f2f2;
cursor: pointer;
}
.daily-info-list:hover {
background-color: #d9d9d9;
}
.daily-info-name {
width: 70%;
display: inline-block;
font-weight: 700;
font-size: 12px;
}
.daily-info-count {
width: 30%;
display: inline-block;
text-align: center;
}
.daily-info-badge {
font-size: 14px !important;
text-align: right;
}

655
src/components/DailyInfo/DailyInfo.js

@ -0,0 +1,655 @@
import * as React from 'react';
import { Row, Col, Badge } from 'reactstrap';
import './DailyInfo.css';
import '../../assets/css/customscroll.css';
import { formatLabel, COLUMN_DAILY_INFO_TABLE } from '../../const/CustomFunc.js'
import { getDailyInfoApi, requestTableDailyInfoApi } from '../../const/GeohrApiFunc.js';
import ContentLoader from 'react-content-loader'
import {
AT_TRIP_COLOR,
AT_CUSTOMER_COLOR,
AT_OFFICE_COLOR,
PRESENT_COLOR,
ABSENT_COLOR,
TOTAL_ATTENDANCE_COLOR,
ACHIEVE_COLOR,
NOT_ACHIEVE_COLOR,
DONE_COLOR,
NOT_YET_COLOR,
IZIN_COLOR,
TOTAL_COLOR,
RED_COLOR,
ORANGE_COLOR,
GREEN_COLOR,
DARK_GREY_COLOR,
BLUE_COLOR,
PURPLE_COLOR,
BROWN_COLOR,
YELLOW_COLOR,
WHITE_COLOR,
BLACK_COLOR
} from '../../const/AppConst.js'
import axios from 'axios';
import { API_GEOHR_KARYAWAN, API_DAILY_INFO, API_DAILY_INFO_DETAIL, DASHBOARD_PROYEK_SEARCH, PROYEK_SEARCH } from '../../const/ApiConst';
// import DialogBottom from './DialogBottom'
import { toast } from 'react-toastify';
import moment from 'moment';
const id_org = window.localStorage.getItem('id_org');
// const token = window.localStorage.getItem('token');
// const config = {
// headers:
// {
// "Authorization": `Bearer ${token}`,
// "Content-type": `application/json`
// }
// };
class DailyInfo extends React.Component {
constructor(props) {
super(props);
this.state = {
menu: null,
isReady: false,
sumPresensi: 0,
sumAbsensi: 0,
sumIzin: 0,
sumTracked: 0,
sumUntracked: 0,
sumEmployee: 0,
sumPanicBtn: 0,
dataNyPresence: [],
dataPresence: [],
dataPermission: [],
dataAbsent: [],
openDialogBottom: false,
itemDialog: [],
dataTableDialog: [],
sumTelat: 0,
sumTanpaKet: 0,
dataTelat: [],
dataTanpaKet: [],
dataAbsensi:[],
dataPanicBtn: [],
dataEmployee: [],
totalProyek: 0,
planning: 0,
realisasi: 0,
status_project: {
good: 0,
warning: 0,
critical: 0
},
waspang_status: {
presensi: 0,
absensi: 0
},
panic_button: 0
}
}
async componentDidMount() {
// this.getTotalProyek();
// this.getDailyInfo()
// this.getDailyEmployee();
// this.setState({ isReady: true })
}
componentDidUpdate(prevProps, prevState) {
}
getDailyInfo = async () => {
const payload = {
"columns": [
{"name": "created_at","logic_operator": "range","value": `${moment().utc().format('YYYY-MM-DD')} 00:00:00`,"value1": `${moment().utc().format('YYYY-MM-DD')} 23:59:59`,"operator": "AND"}
],
"paging": {"start": 0,"length": -1}
}
const config = {
method: 'POST', // *GET, POST, PUT, DELETE, etc.
// mode: 'cors', // no-cors, *cors, same-origin
// cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
// credentials: 'same-origin', // include, *same-origin, omit
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer '+window.localStorage.getItem('token')
// 'Content-Type': 'application/x-www-form-urlencoded',
},
// redirect: 'follow', // manual, *follow, error
// referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
body: JSON.stringify(payload) // body data type must match "Content-Type" header
}
try {
const result = await fetch(DASHBOARD_PROYEK_SEARCH, config).then(response => response.json()).then(res => res);
console.log('getDailyInfo result', result);
if (result.code === 200 && result.data) {
const dataSum = result.data;
this.setState({
planning: dataSum.planning,
realisasi: dataSum.realisasi,
status_project: dataSum.status_project,
waspang_status: dataSum.waspang_status,
panic_button: dataSum.panic_button,
isReady: true
});
}
// const result = await axios
// .get(DASHBOARD_PROYEK, config)
// .then(res => res)
// .catch((error) => error.response);
// console.log('result', result);
// if (result && result.data && result.data.code == 200) {
// const dataSum = result.data;
// this.setState({
// planning: dataSum.planning,
// realisasi: dataSum.realisasi,
// status_project: dataSum.status_project,
// waspang_status: dataSum.waspang_status,
// panic_button: dataSum.panic_button,
// isReady: true
// });
// }
}
catch (e) {
console.log('error getDailyInfo', e);
// return false;
}
}
getTotalProyek = async () => {
const payload = {
}
const config = {
method: 'POST', // *GET, POST, PUT, DELETE, etc.
// mode: 'cors', // no-cors, *cors, same-origin
// cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
// credentials: 'same-origin', // include, *same-origin, omit
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer '+window.localStorage.getItem('token')
// 'Content-Type': 'application/x-www-form-urlencoded',
},
// redirect: 'follow', // manual, *follow, error
// referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
body: JSON.stringify(payload) // body data type must match "Content-Type" header
}
try {
const result = await fetch(PROYEK_SEARCH, config).then(response => response.json()).then(res => res);
console.log('getDailyInfo result', result);
if (result.code === 200 && result.data) {
const dataSum = result.data;
this.setState({
totalProyek: result.data.length,
isReady: true
});
}
// const result = await axios
// .get(PROYEK_LIST, config)
// .then(res => res)
// .catch((error) => error.response);
// if (result && result.data && result.data.code == 200) {
// const dataSum = result.data;
// this.setState({
// totalProyek: result.data.length,
// isReady: true
// });
// }
}
catch (e) {
console.log('error getDailyInfo', e);
// return false;
}
}
openDialogBottom = async(item) => {
let data = []
const { dataPresence, dataAbsensi, dataEmployee, dataPanicBtn, dataTelat, dataTanpaKet } = this.state
if (item.key === "presensi") {
data = dataPresence
} else if (item.key === "absensi") {
data = dataAbsensi
} else if (item.key === "panic button") {
data = dataPanicBtn
} else if (item.key === "total dengan keterangan") {
data = dataTelat
} else if (item.key === "total tanpa keterangan") {
data = dataTanpaKet
} else if (item.key === "total karyawan") {
data = dataEmployee
}
this.setState({ openDialogBottom: true, itemDialog: item, dataTableDialog: data })
}
closeDialogBottom = () => {
this.setState({ openDialogBottom: false })
}
// getListDailyInfo = () => {
// let menu = [
// {
// "id": 1,
// "title": "TOTAL KARYAWAN",
// "key": "total karyawan",
// "total": this.state.sumEmployee,
// "color": TOTAL_COLOR,
// "text_color": WHITE_COLOR
// },
// {
// "id": 2,
// "title": "HADIR",
// "key": "presensi",
// "total": this.state.sumPresensi,
// "color": PRESENT_COLOR,
// "text_color": WHITE_COLOR
// },
// {
// "id": 3,
// "title": "TIDAK HADIR",
// "key": "izin",
// "total": this.state.sumAbsensi,
// "color": IZIN_COLOR,
// "text_color": WHITE_COLOR
// },
// {
// "id": 4,
// "title": "KARYAWAN TELAT",
// "key": "total dengan keterangan",
// "total": this.state.sumTelat,
// "color": NOT_YET_COLOR,
// "text_color": WHITE_COLOR
// },
// {
// "id": 5,
// "title": "KARYAWAN TANPA KETERANGAN",
// "key": "total tanpa keterangan",
// "total": this.state.sumTanpaKet,
// "color": DONE_COLOR,
// "text_color": WHITE_COLOR
// },
// {
// "id": 6,
// "title": "PANIK BUTTON",
// "key": "panic button",
// "total": this.state.sumPanicBtn,
// "color": ABSENT_COLOR,
// "text_color": WHITE_COLOR
// }
// ]
// return menu;
// }
// renderDailyInfo = () => {
// const list = this.getListDailyInfo() || [];
// return (
// list.map((item) => {
// return (
// <div onClick={() => this.openTable(item)} key={item.id} className="daily-info-list">
// <div className="daily-info-name">
// {item.title}
// </div>
// <div className="daily-info-count">
// <Badge color="primary" pill className="daily-info-badge" style={{ backgroundColor: item.color }}>{item.total}</Badge>
// </div>
// </div>
// )
// })
// )
// }
getListDailyInfo = () => {
let menu = [
{
"id": 1,
"title": "PROYEK",
"key": "proyek",
"total": this.state.totalProyek,
"color": BROWN_COLOR,
"text_color": WHITE_COLOR
},
{
"id": 2,
"title": "PLANNING",
"key": "plannng",
"total": this.state.planning,
"color": DARK_GREY_COLOR,
"text_color": WHITE_COLOR
},
{
"id": 3,
"title": "REALISASI",
"key": "realisasi",
"total": this.state.realisasi,
"color": BLUE_COLOR,
"text_color": WHITE_COLOR
},
{
"id": 4,
"title": "STATUS PROJECT",
"key": "status_project",
"total": undefined,
"color": DONE_COLOR,
"text_color": WHITE_COLOR,
"children": [
{
"id": 1,
"title": "Aman",
"key": "status_project_good",
"total": this.state.status_project.good,
"color": GREEN_COLOR,
"text_color": WHITE_COLOR
},
{
"id": 2,
"title": "Alert",
"key": "status_project_warning",
"total": this.state.status_project.warning,
"color": YELLOW_COLOR,
"text_color": DARK_GREY_COLOR
},
{
"id": 3,
"title": "Critical",
"key": "status_project_critical",
"total": this.state.status_project.critical,
"color": RED_COLOR,
"text_color": WHITE_COLOR
}]
},
{
"id": 5,
"title": "WASPANG STATUS",
"key": "waspang_status",
"total": undefined,
"color": IZIN_COLOR,
"text_color": WHITE_COLOR,
"children": [
{
"id": 1,
"title": "Presensi",
"key": "waspang_status_presensi",
"total": this.state.waspang_status.presensi,
"color": GREEN_COLOR,
"text_color": WHITE_COLOR
},
{
"id": 2,
"title": "Absensi",
"key": "waspang_status_absensi",
"total": this.state.waspang_status.absensi,
"color": ORANGE_COLOR,
"text_color": WHITE_COLOR
}],
},
{
"id": 6,
"title": "PANIC BUTTON",
"key": "panic_button",
"total": this.state.panic_button,
"color": PURPLE_COLOR,
"text_color": WHITE_COLOR
},
]
return menu;
}
renderDailyInfo = () => {
const list = this.getListDailyInfo() || [];
return this.renderChildDailyInfo(list);
}
renderChildDailyInfo = (data) => {
return (
data.map((item) => {
return (
<div key={item.id} className="daily-info-list">
<div className="daily-info-name">
{item.title}
</div>
<div className="daily-info-count">
<Badge color="primary" pill className="daily-info-badge" style={{ backgroundColor: item.color, color: item.text_color }}>{item.total !== undefined ? item.total : null}</Badge>
</div>
{ item.children ? this.renderChildDailyInfo(item.children) : null }
</div>
)
})
)
}
// requestTableDailyInfoApi = async (table_type) => {
// const formData = new FormData();
// // formData.append('start', 0);
// // formData.append('length', 100);
// formData.append('table_type', table_type);
// // if(this.state.search!==""){
// // formData.append('value', this.state.search);
// // }
// const start = 0;
// const length = 100;
// const param = {
// method: 'POST',
// header: JSON.stringify({'Content-Type': 'multipart/form-data'}),
// body: formData
// }
// try {
// const result = await fetch(API_DAILY_INFO_DETAIL(start,length), param).then(response => response.json()).then(res => res);
// console.log('requestTableDailyInfoApi result', result);
// if (result.code_status === 200 && result.data) {
// return result.data;
// }
// else {
// return null;
// }
// }
// catch (e) {
// console.log('error get', e);
// toast.warn(e.toString());
// return null;
// }
// }
openTable = async (item) => {
const { dataPresence, dataAbsensi, dataEmployee, dataPanicBtn, dataTelat, dataTanpaKet} = this.state
console.log('openTable', item);
await this.props.setIsProcessing(true);
this.props.removeLayerByName('routeLayer'); // remove the previous routeLayer
let nameUpperCase = item.title.toUpperCase();
this.props.setMapTableTitle(nameUpperCase);
// let table = await requestTableDailyInfoApi(item);
// console.log('[DailyInfo] openTable table', table);
let column = [];
let data = null;
// const editFormatter = () => {
// return (
// <div>
// <i className="cil-search fa-lg" style={{ color: 'lightblue', marginRight: '10px', cursor: "pointer" }} onClick={() => console.log('goToFeature')}></i>
// </div>
// )
// }
// if (table && table.length > 0) {
// let oneRow = table[0];
// let optionCell = {
// dataField: '_option_',
// text: 'Action',
// formatter: editFormatter
// }
// for (let key in oneRow) {
// column.push({
// "dataField": key,
// "text": formatLabel(key)
// })
// }
// data = table;
// }
// await this.requestTableDailyInfoApi(item.key);
// let table_type = '';
// if(type==="presensi"){
// table_type = "hadir";
// }else if(type==="panic button"){
// table_type = "panik_button";
// }else if(type==="absent"){
// table_type = "tidak_hadir";
// }else if(type==="late"){
// table_type = "karyawan_telat";
// }else if(type==="without_ket"){
// table_type = "karyawan_tanpa_keterangan";
// }else if(type==="sum_employee"){
// table_type = "total_karyawan";
// }
let table_type = '';
// if (item.key === "presensi") {
// data = dataPresence
// } else if (item.key === "absensi") {
// data = dataAbsensi
// } else if (item.key === "panic button") {
// data = dataPanicBtn
// } else if (item.key === "total dengan keterangan") {
// data = dataTelat
// } else if (item.key === "total tanpa keterangan") {
// data = dataTanpaKet
// } else if (item.key === "total karyawan") {
// data = dataEmployee
// }
if (item.key === "total karyawan") {
table_type = "total_karyawan";
}
else if (item.key === "presensi") {
table_type = "hadir";
}
else if (item.key === "izin") {
table_type = "tidak_hadir";
}
else if (item.key === "total dengan keterangan") {
table_type = "karyawan_telat";
}
else if (item.key === "total tanpa keterangan") {
table_type = "karyawan_tanpa_keterangan";
}
else if (item.key === "panic button") {
table_type = "panik_button";
}
this.props.setTableType(table_type)
// let dataRes = await requestTableDailyInfoApi(table_type);
// this.props.setMapTableData(dataRes)
if (!this.props.mapTableModalVisible) {
this.props.toggleMapTable();
}
await this.props.setIsProcessing(false);
}
render() {
const { openDialogBottom, itemDialog, dataTableDialog, isReady } = this.state;
if (!isReady) {
return (
<div className="daily-info-container-empty">
<ContentLoader
speed={2}
width="100%"
height="200"
viewBox="0 0 200 200"
backgroundColor="#f3f3f3"
foregroundColor="#ecebeb"
>
<rect x="0" y="0" rx="6" ry="6" width="100" height="25" />
<rect x="0" y="30" rx="10" ry="10" width="100%" height="40" />
<rect x="0" y="75" rx="10" ry="10" width="100%" height="40" />
<rect x="0" y="120" rx="10" ry="10" width="100%" height="40" />
<rect x="0" y="175" rx="0" ry="0" width="100%" height="2" />
</ContentLoader>
<ContentLoader
speed={2}
width="100%"
height="200"
viewBox="0 0 200 200"
backgroundColor="#f3f3f3"
foregroundColor="#ecebeb"
>
<rect x="0" y="0" rx="6" ry="6" width="100" height="25" />
<rect x="0" y="30" rx="10" ry="10" width="100%" height="40" />
<rect x="0" y="75" rx="10" ry="10" width="100%" height="40" />
<rect x="0" y="120" rx="10" ry="10" width="100%" height="40" />
<rect x="0" y="175" rx="0" ry="0" width="100%" height="2" />
</ContentLoader>
</div>
)
}
return (
<div style={{ width: "100%", height: "100%" }} className="daily-info-container">
{/* {openDialogBottom && (
<DialogBottom
isCloseDialog={this.closeDialogBottom}
itemDialog={itemDialog}
dataTable={dataTableDialog}
/>
)} */}
<div className="daily-info-group-container">
{/*<h6 className="daily-info-group-title">Status</h6> */}
{this.renderDailyInfo()}
</div>
{/* {menu && menu.length > 0 && menu.map((menuItem, index) => {
return (
<div className="daily-info-group-container" key={index}>
<h6 className="daily-info-group-title">{menuItem.title.toUpperCase()}</h6>
{menuItem.children.length > 0 && menuItem.children.map((childMenuItem, index) => {
return (
<div className="daily-info-list" key={index} onClick={() => this.openTable(childMenuItem)} key={index}>
<div className="daily-info-name">
{childMenuItem.name.toUpperCase()}
</div>
<div className="daily-info-count">
<Badge color="primary" pill className="daily-info-badge" style={{ backgroundColor: childMenuItem.color }}>{childMenuItem.total}</Badge>
</div>
</div>
)
})}
</div>
)
})
} */}
</div>
)
}
}
export default DailyInfo;

357
src/components/DailyInfo/DialogBottom.js

@ -0,0 +1,357 @@
import React, { Component } from 'react'
import { Resizable } from "re-resizable";
import closeCircleOutline from '@iconify/icons-ion/close-circle-outline';
import removeCircleOutline from '@iconify/icons-ion/remove-circle-outline';
import windowMaximaze from '@iconify/icons-mdi/window-maximize';
import { Col, Row, Table, Card, CardHeader, CardBody, CardFooter } from 'reactstrap';
import { Icon } from '@iconify/react';
import '../../views/Dashboard/Dashboard.css';
import moment from 'moment';
const style = {
position: "fixed",
width: "100%",
bottom: 0,
left: 0,
right: 0,
border: "solid 1px #ddd",
background: "#ffffff",
zIndex: 9999
};
class DialogBottom extends Component {
state = {
tableHeight: 150,
resizableWidth: "100%",
resizableHeight: 300,
maximizeTitle: "maximize"
}
setMapTableWindow = (type) => {
console.log('setMapTableWindow', type);
if (type === 'min') {
this.setState({ resizableHeight: 55, tableHeight: 150 });
}
else if (type === "max") {
if (this.state.resizableHeight === 725) {
// restore (back to default)
this.setState({ resizableHeight: 300, tableHeight: 150, maximizeTitle: "maximize" });
}
else {
// maximize
this.setState({ resizableHeight: 725, tableHeight: 950, maximizeTitle: "restore" });
}
}
}
render() {
const { isCloseDialog, itemDialog, dataTable } = this.props
const { resizableHeight } = this.state
// console.log('dataTable', dataTable.length)
// console.log('itemDialog', itemDialog)
console.log(`resizableHeight`, resizableHeight)
return (
<Resizable
style={style}
size={{
width: this.state.resizableWidth,
height: this.state.resizableHeight
}}
maxHeight={625}
enable={{ top: true, right: false, bottom: false, left: false, topRight: false, bottomRight: false, bottomLeft: false, topLeft: false }}
onResizeStop={(e, direction, ref, d) => {
// console.log('onResizeStop,e,direction,ref,d', { e, direction, ref, d })
this.setState({
resizableWidth: "100%", // to keep always full width
resizableHeight: this.state.resizableHeight + d.height
});
// if drag the table header
if (e.screenY < 100) {
this.setState({ tableHeight: 450 })
}
else if (e.screenY < 150) {
this.setState({ tableHeight: 400 })
}
else if (e.screenY < 200) {
this.setState({ tableHeight: 350 })
}
else if (e.screenY < 250) {
this.setState({ tableHeight: 300 })
}
else if (e.screenY < 300) {
this.setState({ tableHeight: 250 })
}
else if (e.screenY < 400) {
this.setState({ tableHeight: 200 })
}
else if (e.screenY < 600) {
this.setState({ tableHeight: 150 }) // default
}
else if (e.screenY >= 600) {
// this.props.toggleMapTable(); // close the MapTable
this.setMapTableWindow('min');
}
}}
>
<div style={{ paddingTop: 10, position: "relative", height: "100%" }}>
<Row className="maptable-header">
<Col md={9}>
{/* <p className="maptable-title">{itemDialog.title}</p> */}
</Col>
<Col md={3} style={{ paddingLeft: '15%' }} className="maptable-window-button-container">
<span className="maptable-minimize" title="minimize"
onClick={() => this.setMapTableWindow("min")}
>
<Icon icon={removeCircleOutline} width={30} height={30} />
</span>
<span className="maptable-maximize" title={this.state.maximizeTitle}
onClick={() => this.setMapTableWindow("max")}
>
<Icon icon={windowMaximaze} width={30} height={30} />
</span>
<span className="maptable-close" title="close"
onClick={() => isCloseDialog()}
>
<Icon icon={closeCircleOutline} width={30} height={30} />
</span>
</Col>
</Row>
{itemDialog.key === "presensi" && (
<Card style={{ margin: 10 }}>
<CardHeader>
<b>Daftar Kehadiran Karyawan Hari Ini</b>
</CardHeader>
<CardBody style={{ overflowY: 'auto', height: resizableHeight === 300 ? 200 : 510 }}>
{dataTable.length === 0 ?
<Table>
<tr>
<td style={{ fontWeight: "bold" }} colSpan="4" align="center">No Data Available</td>
</tr>
</Table>
:
<Table>
<thead>
<tr>
<th>#</th>
<th>Nama Karyawan</th>
<th>Jam Masuk</th>
<th>Jam Keluar</th>
</tr>
</thead>
<tbody >
{dataTable.map((item, index) => {
return (
<tr key={index}>
<td>{++index}</td>
<td>{item.employee_name}</td>
<td>{item.clock_time ? moment(item.clock_time).format('DD-MM-YYYY HH:mm') : "-"}</td>
<td>{item.clock_out_time ? moment(item.clock_out_time).format('DD-MM-YYYY HH:mm') : "-"}</td>
</tr>
)
})}
</tbody>
</Table>
}
</CardBody>
</Card>
)}
{itemDialog.key === "karyawan telat" && (
<Card style={{ margin: 10 }}>
<CardHeader>
<b>Daftar Karyawan Telat Hari Ini</b>
</CardHeader>
<CardBody style={{ overflowY: 'auto', height: resizableHeight === 300 ? 200 : 510 }}>
{dataTable.length === 0 ?
<Table>
<tr>
<td style={{ fontWeight: "bold" }} colSpan="4" align="center">No Data Available</td>
</tr>
</Table>
:
<Table>
<thead>
<tr>
<th>#</th>
<th>Nama Karyawan</th>
<th>Jam Masuk</th>
<th>Jam Keluar</th>
</tr>
</thead>
<tbody >
{dataTable.map((item, index) => {
return (
<tr key={index}>
<td>{++index}</td>
<td>{item.employee_name}</td>
<td>{item.clock_time ? moment(item.clock_time).format('DD-MM-YYYY HH:mm') : "-"}</td>
<td>{item.clock_out_time ? moment(item.clock_out_time).format('DD-MM-YYYY HH:mm') : "-"}</td>
</tr>
)
})}
</tbody>
</Table>
}
</CardBody>
</Card>
)}
{itemDialog.key === "total karyawan" && (
<Card style={{ margin: 10 }}>
<CardHeader>
<b>Daftar Total Karyawan</b>
</CardHeader>
<CardBody style={{ overflowY: 'auto', height: resizableHeight === 300 ? 200 : 510 }}>
{dataTable.length === 0 ?
<Table>
<tr>
<td style={{ fontWeight: "bold" }} colSpan="4" align="center">No Data Available</td>
</tr>
</Table>
:
<Table>
<thead>
<tr>
<th>#</th>
<th>Devisi</th>
<th>Nama Karyawan</th>
<th>Jenis Kelamin</th>
<th>No HP</th>
<th>Alamat</th>
</tr>
</thead>
<tbody >
{dataTable.map((item, index) => {
return (
<tr key={index}>
<td>{++index}</td>
<td>{item.devisi_name}</td>
<td>{item.name}</td>
<td>{item.gender == "P" ? "Perempuan" : "Laki-laki"}</td>
<td>{item.phone_number}</td>
<td>{item.address}</td>
</tr>
)
})}
</tbody>
</Table>
}
</CardBody>
</Card>
)}
{itemDialog.key === "absent" && (
<Card style={{ margin: 10 }}>
<CardHeader>
<b>Daftar Karyawan Absent Hari ini </b>
</CardHeader>
<CardBody style={{ overflowY: 'auto', height: resizableHeight === 300 ? 200 : 510 }}>
{dataTable.length === 0 ?
<Table>
<tr>
<td style={{ fontWeight: "bold" }} colSpan="4" align="center">No Data Available</td>
</tr>
</Table>
:
<Table>
<thead>
<tr>
<th>#</th>
<th>Nama Karyawan</th>
<th>Jam Masuk</th>
<th>Jam Keluar</th>
</tr>
</thead>
</Table>}
</CardBody>
</Card>
)}
{itemDialog.key === "karyawan tanpa keterangan" && (
<Card style={{ margin: 10 }}>
<CardHeader>
<b>Daftar Karyawan Tanpa Keterangan</b>
</CardHeader>
<CardBody style={{ overflowY: 'auto', height: resizableHeight === 300 ? 200 : 510 }}>
{dataTable.length === 0 ?
<Table>
<tr>
<td style={{ fontWeight: "bold" }} colSpan="4" align="center">No Data Available</td>
</tr>
</Table>
:
<Table>
<thead>
<tr>
<th>#</th>
<th>Devisi</th>
<th>Nama Karyawan</th>
<th>Jenis Kelamin</th>
<th>No HP</th>
<th>Alamat</th>
</tr>
</thead>
<tbody >
{dataTable.map((item, index) => {
return (
<tr key={index}>
<td>{++index}</td>
<td>{item.devisi_name}</td>
<td>{item.name}</td>
<td>{item.gender == "P" ? "Perempuan" : "Laki-laki"}</td>
<td>{item.phone_number}</td>
<td>{item.address}</td>
</tr>
)
})}
</tbody>
</Table>
}
</CardBody>
</Card>
)}
{itemDialog.key === "panic button" && (
<Card style={{ margin: 10 }}>
<CardHeader>
<b>Daftar Karyawan Melakukan Panik Button Hari Ini</b>
</CardHeader>
<CardBody style={{ overflowY: 'auto', height: resizableHeight === 300 ? 200 : 510 }}>
{dataTable.length === 0 ?
<Table>
<tr>
<td style={{ fontWeight: "bold" }} colSpan="4" align="center">No Data Available</td>
</tr>
</Table>
:
<Table>
<thead>
<tr>
<th>#</th>
<th>Nama Karyawan</th>
<th>Jam Masuk</th>
<th>Jam Keluar</th>
</tr>
</thead>
<tbody >
{dataTable.map((item, index) => {
return (
<tr key={index}>
<td>{++index}</td>
<td>{item.employee_name}</td>
<td>{item.clock_time ? moment(item.clock_time).format('DD-MM-YYYY HH:mm') : "-"}</td>
<td>{item.clock_out_time ? moment(item.clock_out_time).format('DD-MM-YYYY HH:mm') : "-"}</td>
</tr>
)
})}
</tbody>
</Table>
}
</CardBody>
</Card>
)}
</div>
</Resizable>
)
}
}
export default DialogBottom

6
src/components/DailyInfo/package.json

@ -0,0 +1,6 @@
{
"name": "DailyInfo",
"version": "0.0.0",
"private": true,
"main": "./DailyInfo.js"
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save