Compare commits
No commits in common. "main" and "v1.113.0" have entirely different histories.
|
@ -1,59 +0,0 @@
|
||||||
name: 'Build Container'
|
|
||||||
description: 'Build and publish OpenCost UI container image'
|
|
||||||
|
|
||||||
inputs:
|
|
||||||
actor:
|
|
||||||
description: 'GitHub actor'
|
|
||||||
required: true
|
|
||||||
GITHUB_TOKEN:
|
|
||||||
description: 'GitHub token for authentication'
|
|
||||||
required: true
|
|
||||||
image_tag:
|
|
||||||
description: 'Full image tag to use for the container'
|
|
||||||
required: true
|
|
||||||
release_version:
|
|
||||||
description: 'Release version for the container'
|
|
||||||
required: true
|
|
||||||
registry:
|
|
||||||
description: 'Container registry to use'
|
|
||||||
required: true
|
|
||||||
default: 'ghcr.io'
|
|
||||||
|
|
||||||
runs:
|
|
||||||
using: "composite"
|
|
||||||
steps:
|
|
||||||
- name: Log into registry
|
|
||||||
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772
|
|
||||||
with:
|
|
||||||
registry: ${{ inputs.registry }}
|
|
||||||
username: ${{ inputs.actor }}
|
|
||||||
password: ${{ inputs.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
|
||||||
uses: docker/setup-buildx-action@v3
|
|
||||||
with:
|
|
||||||
buildkitd-flags: --debug
|
|
||||||
|
|
||||||
- name: Set up just
|
|
||||||
uses: extractions/setup-just@v3
|
|
||||||
|
|
||||||
- name: Install crane
|
|
||||||
uses: imjasonh/setup-crane@v0.3
|
|
||||||
|
|
||||||
- name: Install manifest-tool
|
|
||||||
run: |
|
|
||||||
mkdir -p manifest-tool
|
|
||||||
pushd manifest-tool
|
|
||||||
wget -q https://github.com/estesp/manifest-tool/releases/download/v2.0.8/binaries-manifest-tool-2.0.8.tar.gz
|
|
||||||
tar -xzf binaries-manifest-tool-2.0.8.tar.gz
|
|
||||||
cp manifest-tool-linux-amd64 manifest-tool
|
|
||||||
echo "$(pwd)" >> $GITHUB_PATH
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- name: Build and push (multiarch)
|
|
||||||
env:
|
|
||||||
IMAGE_TAG: ${{ inputs.image_tag }}
|
|
||||||
RELEASE_VERSION: ${{ inputs.release_version }}
|
|
||||||
run: |
|
|
||||||
just build "$IMAGE_TAG" "$RELEASE_VERSION"
|
|
||||||
shell: bash
|
|
|
@ -1,59 +0,0 @@
|
||||||
name: Build and Publish Develop UI
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_run:
|
|
||||||
workflows: [Build/Test]
|
|
||||||
types: [completed]
|
|
||||||
branches: [main]
|
|
||||||
|
|
||||||
concurrency:
|
|
||||||
group: build-opencost-ui-develop
|
|
||||||
cancel-in-progress: false
|
|
||||||
|
|
||||||
env:
|
|
||||||
# Use docker.io for Docker Hub if empty
|
|
||||||
REGISTRY: ghcr.io
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build-and-publish-opencost-ui:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
if: ${{ github.event.workflow_run.conclusion == 'success' }}
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
packages: write
|
|
||||||
steps:
|
|
||||||
- name: Checkout Repo
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Set SHA
|
|
||||||
id: sha
|
|
||||||
run: |
|
|
||||||
echo "OC_SHORTHASH=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
|
|
||||||
|
|
||||||
- name: Set OpenCost Image Tags
|
|
||||||
id: tags
|
|
||||||
run: |
|
|
||||||
echo "IMAGE_TAG=ghcr.io/${{ github.repository_owner }}/opencost-ui:develop-${{ steps.sha.outputs.OC_SHORTHASH }}" >> $GITHUB_OUTPUT
|
|
||||||
|
|
||||||
- name: Build and publish container
|
|
||||||
uses: ./.github/actions/build-container
|
|
||||||
with:
|
|
||||||
actor: ${{ github.actor }}
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
image_tag: ${{ steps.tags.outputs.IMAGE_TAG }}
|
|
||||||
release_version: develop-${{ steps.sha.outputs.OC_SHORTHASH }}
|
|
||||||
registry: ${{ env.REGISTRY }}
|
|
||||||
|
|
||||||
- name: Install crane
|
|
||||||
uses: imjasonh/setup-crane@v0.4
|
|
||||||
|
|
||||||
- name: Tag and push latest image
|
|
||||||
run: |
|
|
||||||
# Extract the repository part (everything before the last colon)
|
|
||||||
REPO=$(echo "${{ steps.tags.outputs.IMAGE_TAG }}" | sed 's/:.*$//')
|
|
||||||
# Create the new tag
|
|
||||||
NEW_TAG="${REPO}:develop-latest"
|
|
||||||
echo "Copying ${{ steps.tags.outputs.IMAGE_TAG }} to ${NEW_TAG}"
|
|
||||||
crane copy "${{ steps.tags.outputs.IMAGE_TAG }}" "${NEW_TAG}"
|
|
||||||
|
|
||||||
|
|
|
@ -59,12 +59,6 @@ jobs:
|
||||||
VERSION_NUMBER=${{ steps.version_number.outputs.RELEASE_VERSION }}
|
VERSION_NUMBER=${{ steps.version_number.outputs.RELEASE_VERSION }}
|
||||||
echo "BRANCH_NAME=v${VERSION_NUMBER%.*}" >> $GITHUB_ENV
|
echo "BRANCH_NAME=v${VERSION_NUMBER%.*}" >> $GITHUB_ENV
|
||||||
|
|
||||||
# checkout opencost UI to allow access to actions
|
|
||||||
- name: Checkout actions
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
repository: 'opencost/opencost-ui'
|
|
||||||
|
|
||||||
- name: Checkout Repo
|
- name: Checkout Repo
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
|
@ -79,6 +73,15 @@ jobs:
|
||||||
echo "OC_SHORTHASH=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
|
echo "OC_SHORTHASH=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
|
||||||
popd
|
popd
|
||||||
|
|
||||||
|
# Login against a Docker registry except on PR
|
||||||
|
# https://github.com/docker/login-action
|
||||||
|
- name: Log into registry ${{ env.REGISTRY }}
|
||||||
|
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0
|
||||||
|
with:
|
||||||
|
registry: ${{ env.REGISTRY }}
|
||||||
|
username: ${{ github.actor }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Set OpenCost Image Tags
|
- name: Set OpenCost Image Tags
|
||||||
id: tags
|
id: tags
|
||||||
run: |
|
run: |
|
||||||
|
@ -86,17 +89,31 @@ jobs:
|
||||||
echo "IMAGE_TAG_UI_LATEST=ghcr.io/opencost/opencost-ui:latest" >> $GITHUB_OUTPUT
|
echo "IMAGE_TAG_UI_LATEST=ghcr.io/opencost/opencost-ui:latest" >> $GITHUB_OUTPUT
|
||||||
echo "IMAGE_TAG_UI_VERSION=ghcr.io/opencost/opencost-ui:${{ steps.version_number.outputs.RELEASE_VERSION }}" >> $GITHUB_OUTPUT
|
echo "IMAGE_TAG_UI_VERSION=ghcr.io/opencost/opencost-ui:${{ steps.version_number.outputs.RELEASE_VERSION }}" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
- name: Build and publish container
|
- name: Set up Docker Buildx
|
||||||
uses: ./.github/actions/build-container
|
uses: docker/setup-buildx-action@v3
|
||||||
with:
|
with:
|
||||||
actor: ${{ github.actor }}
|
buildkitd-flags: --debug
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
image_tag: ${{ steps.tags.outputs.IMAGE_TAG_UI }}
|
- name: Set up just
|
||||||
release_version: ${{ steps.version_number.outputs.RELEASE_VERSION }}
|
uses: extractions/setup-just@v2
|
||||||
registry: ${{ env.REGISTRY }}
|
|
||||||
- name: Install crane
|
- name: Install crane
|
||||||
uses: imjasonh/setup-crane@v0.4
|
uses: imjasonh/setup-crane@v0.3
|
||||||
- name: Tag and push latest image
|
|
||||||
|
## Install manifest-tool, which is required to combine multi-arch images
|
||||||
|
## https://github.com/estesp/manifest-tool
|
||||||
|
- name: Install manifest-tool
|
||||||
run: |
|
run: |
|
||||||
crane copy "${{ steps.tags.outputs.IMAGE_TAG_UI }}" "${{ steps.tags.outputs.IMAGE_TAG_UI_LATEST }}"
|
mkdir -p manifest-tool
|
||||||
crane copy "${{ steps.tags.outputs.IMAGE_TAG_UI }}" "${{ steps.tags.outputs.IMAGE_TAG_UI_VERSION }}"
|
pushd manifest-tool
|
||||||
|
wget -q https://github.com/estesp/manifest-tool/releases/download/v2.0.8/binaries-manifest-tool-2.0.8.tar.gz
|
||||||
|
tar -xzf binaries-manifest-tool-2.0.8.tar.gz
|
||||||
|
cp manifest-tool-linux-amd64 manifest-tool
|
||||||
|
echo "$(pwd)" >> $GITHUB_PATH
|
||||||
|
|
||||||
|
- name: Build and push (multiarch) OpenCost UI
|
||||||
|
working-directory: ./opencost-ui
|
||||||
|
run: |
|
||||||
|
just build '${{ steps.tags.outputs.IMAGE_TAG_UI }}' '${{ steps.version_number.outputs.RELEASE_VERSION }}'
|
||||||
|
crane copy '${{ steps.tags.outputs.IMAGE_TAG_UI }}' '${{ steps.tags.outputs.IMAGE_TAG_UI_LATEST }}'
|
||||||
|
crane copy '${{ steps.tags.outputs.IMAGE_TAG_UI }}' '${{ steps.tags.outputs.IMAGE_TAG_UI_VERSION }}'
|
||||||
|
|
|
@ -1,61 +0,0 @@
|
||||||
name: Build and Publish UI Test Image
|
|
||||||
|
|
||||||
on:
|
|
||||||
merge_group:
|
|
||||||
types: [checks_requested]
|
|
||||||
pull_request_target:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
|
|
||||||
|
|
||||||
env:
|
|
||||||
REGISTRY: ghcr.io
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
check_actor_permissions:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
if: ${{ github.event_name == 'pull_request_target' }}
|
|
||||||
outputs:
|
|
||||||
ismaintainer: ${{ steps.determine-maintainer.outputs.ismaintainer }}
|
|
||||||
steps:
|
|
||||||
- name: Check team membership
|
|
||||||
uses: tspascoal/get-user-teams-membership@v3
|
|
||||||
id: teamAffiliation
|
|
||||||
with:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.ORG_READER_PAT }}
|
|
||||||
username: ${{ github.actor }}
|
|
||||||
organization: opencost
|
|
||||||
- name: determine if actor is a maintainer
|
|
||||||
id: determine-maintainer
|
|
||||||
run: |
|
|
||||||
echo "Actor: ${{ github.actor }}"
|
|
||||||
echo "Is maintainer: ${{ contains(steps.teamAffiliation.outputs.teams, 'OpenCost Maintainers') || contains(github.actor, 'dependabot[bot]') }}"
|
|
||||||
echo "ismaintainer=${{ contains(steps.teamAffiliation.outputs.teams, 'OpenCost Maintainers') || contains(github.actor, 'dependabot[bot]') }}" >> $GITHUB_OUTPUT
|
|
||||||
build-and-publish-test-image:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
needs: check_actor_permissions
|
|
||||||
if: ${{ (always() && !cancelled()) && ( github.event_name == 'merge_group' || needs.check_actor_permissions.outputs.ismaintainer == 'true') }}
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
packages: write
|
|
||||||
steps:
|
|
||||||
- name: Checkout Repo
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
ref: ${{ github.event.merge_group.head_sha || github.event.pull_request.head.sha }}
|
|
||||||
- name: Set SHA
|
|
||||||
id: sha
|
|
||||||
run: |
|
|
||||||
echo "OC_SHORTHASH=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
|
|
||||||
- name: Set OpenCost Image Tags
|
|
||||||
id: tags
|
|
||||||
run: |
|
|
||||||
echo "IMAGE_TAG=ghcr.io/${{ github.repository_owner }}/opencost-ui:test-${{ steps.sha.outputs.OC_SHORTHASH }}" >> $GITHUB_OUTPUT
|
|
||||||
- name: Build and publish container
|
|
||||||
uses: ./.github/actions/build-container
|
|
||||||
with:
|
|
||||||
actor: ${{ github.actor }}
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
image_tag: ${{ steps.tags.outputs.IMAGE_TAG }}
|
|
||||||
release_version: test-${{ steps.sha.outputs.OC_SHORTHASH }}
|
|
||||||
registry: ${{ env.REGISTRY }}
|
|
|
@ -19,7 +19,7 @@ jobs:
|
||||||
|
|
||||||
-
|
-
|
||||||
name: Install just
|
name: Install just
|
||||||
uses: extractions/setup-just@v3
|
uses: extractions/setup-just@v2
|
||||||
|
|
||||||
-
|
-
|
||||||
name: Install node
|
name: Install node
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
name: Promote UI to Demo
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_run:
|
|
||||||
workflows: [Build and Publish Develop UI]
|
|
||||||
types: [completed]
|
|
||||||
branches: [main]
|
|
||||||
|
|
||||||
concurrency:
|
|
||||||
group: build-opencost-ui-develop
|
|
||||||
cancel-in-progress: false
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
prep-image-name:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
if: ${{ github.event.workflow_run.conclusion == 'success' }}
|
|
||||||
outputs:
|
|
||||||
image_tag: ${{ steps.tags.outputs.IMAGE_TAG }}
|
|
||||||
steps:
|
|
||||||
- name: Checkout Repo
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
- name: Set SHA
|
|
||||||
id: sha
|
|
||||||
run: |
|
|
||||||
echo "OC_SHORTHASH=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
|
|
||||||
|
|
||||||
- name: Set OpenCost Image Tags
|
|
||||||
id: tags
|
|
||||||
run: |
|
|
||||||
echo "IMAGE_TAG=ghcr.io/${{ github.repository_owner }}/opencost-ui:develop-${{ steps.sha.outputs.OC_SHORTHASH }}" >> $GITHUB_OUTPUT
|
|
||||||
|
|
||||||
install-on-demo:
|
|
||||||
needs: [prep-image-name]
|
|
||||||
uses: opencost/opencost-infra/.github/workflows/promote-to-oc-demo.yaml@main
|
|
||||||
secrets: inherit
|
|
||||||
with:
|
|
||||||
img-fqdn: ${{ needs.prep-image-name.outputs.image_tag }}
|
|
||||||
is_be: false
|
|
||||||
is_fe: true
|
|
|
@ -2,16 +2,16 @@
|
||||||
|
|
||||||
# OpenCost UI
|
# OpenCost UI
|
||||||
|
|
||||||
<img src="src/images/logo.png"/>
|
<img src="./opencost-header.png"/>
|
||||||
|
|
||||||
This is the web UI for the [OpenCost](http://github.com/opencost/opencost) project. You can learn more about the [User Interface](https://www.opencost.io/docs/installation/ui) in the OpenCost docs.
|
This is the web UI for the [OpenCost](http://github.com/opencost/opencost) project. You can learn more about the [User Interface](https://www.opencost.io/docs/installation/ui) in the OpenCost docs.
|
||||||
|
|
||||||
[](https://youtu.be/lCP4Ci9Kcdg)
|
[](https://youtu.be/lCP4Ci9Kcdg)
|
||||||
*OpenCost UI Walkthrough*
|
*OpenCost UI Walkthrough*
|
||||||
|
|
||||||
## Installing
|
## Installing
|
||||||
|
|
||||||
See [Installation Guide](https://opencost.io/docs/installation/install) for the full instructions.
|
See https://www.opencost.io/docs/install for the full instructions.
|
||||||
|
|
||||||
## Using
|
## Using
|
||||||
|
|
||||||
|
|
|
@ -18,9 +18,8 @@ else
|
||||||
sed -i "s^PLACEHOLDER_FOOTER_CONTENT^OpenCost version: $VERSION ($HEAD)^g" /var/www/*.js
|
sed -i "s^PLACEHOLDER_FOOTER_CONTENT^OpenCost version: $VERSION ($HEAD)^g" /var/www/*.js
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ ! -e /etc/nginx/conf.d/default.nginx.conf ]];then
|
envsubst '$API_PORT $API_SERVER $UI_PORT' < /etc/nginx/conf.d/default.nginx.conf.template > /etc/nginx/conf.d/default.nginx.conf
|
||||||
envsubst '$API_PORT $API_SERVER $UI_PORT' < /etc/nginx/conf.d/default.nginx.conf.template > /etc/nginx/conf.d/default.nginx.conf
|
|
||||||
fi
|
|
||||||
echo "Starting OpenCost UI version $VERSION ($HEAD)"
|
echo "Starting OpenCost UI version $VERSION ($HEAD)"
|
||||||
|
|
||||||
# Run the parent (nginx) container's entrypoint script
|
# Run the parent (nginx) container's entrypoint script
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
16
package.json
16
package.json
|
@ -14,14 +14,14 @@
|
||||||
"defaults"
|
"defaults"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.27.0",
|
"@babel/runtime": "^7.23.9",
|
||||||
"@date-io/core": "^3.2.0",
|
"@date-io/core": "^1.3.13",
|
||||||
"@date-io/date-fns": "^1.3.13",
|
"@date-io/date-fns": "^1.3.13",
|
||||||
"@material-ui/core": "^4.11.3",
|
"@material-ui/core": "^4.11.3",
|
||||||
"@material-ui/icons": "^4.11.2",
|
"@material-ui/icons": "^4.11.2",
|
||||||
"@material-ui/pickers": "^3.3.10",
|
"@material-ui/pickers": "^3.3.10",
|
||||||
"@material-ui/styles": "^4.11.5",
|
"@material-ui/styles": "^4.11.5",
|
||||||
"axios": "^1.8.4",
|
"axios": "^1.6.0",
|
||||||
"date-fns": "^2.30.0",
|
"date-fns": "^2.30.0",
|
||||||
"html-to-react": "^1.7.0",
|
"html-to-react": "^1.7.0",
|
||||||
"material-design-icons-iconfont": "^6.1.0",
|
"material-design-icons-iconfont": "^6.1.0",
|
||||||
|
@ -29,15 +29,15 @@
|
||||||
"react": "^17.0.1",
|
"react": "^17.0.1",
|
||||||
"react-dom": "^17.0.1",
|
"react-dom": "^17.0.1",
|
||||||
"react-router-dom": "^5.2.0",
|
"react-router-dom": "^5.2.0",
|
||||||
"recharts": "^2.15.3"
|
"recharts": "^2.2.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.28.0",
|
"@babel/core": "^7.13.10",
|
||||||
"@babel/plugin-proposal-class-properties": "^7.13.0",
|
"@babel/plugin-proposal-class-properties": "^7.13.0",
|
||||||
"@babel/plugin-transform-runtime": "^7.26.10",
|
"@babel/plugin-transform-runtime": "^7.23.9",
|
||||||
"@babel/preset-react": "^7.26.3",
|
"@babel/preset-react": "^7.12.13",
|
||||||
"buffer": "^6.0.3",
|
"buffer": "^6.0.3",
|
||||||
"parcel": "^2.14.4",
|
"parcel": "^2.11.0",
|
||||||
"process": "^0.11.10",
|
"process": "^0.11.10",
|
||||||
"set-value": "4.1.0"
|
"set-value": "4.1.0"
|
||||||
},
|
},
|
||||||
|
|
|
@ -6,8 +6,6 @@ import { BarChart } from "@material-ui/icons";
|
||||||
import { Cloud } from "@material-ui/icons";
|
import { Cloud } from "@material-ui/icons";
|
||||||
import { makeStyles } from "@material-ui/styles";
|
import { makeStyles } from "@material-ui/styles";
|
||||||
|
|
||||||
const logo = new URL("../../images/logo.png", import.meta.url).href;
|
|
||||||
|
|
||||||
const DRAWER_WIDTH = 200;
|
const DRAWER_WIDTH = 200;
|
||||||
|
|
||||||
const SidebarNav = ({ active }) => {
|
const SidebarNav = ({ active }) => {
|
||||||
|
@ -57,7 +55,7 @@ const SidebarNav = ({ active }) => {
|
||||||
variant={"permanent"}
|
variant={"permanent"}
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
src={logo}
|
src={require("../../images/logo.png")}
|
||||||
alt="OpenCost"
|
alt="OpenCost"
|
||||||
style={{ flexShrink: 1, padding: "1rem" }}
|
style={{ flexShrink: 1, padding: "1rem" }}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -238,8 +238,8 @@ const AllocationReport = ({
|
||||||
rowsPerPage={rowsPerPage}
|
rowsPerPage={rowsPerPage}
|
||||||
rowsPerPageOptions={[10, 25, 50]}
|
rowsPerPageOptions={[10, 25, 50]}
|
||||||
page={Math.min(page, lastPage)}
|
page={Math.min(page, lastPage)}
|
||||||
onPageChange={handleChangePage}
|
onChangePage={handleChangePage}
|
||||||
onRowsPerPageChange={handleChangeRowsPerPage}
|
onChangeRowsPerPage={handleChangeRowsPerPage}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -204,8 +204,8 @@ const CloudCost = ({
|
||||||
rowsPerPage={rowsPerPage}
|
rowsPerPage={rowsPerPage}
|
||||||
rowsPerPageOptions={[10, 25, 50]}
|
rowsPerPageOptions={[10, 25, 50]}
|
||||||
page={Math.min(page, lastPage)}
|
page={Math.min(page, lastPage)}
|
||||||
onPageChange={handleChangePage}
|
onChangePage={handleChangePage}
|
||||||
onRowsPerPageChange={handleChangeRowsPerPage}
|
onChangeRowsPerPage={handleChangeRowsPerPage}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -56,7 +56,7 @@ const ExternalCostsTable = ({
|
||||||
const routerHistory = useHistory();
|
const routerHistory = useHistory();
|
||||||
const [page, setPage] = React.useState(0);
|
const [page, setPage] = React.useState(0);
|
||||||
const [rowsPerPage, setRowsPerPage] = React.useState(25);
|
const [rowsPerPage, setRowsPerPage] = React.useState(25);
|
||||||
const numData = tableData.customCosts?.length ?? 0;
|
const numData = tableData.customCosts?.length;
|
||||||
|
|
||||||
const lastPage = Math.floor(numData / rowsPerPage);
|
const lastPage = Math.floor(numData / rowsPerPage);
|
||||||
|
|
||||||
|
@ -67,20 +67,16 @@ const ExternalCostsTable = ({
|
||||||
setPage(0);
|
setPage(0);
|
||||||
};
|
};
|
||||||
|
|
||||||
let pageRows = [];
|
const pageRows = tableData.customCosts.slice(
|
||||||
|
page * rowsPerPage,
|
||||||
if (tableData && 'customCosts' in tableData) {
|
page * rowsPerPage + rowsPerPage
|
||||||
pageRows = tableData.customCosts.slice(
|
);
|
||||||
page * rowsPerPage,
|
|
||||||
page * rowsPerPage + rowsPerPage
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
setPage(0);
|
setPage(0);
|
||||||
}, [numData]);
|
}, [numData]);
|
||||||
|
|
||||||
if ('customCosts' in tableData && tableData.customCosts.length === 0) {
|
if (tableData.customCosts.length === 0) {
|
||||||
return (
|
return (
|
||||||
<Typography variant="body2" className={classes.noResults}>
|
<Typography variant="body2" className={classes.noResults}>
|
||||||
No results
|
No results
|
||||||
|
@ -172,8 +168,8 @@ const ExternalCostsTable = ({
|
||||||
rowsPerPage={rowsPerPage}
|
rowsPerPage={rowsPerPage}
|
||||||
rowsPerPageOptions={[10, 25, 50]}
|
rowsPerPageOptions={[10, 25, 50]}
|
||||||
page={Math.min(page, lastPage)}
|
page={Math.min(page, lastPage)}
|
||||||
onPageChange={handleChangePage}
|
onChangePage={handleChangePage}
|
||||||
onRowsPerPageChange={handleChangeRowsPerPage}
|
onChangeRowsPerPage={handleChangeRowsPerPage}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in New Issue