From 4e81922b97dbe392bee8ee4eb58be33cd8344a7c Mon Sep 17 00:00:00 2001 From: AMUZY Date: Fri, 13 Oct 2023 14:26:59 +0100 Subject: [PATCH 01/14] view required signoffs in the rule update page --- agent/run.sh | 0 agent/scripts/test-entrypoint.sh | 0 client/setup.py | 0 maintenance/pin-helper.sh | 0 maintenance/pin.sh | 0 scripts/adhoc-tests.py | 0 scripts/initdb_and_run.sh | 0 scripts/manage-db.py | 0 scripts/reset-stage-db.sh | 0 scripts/run-batch-deletes.sh | 0 scripts/run.sh | 0 scripts/test-rules.py | 0 src/auslib/blobs/apprelease.py | 0 src/auslib/blobs/base.py | 0 taskcluster/docker/skopeo/push_image.sh | 0 taskcluster/scripts/get-coveralls-token | 0 tests/blobs/test_apprelease.py | 0 ui/scripts/deploy | 0 ui/src/views/Rules/Rule/index.jsx | 300 +++++++++++++++--------- 19 files changed, 186 insertions(+), 114 deletions(-) mode change 100755 => 100644 agent/run.sh mode change 100755 => 100644 agent/scripts/test-entrypoint.sh mode change 100755 => 100644 client/setup.py mode change 100755 => 100644 maintenance/pin-helper.sh mode change 100755 => 100644 maintenance/pin.sh mode change 100755 => 100644 scripts/adhoc-tests.py mode change 100755 => 100644 scripts/initdb_and_run.sh mode change 100755 => 100644 scripts/manage-db.py mode change 100755 => 100644 scripts/reset-stage-db.sh mode change 100755 => 100644 scripts/run-batch-deletes.sh mode change 100755 => 100644 scripts/run.sh mode change 100755 => 100644 scripts/test-rules.py mode change 100755 => 100644 src/auslib/blobs/apprelease.py mode change 100755 => 100644 src/auslib/blobs/base.py mode change 100755 => 100644 taskcluster/docker/skopeo/push_image.sh mode change 100755 => 100644 taskcluster/scripts/get-coveralls-token mode change 100755 => 100644 tests/blobs/test_apprelease.py mode change 100755 => 100644 ui/scripts/deploy diff --git a/agent/run.sh b/agent/run.sh old mode 100755 new mode 100644 diff --git a/agent/scripts/test-entrypoint.sh b/agent/scripts/test-entrypoint.sh old mode 100755 new mode 100644 diff --git a/client/setup.py b/client/setup.py old mode 100755 new mode 100644 diff --git a/maintenance/pin-helper.sh b/maintenance/pin-helper.sh old mode 100755 new mode 100644 diff --git a/maintenance/pin.sh b/maintenance/pin.sh old mode 100755 new mode 100644 diff --git a/scripts/adhoc-tests.py b/scripts/adhoc-tests.py old mode 100755 new mode 100644 diff --git a/scripts/initdb_and_run.sh b/scripts/initdb_and_run.sh old mode 100755 new mode 100644 diff --git a/scripts/manage-db.py b/scripts/manage-db.py old mode 100755 new mode 100644 diff --git a/scripts/reset-stage-db.sh b/scripts/reset-stage-db.sh old mode 100755 new mode 100644 diff --git a/scripts/run-batch-deletes.sh b/scripts/run-batch-deletes.sh old mode 100755 new mode 100644 diff --git a/scripts/run.sh b/scripts/run.sh old mode 100755 new mode 100644 diff --git a/scripts/test-rules.py b/scripts/test-rules.py old mode 100755 new mode 100644 diff --git a/src/auslib/blobs/apprelease.py b/src/auslib/blobs/apprelease.py old mode 100755 new mode 100644 diff --git a/src/auslib/blobs/base.py b/src/auslib/blobs/base.py old mode 100755 new mode 100644 diff --git a/taskcluster/docker/skopeo/push_image.sh b/taskcluster/docker/skopeo/push_image.sh old mode 100755 new mode 100644 diff --git a/taskcluster/scripts/get-coveralls-token b/taskcluster/scripts/get-coveralls-token old mode 100755 new mode 100644 diff --git a/tests/blobs/test_apprelease.py b/tests/blobs/test_apprelease.py old mode 100755 new mode 100644 diff --git a/ui/scripts/deploy b/ui/scripts/deploy old mode 100755 new mode 100644 diff --git a/ui/src/views/Rules/Rule/index.jsx b/ui/src/views/Rules/Rule/index.jsx index a2242bb646..aa37c1d70f 100644 --- a/ui/src/views/Rules/Rule/index.jsx +++ b/ui/src/views/Rules/Rule/index.jsx @@ -1,26 +1,26 @@ -import React, { Fragment, useState, useEffect } from 'react'; -import classNames from 'classnames'; -import { bool } from 'prop-types'; -import { defaultTo, assocPath, pick } from 'ramda'; -import { stringify } from 'qs'; -import NumberFormat from 'react-number-format'; -import { makeStyles } from '@material-ui/styles'; -import Spinner from '@mozilla-frontend-infra/components/Spinner'; -import Grid from '@material-ui/core/Grid'; -import TextField from '@material-ui/core/TextField'; -import MenuItem from '@material-ui/core/MenuItem'; -import Tooltip from '@material-ui/core/Tooltip'; -import Fab from '@material-ui/core/Fab'; -import SpeedDialAction from '@material-ui/lab/SpeedDialAction'; -import ContentSaveIcon from 'mdi-react/ContentSaveIcon'; -import DeleteIcon from 'mdi-react/DeleteIcon'; -import Dashboard from '../../../components/Dashboard'; -import ErrorPanel from '../../../components/ErrorPanel'; -import AutoCompleteText from '../../../components/AutoCompleteText'; -import getSuggestions from '../../../components/AutoCompleteText/getSuggestions'; -import DateTimePicker from '../../../components/DateTimePicker'; -import SpeedDial from '../../../components/SpeedDial'; -import useAction from '../../../hooks/useAction'; +import React, { Fragment, useState, useEffect } from "react"; +import classNames from "classnames"; +import { bool } from "prop-types"; +import { defaultTo, assocPath, pick } from "ramda"; +import { stringify } from "qs"; +import NumberFormat from "react-number-format"; +import { makeStyles } from "@material-ui/styles"; +import Spinner from "@mozilla-frontend-infra/components/Spinner"; +import Grid from "@material-ui/core/Grid"; +import TextField from "@material-ui/core/TextField"; +import MenuItem from "@material-ui/core/MenuItem"; +import Tooltip from "@material-ui/core/Tooltip"; +import Fab from "@material-ui/core/Fab"; +import SpeedDialAction from "@material-ui/lab/SpeedDialAction"; +import ContentSaveIcon from "mdi-react/ContentSaveIcon"; +import DeleteIcon from "mdi-react/DeleteIcon"; +import Dashboard from "../../../components/Dashboard"; +import ErrorPanel from "../../../components/ErrorPanel"; +import AutoCompleteText from "../../../components/AutoCompleteText"; +import getSuggestions from "../../../components/AutoCompleteText/getSuggestions"; +import DateTimePicker from "../../../components/DateTimePicker"; +import SpeedDial from "../../../components/SpeedDial"; +import useAction from "../../../hooks/useAction"; import { getScheduledChangeByRuleId, getScheduledChangeByScId, @@ -30,39 +30,43 @@ import { addScheduledChange, updateScheduledChange, deleteScheduledChange, -} from '../../../services/rules'; -import { getReleaseNames, getReleaseNamesV2 } from '../../../services/releases'; -import { withUser } from '../../../utils/AuthContext'; +} from "../../../services/rules"; +import { getReleaseNames, getReleaseNamesV2 } from "../../../services/releases"; +import { withUser } from "../../../utils/AuthContext"; import { EMPTY_MENU_ITEM_CHAR, SPLIT_WITH_NEWLINES_AND_COMMA_REGEX, RULE_PRODUCT_UNSUPPORTED_PROPERTIES, -} from '../../../utils/constants'; +} from "../../../utils/constants"; +// ALL IMPORTS TO FETCH REQUIRED SIGNOFFS BELOW: +import { OBJECT_NAMES } from "../../../utils/constants"; +import { getRequiredSignoffs } from "../../../services/requiredSignoffs"; +import Typography from '@material-ui/core/Typography'; const initialRule = { - alias: '', + alias: "", backgroundRate: 0, - buildID: '', - buildTarget: '', - channel: '', - comment: '', - distVersion: '', - distribution: '', - fallbackMapping: '', - headerArchitecture: '', - instructionSet: '', + buildID: "", + buildTarget: "", + channel: "", + comment: "", + distVersion: "", + distribution: "", + fallbackMapping: "", + headerArchitecture: "", + instructionSet: "", jaws: EMPTY_MENU_ITEM_CHAR, - locale: '', - mapping: '', - memory: '', + locale: "", + mapping: "", + memory: "", mig64: EMPTY_MENU_ITEM_CHAR, - osVersion: '', + osVersion: "", priority: 0, - product: '', - update_type: 'minor', - version: '', + product: "", + update_type: "minor", + version: "", }; -const useStyles = makeStyles(theme => ({ +const useStyles = makeStyles((theme) => ({ fab: { ...theme.mixins.fab, }, @@ -75,8 +79,8 @@ const useStyles = makeStyles(theme => ({ width: theme.spacing(7), }, scheduleDiv: { - display: 'flex', - alignItems: 'center', + display: "flex", + alignItems: "center", marginBottom: theme.spacing(4), }, scheduleIcon: { @@ -91,13 +95,13 @@ function Rule({ isNewRule, user, ...props }) { ? props.location.state.rulesFilter : []; const [rule, setRule] = useState(initialRule); + const [allRequiredSignOffs, setAllrequiredSignoffs] = useState([]); const [releaseNames, setReleaseNames] = useState([]); const [products, fetchProducts] = useAction(getProducts); const [channels, fetchChannels] = useAction(getChannels); const [releaseNamesAction, fetchReleaseNames] = useAction(getReleaseNames); - const [releaseNamesV2Action, fetchReleaseNamesV2] = useAction( - getReleaseNamesV2 - ); + const [releaseNamesV2Action, fetchReleaseNamesV2] = + useAction(getReleaseNamesV2); // 30 seconds - to make sure the helper text "Scheduled for ASAP" shows up const [scheduleDate, setScheduleDate] = useState(new Date()); const [dateTimePickerError, setDateTimePickerError] = useState(null); @@ -132,34 +136,36 @@ function Rule({ isNewRule, user, ...props }) { deleteSCAction.error; const { ruleId, scId } = props.match.params; const hasScheduledChange = !!rule.sc_id; - const defaultToEmptyString = defaultTo(''); + const defaultToEmptyString = defaultTo(""); const osVersionTextValue = defaultToEmptyString(rule.osVersion) .split(SPLIT_WITH_NEWLINES_AND_COMMA_REGEX) - .join('\n'); + .join("\n"); const localeTextValue = defaultToEmptyString(rule.locale) .split(SPLIT_WITH_NEWLINES_AND_COMMA_REGEX) - .join('\n'); + .join("\n"); const handleInputChange = ({ target: { name, value } }) => { setRule(assocPath([name], value, rule)); }; const handleTextFieldWithNewLinesChange = ({ target: { name, value } }) => { - setRule(assocPath([name], value.split('\n').join(','), rule)); + setRule(assocPath([name], value.split("\n").join(","), rule)); }; - const handleProductChange = value => - setRule(assocPath(['product'], value, rule)); - const handleChannelChange = value => - setRule(assocPath(['channel'], value, rule)); - const handleMappingChange = value => - setRule(assocPath(['mapping'], value, rule)); - const handleFallbackMappingChange = value => - setRule(assocPath(['fallbackMapping'], value, rule)); - const handleNumberChange = name => ({ floatValue: value }) => { - setRule(assocPath([name], value, rule)); - }; + const handleProductChange = (value) => + setRule(assocPath(["product"], value, rule)); + const handleChannelChange = (value) => + setRule(assocPath(["channel"], value, rule)); + const handleMappingChange = (value) => + setRule(assocPath(["mapping"], value, rule)); + const handleFallbackMappingChange = (value) => + setRule(assocPath(["fallbackMapping"], value, rule)); + const handleNumberChange = + (name) => + ({ floatValue: value }) => { + setRule(assocPath([name], value, rule)); + }; - const redirectWithRulesFilter = hashFilter => { + const redirectWithRulesFilter = (hashFilter) => { const [product, channel] = rulesFilter; const query = stringify({ product, channel }, { addQueryPrefix: true }); @@ -178,12 +184,12 @@ function Rule({ isNewRule, user, ...props }) { ); }, []); - const handleDateTimeChange = date => { + const handleDateTimeChange = (date) => { setScheduleDate(date); setDateTimePickerError(null); }; - const handleDateTimePickerError = error => { + const handleDateTimePickerError = (error) => { setDateTimePickerError(error); }; @@ -198,12 +204,12 @@ function Rule({ isNewRule, user, ...props }) { } }; - const productSupportsField = field => + const productSupportsField = (field) => !( rule.product in RULE_PRODUCT_UNSUPPORTED_PROPERTIES && RULE_PRODUCT_UNSUPPORTED_PROPERTIES[rule.product].includes(field) ); - const filterProductData = data => + const filterProductData = (data) => pick(Object.keys(data).filter(productSupportsField), data); const handleCreateRule = async () => { const now = new Date(); @@ -221,11 +227,11 @@ function Rule({ isNewRule, user, ...props }) { fallbackMapping: rule.fallbackMapping, headerArchitecture: rule.headerArchitecture, instructionSet: rule.instructionSet, - jaws: rule.jaws === EMPTY_MENU_ITEM_CHAR ? null : rule.jaws === 'true', + jaws: rule.jaws === EMPTY_MENU_ITEM_CHAR ? null : rule.jaws === "true", locale: rule.locale, mapping: rule.mapping, memory: rule.memory, - mig64: rule.mig64 === EMPTY_MENU_ITEM_CHAR ? null : rule.mig64 === 'true', + mig64: rule.mig64 === EMPTY_MENU_ITEM_CHAR ? null : rule.mig64 === "true", osVersion: rule.osVersion, priority: rule.priority, product: rule.product, @@ -233,7 +239,7 @@ function Rule({ isNewRule, user, ...props }) { version: rule.version, }; const { data: response, error } = await addSC({ - change_type: 'insert', + change_type: "insert", when, ...filterProductData(data), }); @@ -259,11 +265,11 @@ function Rule({ isNewRule, user, ...props }) { fallbackMapping: rule.fallbackMapping, headerArchitecture: rule.headerArchitecture, instructionSet: rule.instructionSet, - jaws: rule.jaws === EMPTY_MENU_ITEM_CHAR ? null : rule.jaws === 'true', + jaws: rule.jaws === EMPTY_MENU_ITEM_CHAR ? null : rule.jaws === "true", locale: rule.locale, mapping: rule.mapping, memory: rule.memory, - mig64: rule.mig64 === EMPTY_MENU_ITEM_CHAR ? null : rule.mig64 === 'true', + mig64: rule.mig64 === EMPTY_MENU_ITEM_CHAR ? null : rule.mig64 === "true", osVersion: rule.osVersion, priority: rule.priority, product: rule.product, @@ -287,7 +293,7 @@ function Rule({ isNewRule, user, ...props }) { const { data: response, error } = await addSC({ rule_id: rule.rule_id, data_version: rule.data_version, - change_type: 'update', + change_type: "update", when, ...filterProductData(data), }); @@ -308,7 +314,7 @@ function Rule({ isNewRule, user, ...props }) { // values, they get stored as EMPTY_MENU_ITEM_CHAR or a string // true/false when they change in the UI. In order to keep things // consistent, we do the same to the data fetched from the server. - const getOptionalBooleanValue = current => + const getOptionalBooleanValue = (current) => current === null ? EMPTY_MENU_ITEM_CHAR : String(current); if (!isNewRule) { @@ -385,14 +391,44 @@ function Rule({ isNewRule, user, ...props }) { if (isNewRule) { if (scId) { return `Update Scheduled Rule ${scId}${ - rule.alias ? ` (${rule.alias})` : '' + rule.alias ? ` (${rule.alias})` : "" }`; } - return 'Create Rule'; + return "Create Rule"; } - return `Update Rule ${ruleId}${rule.alias ? ` (${rule.alias})` : ''}`; + return `Update Rule ${ruleId}${rule.alias ? ` (${rule.alias})` : ""}`; + }; + + const [requiredSignoffs, fetchRequiredSignoffs] = + useAction(getRequiredSignoffs); + + useEffect(() => { + let myPromise = new Promise((res) => { + res(fetchRequiredSignoffs(OBJECT_NAMES.PRODUCT_REQUIRED_SIGNOFF)); + }); + myPromise.then((rs) => { + setAllrequiredSignoffs(rs.data.data.required_signoffs); + }); + }, []); + + // SignOff style + const signoffStyle = { + div: { + display: "flex", + flexFlow: "row wrap", + width: "100%", + margin: "8px 0 8px 0", + alignItems: "center", + }, + p1: { + marginRight: "8px", + color: "gray", + }, + p2: { + color: "black", + }, }; return ( @@ -400,7 +436,37 @@ function Rule({ isNewRule, user, ...props }) { {isLoading && } {error && } {!isLoading && ( + /* + THE SIGN OFF DETAIL SHOULD GO JUST UNDERNEATH THE OPENING FRAGMENT + It should be in the form : + "SignOffs Required : 1 signoff from a releng user" + */ + {/* SHOWS REQUIRED SIGNOFFS */} +
+ Required Signoff(s) : + {allRequiredSignOffs.map((reqSignOff, index, all) => { + if ( + rule.product === reqSignOff.product && + rule.channel === `${reqSignOff.channel}*` + ) { + return ( + {`${ + reqSignOff.signoffs_required + } member${reqSignOff.count > 1 ? "s" : ""} of ${ + reqSignOff.role + }${all[index + 1] ? "," : ""}`} + ); + } else { + return ( + + No signoffs provided for this product in local development + + ); + } + })} + {/* END OF REQUIRED SIGNOFFS INFO */} +
- {productSupportsField('channel') && ( + {productSupportsField("channel") && ( )} - {productSupportsField('mapping') && ( + {productSupportsField("mapping") && ( )} - {productSupportsField('fallbackMapping') && ( + {productSupportsField("fallbackMapping") && ( )} - {productSupportsField('backgroundRate') && ( + {productSupportsField("backgroundRate") && ( )} - {productSupportsField('priority') && ( + {productSupportsField("priority") && ( )} - {productSupportsField('version') && ( + {productSupportsField("version") && ( )} - {productSupportsField('buildID') && ( + {productSupportsField("buildID") && ( )} - {productSupportsField('locale') && ( + {productSupportsField("locale") && ( )} - {productSupportsField('osVersion') && ( + {productSupportsField("osVersion") && ( )} - {productSupportsField('buildTarget') && ( + {productSupportsField("buildTarget") && ( )} - {productSupportsField('instructionSet') && ( + {productSupportsField("instructionSet") && ( )} - {productSupportsField('memory') && ( + {productSupportsField("memory") && ( )} - {productSupportsField('jaws') && ( + {productSupportsField("jaws") && ( + onChange={handleInputChange} + > {EMPTY_MENU_ITEM_CHAR} @@ -606,7 +673,7 @@ function Rule({ isNewRule, user, ...props }) { )} - {productSupportsField('distribution') && ( + {productSupportsField("distribution") && ( )} - {productSupportsField('distVersion') && ( + {productSupportsField("distVersion") && ( )} - {productSupportsField('headerArchitecture') && ( + {productSupportsField("headerArchitecture") && ( )} - {productSupportsField('mig64') && ( + {productSupportsField("mig64") && ( + onChange={handleInputChange} + > {EMPTY_MENU_ITEM_CHAR} @@ -656,7 +724,7 @@ function Rule({ isNewRule, user, ...props }) { )} - {productSupportsField('alias') && ( + {productSupportsField("alias") && ( )} - {productSupportsField('update_type') && ( + {productSupportsField("update_type") && ( + onChange={handleInputChange} + > minor major )} - {productSupportsField('comment') && ( + {productSupportsField("comment") && ( - + {/* Add
to avoid material-ui error "you are providing a disabled `button` child to the Tooltip component." */}
+ })} + > + color="primary" + >
@@ -721,7 +792,8 @@ function Rule({ isNewRule, user, ...props }) { {hasScheduledChange && ( + ariaLabel="Secondary Actions" + > } From 31a6d3abb3cf9e13a4db79494ac105c30185ea21 Mon Sep 17 00:00:00 2001 From: AMUZY Date: Fri, 13 Oct 2023 18:57:15 +0100 Subject: [PATCH 02/14] refactored the code to fix test errors in github --- ui/src/views/Rules/Rule/index.jsx | 75 ++++++++++++++++++++++++++++--- 1 file changed, 70 insertions(+), 5 deletions(-) diff --git a/ui/src/views/Rules/Rule/index.jsx b/ui/src/views/Rules/Rule/index.jsx index a2242bb646..40e39df55b 100644 --- a/ui/src/views/Rules/Rule/index.jsx +++ b/ui/src/views/Rules/Rule/index.jsx @@ -38,6 +38,10 @@ import { SPLIT_WITH_NEWLINES_AND_COMMA_REGEX, RULE_PRODUCT_UNSUPPORTED_PROPERTIES, } from '../../../utils/constants'; +// ALL IMPORTS TO FETCH REQUIRED SIGNOFFS BELOW: +import { OBJECT_NAMES } from "../../../utils/constants"; +import { getRequiredSignoffs } from "../../../services/requiredSignoffs"; +import Typography from '@material-ui/core/Typography'; const initialRule = { alias: '', @@ -91,6 +95,7 @@ function Rule({ isNewRule, user, ...props }) { ? props.location.state.rulesFilter : []; const [rule, setRule] = useState(initialRule); + const [allRequiredSignOffs, setAllrequiredSignoffs] = useState([]); const [releaseNames, setReleaseNames] = useState([]); const [products, fetchProducts] = useAction(getProducts); const [channels, fetchChannels] = useAction(getChannels); @@ -395,13 +400,73 @@ function Rule({ isNewRule, user, ...props }) { return `Update Rule ${ruleId}${rule.alias ? ` (${rule.alias})` : ''}`; }; + const [requiredSignoffs, fetchRequiredSignoffs] = + useAction(getRequiredSignoffs); + + useEffect(() => { + let myPromise = new Promise((res) => { + res(fetchRequiredSignoffs(OBJECT_NAMES.PRODUCT_REQUIRED_SIGNOFF)); + }); + myPromise.then((rs) => { + setAllrequiredSignoffs(rs.data.data.required_signoffs); + }); + }, []); + + // SignOff style + const signoffStyle = { + div: { + display: "flex", + flexFlow: "row wrap", + width: "100%", + margin: "8px 0 8px 0", + alignItems: "center", + }, + p1: { + marginRight: "8px", + color: "gray", + }, + p2: { + color: "black", + }, + }; + return ( - {isLoading && } - {error && } - {!isLoading && ( - -
+ {isLoading && } + {error && } + {!isLoading && ( + /* + THE SIGN OFF DETAIL SHOULD GO JUST UNDERNEATH THE OPENING FRAGMENT + It should be in the form : + "SignOffs Required : 1 signoff from a releng user" + */ + + {/* SHOWS REQUIRED SIGNOFFS */} +
+ Required Signoff(s) : + {allRequiredSignOffs.map((reqSignOff, index, all) => { + if ( + rule.product === reqSignOff.product && + rule.channel === `${reqSignOff.channel}*` + ) { + return ( + {`${ + reqSignOff.signoffs_required + } member${reqSignOff.count > 1 ? "s" : ""} of ${ + reqSignOff.role + }${all[index + 1] ? "," : ""}`} + ); + } else { + return ( + + No signoffs provided for this product in local development + + ); + } + })} + {/* END OF REQUIRED SIGNOFFS INFO */} +
+
Date: Fri, 13 Oct 2023 19:19:57 +0100 Subject: [PATCH 03/14] fixed eslint errors --- ui/src/views/Rules/Rule/index.jsx | 136 +++++++++++++++--------------- 1 file changed, 68 insertions(+), 68 deletions(-) diff --git a/ui/src/views/Rules/Rule/index.jsx b/ui/src/views/Rules/Rule/index.jsx index f5c9d183c0..d52373f3b9 100644 --- a/ui/src/views/Rules/Rule/index.jsx +++ b/ui/src/views/Rules/Rule/index.jsx @@ -103,7 +103,7 @@ function Rule({ isNewRule, user, ...props }) { const [releaseNamesV2Action, fetchReleaseNamesV2] = useAction( getReleaseNamesV2 ); - // 30 seconds - to make sure the helper text 'Scheduled for ASAP' shows up + // 30 seconds - to make sure the helper text "Scheduled for ASAP" shows up const [scheduleDate, setScheduleDate] = useState(new Date()); const [dateTimePickerError, setDateTimePickerError] = useState(null); const [fetchRuleAction, fetchRule] = useAction(getRule); @@ -382,7 +382,7 @@ function Rule({ isNewRule, user, ...props }) { const today = new Date(); // This will make sure the helperText - // will always be displayed for a 'today' date + // will always be displayed for a "today" date today.setHours(0, 0, 0, 0); // To avoid nested ternary @@ -415,18 +415,18 @@ function Rule({ isNewRule, user, ...props }) { // SignOff style const signoffStyle = { div: { - display: 'flex', - flexFlow: 'row wrap', - width: '100%', - margin: '8px 0 8px 0', - alignItems: 'center', + display: "flex", + flexFlow: "row wrap", + width: "100%", + margin: "8px 0 8px 0", + alignItems: "center", }, p1: { - marginRight: '8px', - color: 'gray', + marginRight: "8px", + color: "gray", }, p2: { - color: 'black', + color: "black", }, }; @@ -438,27 +438,27 @@ function Rule({ isNewRule, user, ...props }) { /* THE SIGN OFF DETAIL SHOULD GO JUST UNDERNEATH THE OPENING FRAGMENT It should be in the form : - 'SignOffs Required : 1 signoff from a releng user' + "SignOffs Required : 1 signoff from a releng user" */ {/* SHOWS REQUIRED SIGNOFFS */}
- Required Signoff(s) : + Required Signoff(s) : {allRequiredSignOffs.map((reqSignOff, index, all) => { if ( rule.product === reqSignOff.product && rule.channel === `${reqSignOff.channel}*` ) { return ( - {`${ + {`${ reqSignOff.signoffs_required - } member${reqSignOff.count > 1 ? 's' : ''} of ${ + } member${reqSignOff.count > 1 ? "s" : ""} of ${ reqSignOff.role - }${all[index + 1] ? ',' : ''}`} + }${all[index + 1] ? "," : ""}`} ); } else { return ( - + No signoffs provided for this product in local development ); @@ -468,11 +468,11 @@ function Rule({ isNewRule, user, ...props }) {
@@ -586,9 +586,9 @@ function Rule({ isNewRule, user, ...props }) { @@ -596,13 +596,13 @@ function Rule({ isNewRule, user, ...props }) { {productSupportsField('locale') && ( @@ -610,13 +610,13 @@ function Rule({ isNewRule, user, ...props }) { {productSupportsField('osVersion') && ( @@ -625,9 +625,9 @@ function Rule({ isNewRule, user, ...props }) { @@ -636,9 +636,9 @@ function Rule({ isNewRule, user, ...props }) { @@ -647,9 +647,9 @@ function Rule({ isNewRule, user, ...props }) { @@ -658,16 +658,16 @@ function Rule({ isNewRule, user, ...props }) { {EMPTY_MENU_ITEM_CHAR} - Yes - No + Yes + No )} @@ -675,9 +675,9 @@ function Rule({ isNewRule, user, ...props }) { @@ -686,9 +686,9 @@ function Rule({ isNewRule, user, ...props }) { @@ -697,9 +697,9 @@ function Rule({ isNewRule, user, ...props }) { @@ -708,16 +708,16 @@ function Rule({ isNewRule, user, ...props }) { {EMPTY_MENU_ITEM_CHAR} - Yes - No + Yes + No )} @@ -725,9 +725,9 @@ function Rule({ isNewRule, user, ...props }) { @@ -738,12 +738,12 @@ function Rule({ isNewRule, user, ...props }) { fullWidth select required - label='Update Type' + label="Update Type" value={rule.update_type || 'minor'} - name='update_type' + name="update_type" onChange={handleInputChange}> - minor - major + minor + major )} @@ -753,9 +753,9 @@ function Rule({ isNewRule, user, ...props }) { fullWidth multiline rows={4} - label='Comment' + label="Comment" value={defaultToEmptyString(rule.comment)} - name='comment' + name="comment" onChange={handleInputChange} /> @@ -766,8 +766,8 @@ function Rule({ isNewRule, user, ...props }) { {!isLoading && ( - {/* Add
to avoid material-ui error 'you are providing - a disabled `button` child to the Tooltip component.' */} + {/* Add
to avoid material-ui error "you are providing + a disabled `button` child to the Tooltip component." */}
+ color="primary">
@@ -786,12 +786,12 @@ function Rule({ isNewRule, user, ...props }) { {hasScheduledChange && ( + ariaLabel="Secondary Actions"> } tooltipOpen - tooltipTitle='Cancel Pending Change' + tooltipTitle="Cancel Pending Change" onClick={handleScheduleChangeDelete} /> From ccc7078fb9b05ce076b877c67821026f1a6c2477 Mon Sep 17 00:00:00 2001 From: AMUZY Date: Fri, 13 Oct 2023 19:33:10 +0100 Subject: [PATCH 04/14] fixed eslint errors finally --- ui/src/views/Rules/Rule/index.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/src/views/Rules/Rule/index.jsx b/ui/src/views/Rules/Rule/index.jsx index d52373f3b9..3001a346bc 100644 --- a/ui/src/views/Rules/Rule/index.jsx +++ b/ui/src/views/Rules/Rule/index.jsx @@ -810,4 +810,4 @@ Rule.defaultProps = { isNewRule: false, }; -export default withUser(Rule); +export default withUser(Rule); \ No newline at end of file From 55838e9331dd53222de24afb93a939d9d6053cf7 Mon Sep 17 00:00:00 2001 From: AMUZY Date: Fri, 13 Oct 2023 21:12:55 +0100 Subject: [PATCH 05/14] tried to fix lint errors --- ui/package.json | 2 +- ui/src/views/Rules/Rule/index.jsx | 44 ++++++++++++++----------------- 2 files changed, 21 insertions(+), 25 deletions(-) diff --git a/ui/package.json b/ui/package.json index cb54482ad0..6044bcf95b 100644 --- a/ui/package.json +++ b/ui/package.json @@ -4,7 +4,7 @@ "main": "index.js", "license": "MIT", "engines": { - "node": ">=16.0.0 <17.0.0" + "node": ">=16.0.0" }, "scripts": { "build": "dotenv webpack -- --mode production", diff --git a/ui/src/views/Rules/Rule/index.jsx b/ui/src/views/Rules/Rule/index.jsx index 3001a346bc..f1827cd80d 100644 --- a/ui/src/views/Rules/Rule/index.jsx +++ b/ui/src/views/Rules/Rule/index.jsx @@ -444,29 +444,25 @@ function Rule({ isNewRule, user, ...props }) { {/* SHOWS REQUIRED SIGNOFFS */}
Required Signoff(s) : - {allRequiredSignOffs.map((reqSignOff, index, all) => { - if ( - rule.product === reqSignOff.product && - rule.channel === `${reqSignOff.channel}*` - ) { - return ( - {`${ - reqSignOff.signoffs_required - } member${reqSignOff.count > 1 ? "s" : ""} of ${ - reqSignOff.role - }${all[index + 1] ? "," : ""}`} - ); - } else { - return ( - - No signoffs provided for this product in local development - - ); - } - })} - {/* END OF REQUIRED SIGNOFFS INFO */} -
-
+ {allRequiredSignOffs.map((reqSignOff, inx, all) => { + if (rule.product === reqSignOff.product && rule.channel === `${reqSignOff.channel}*`) { + return ( + + {`${reqSignOff.signoffs_required} member${reqSignOff.count > 1 ? 's' : ''} of ${reqSignOff.role}${all[inx + 1] ? ',' : ''}`} + + ); + } + else { + return ( + + No signoffs provided for this product in local development + + ); + } + })} + {/* END OF REQUIRED SIGNOFFS INFO */} +
+
Date: Fri, 13 Oct 2023 21:17:02 +0100 Subject: [PATCH 06/14] updated required signoffs for rules --- ui/src/views/Rules/Rule/index.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/src/views/Rules/Rule/index.jsx b/ui/src/views/Rules/Rule/index.jsx index f1827cd80d..05b7223350 100644 --- a/ui/src/views/Rules/Rule/index.jsx +++ b/ui/src/views/Rules/Rule/index.jsx @@ -455,7 +455,7 @@ function Rule({ isNewRule, user, ...props }) { else { return ( - No signoffs provided for this product in local development + None ); } From d4abc85f59157f42f861e5615c67d374e0cc1883 Mon Sep 17 00:00:00 2001 From: AMUZY Date: Fri, 13 Oct 2023 22:10:01 +0100 Subject: [PATCH 07/14] fixed eslint errors 5 --- ui/src/views/Rules/Rule/index.jsx | 89 +++++++++++++++++++------------ 1 file changed, 54 insertions(+), 35 deletions(-) diff --git a/ui/src/views/Rules/Rule/index.jsx b/ui/src/views/Rules/Rule/index.jsx index 05b7223350..b0eb31a06d 100644 --- a/ui/src/views/Rules/Rule/index.jsx +++ b/ui/src/views/Rules/Rule/index.jsx @@ -14,6 +14,7 @@ import Fab from '@material-ui/core/Fab'; import SpeedDialAction from '@material-ui/lab/SpeedDialAction'; import ContentSaveIcon from 'mdi-react/ContentSaveIcon'; import DeleteIcon from 'mdi-react/DeleteIcon'; +import Typography from '@material-ui/core/Typography'; import Dashboard from '../../../components/Dashboard'; import ErrorPanel from '../../../components/ErrorPanel'; import AutoCompleteText from '../../../components/AutoCompleteText'; @@ -34,14 +35,13 @@ import { import { getReleaseNames, getReleaseNamesV2 } from '../../../services/releases'; import { withUser } from '../../../utils/AuthContext'; import { + OBJECT_NAMES, EMPTY_MENU_ITEM_CHAR, SPLIT_WITH_NEWLINES_AND_COMMA_REGEX, RULE_PRODUCT_UNSUPPORTED_PROPERTIES, } from '../../../utils/constants'; // ALL IMPORTS TO FETCH REQUIRED SIGNOFFS BELOW: -import { OBJECT_NAMES } from '../../../utils/constants'; import { getRequiredSignoffs } from '../../../services/requiredSignoffs'; -import Typography from '@material-ui/core/Typography'; const initialRule = { alias: '', @@ -400,14 +400,17 @@ function Rule({ isNewRule, user, ...props }) { return `Update Rule ${ruleId}${rule.alias ? ` (${rule.alias})` : ''}`; }; - const [requiredSignoffs, fetchRequiredSignoffs] = - useAction(getRequiredSignoffs); + // eslint-disable-next-line no-unused-vars + const [requiredSignoffs, fetchRequiredSignoffs] = useAction( + getRequiredSignoffs + ); useEffect(() => { - let myPromise = new Promise((res) => { + const myPromise = new Promise(res => { res(fetchRequiredSignoffs(OBJECT_NAMES.PRODUCT_REQUIRED_SIGNOFF)); }); - myPromise.then((rs) => { + + myPromise.then(rs => { setAllrequiredSignoffs(rs.data.data.required_signoffs); }); }, []); @@ -415,51 +418,67 @@ function Rule({ isNewRule, user, ...props }) { // SignOff style const signoffStyle = { div: { - display: "flex", - flexFlow: "row wrap", - width: "100%", - margin: "8px 0 8px 0", - alignItems: "center", + display: 'flex', + flexFlow: 'row wrap', + width: '100%', + margin: '8px 0 8px 0', + alignItems: 'center', }, p1: { - marginRight: "8px", - color: "gray", + marginRight: '8px', + color: 'gray', }, p2: { - color: "black", + color: 'black', }, }; return ( - {isLoading && } - {error && } - {!isLoading && ( - /* + {isLoading && } + {error && } + {!isLoading && ( + /* THE SIGN OFF DETAIL SHOULD GO JUST UNDERNEATH THE OPENING FRAGMENT It should be in the form : "SignOffs Required : 1 signoff from a releng user" */ - - {/* SHOWS REQUIRED SIGNOFFS */} -
- Required Signoff(s) : - {allRequiredSignOffs.map((reqSignOff, inx, all) => { - if (rule.product === reqSignOff.product && rule.channel === `${reqSignOff.channel}*`) { + + {/* SHOWS REQUIRED SIGNOFFS */} +
+ + Required Signoff(s) : + + {allRequiredSignOffs.map((reqSignOff, index, all) => { + const no = index; + + if ( + rule.product === reqSignOff.product && + rule.channel === `${reqSignOff.channel}*` + ) { return ( - - {`${reqSignOff.signoffs_required} member${reqSignOff.count > 1 ? 's' : ''} of ${reqSignOff.role}${all[inx + 1] ? ',' : ''}`} + + {`${reqSignOff.signoffs_required} member${ + reqSignOff.signoffs_required > 1 ? 's' : '' + } of ${reqSignOff.role}${all[index + 1] ? ',' : ''}`} ); - } - else { - return ( - - None - - ); - } - })} + } + + return ( + + None + + ); + })} {/* END OF REQUIRED SIGNOFFS INFO */}
From af85b25675de1f03371cbb51fbcfe96ad21c527c Mon Sep 17 00:00:00 2001 From: AMUZY Date: Sat, 14 Oct 2023 11:25:23 +0100 Subject: [PATCH 08/14] fixed the channel name release --- ui/src/views/Rules/Rule/index.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/src/views/Rules/Rule/index.jsx b/ui/src/views/Rules/Rule/index.jsx index b0eb31a06d..ec5a37e770 100644 --- a/ui/src/views/Rules/Rule/index.jsx +++ b/ui/src/views/Rules/Rule/index.jsx @@ -454,7 +454,7 @@ function Rule({ isNewRule, user, ...props }) { if ( rule.product === reqSignOff.product && - rule.channel === `${reqSignOff.channel}*` + rule.channel === `${reqSignOff.channel}` ) { return ( Date: Mon, 16 Oct 2023 11:23:14 +0100 Subject: [PATCH 09/14] just changed the signoffs display mode --- ui/src/components/SignoffSummary/index.jsx | 101 ++++++++++++++++++--- 1 file changed, 87 insertions(+), 14 deletions(-) diff --git a/ui/src/components/SignoffSummary/index.jsx b/ui/src/components/SignoffSummary/index.jsx index 7d94b0e578..60ab20f2f1 100644 --- a/ui/src/components/SignoffSummary/index.jsx +++ b/ui/src/components/SignoffSummary/index.jsx @@ -7,8 +7,18 @@ import ListItem from '@material-ui/core/ListItem'; import ListItemText from '@material-ui/core/ListItemText'; import ListSubheader from '@material-ui/core/ListSubheader'; import Typography from '@material-ui/core/Typography'; +import CheckCircleIcon from 'mdi-react/CheckCircleIcon'; +import AccountClockIcon from 'mdi-react/AccountClockIcon'; const useStyles = makeStyles(theme => ({ + approval: { + display: 'flex', + width: 'max-content', + flexFlow: 'row nowrap', + justifyContent: 'center', + alignItems: 'center', + margin: '0 2px 0 2px', + }, listSubheader: { lineHeight: 1.5, marginBottom: theme.spacing(0.5), @@ -21,7 +31,11 @@ const useStyles = makeStyles(theme => ({ marginBottom: 0, marginTop: 0, }, + signoffsContainer: { + display: 'flex', + }, signoffsList: { + width: 'max-content', marginRight: theme.spacing(6), paddingTop: 0, paddingBottom: 0, @@ -33,9 +47,10 @@ const useStyles = makeStyles(theme => ({ })); function SignoffSummary(props) { - const classes = useStyles(); const { requiredSignoffs, signoffs, className } = props; const listOfSignoffs = Object.entries(signoffs); + const theRequiredSignoffs = Object.entries(requiredSignoffs); + const classes = useStyles(); return (
@@ -46,24 +61,82 @@ function SignoffSummary(props) { Requires Signoffs From }> - {Object.entries(requiredSignoffs).map(([role, count], index) => { + {theRequiredSignoffs.map(([role, count], index) => { const key = `${role}-${index}`; + // AllSigned Returns all that have signed + let AllSigned = []; + + if (listOfSignoffs) { + AllSigned = listOfSignoffs.filter(arr => { + return role === arr[1]; + }); + } + + // AllNotSigned() Gets and returns all that haven't signed + const AllNotSigned = () => { + const leftarr = []; + const allleft = count - AllSigned.length; + + // Disabled eslint because "i+1" runs loop till eternity + // eslint-disable-next-line no-plusplus + for (let i = 0; i < allleft; i++) { + leftarr.push([]); + } + + return leftarr; + }; return ( - - - {`${count} member${count > 1 ? 's' : ''} of ${role}`} - - } - className={classes.listItemText} - /> - +
+ + + {`${count} member${count > 1 ? 's' : ''} of ${role} -`} + + } + className={classes.listItemText} + /> + {listOfSignoffs && ( + + {AllSigned.map((arr, index) => { + const no = index; + + return ( +
+ + + {`${arr[0]}`} + +
+ ); + })} + {AllNotSigned().map(arr => { + const no = arr; + + return ( +
+ + + Awaiting approval... + +
+ ); + })} +
+ )} +
+
); })} - {listOfSignoffs && Boolean(listOfSignoffs.length) && ( + {/* {listOfSignoffs && Boolean(listOfSignoffs.length) && ( ))} - )} + )} */}
); } From b66bd64c44139d043511b0c98ba0f8928dfcb183 Mon Sep 17 00:00:00 2001 From: AMUZY Date: Mon, 16 Oct 2023 11:54:06 +0100 Subject: [PATCH 10/14] signoffs display changed --- ui/src/views/Rules/Rule/index.jsx | 82 +------------------------------ 1 file changed, 1 insertion(+), 81 deletions(-) diff --git a/ui/src/views/Rules/Rule/index.jsx b/ui/src/views/Rules/Rule/index.jsx index ec5a37e770..342f8e9a15 100644 --- a/ui/src/views/Rules/Rule/index.jsx +++ b/ui/src/views/Rules/Rule/index.jsx @@ -14,7 +14,6 @@ import Fab from '@material-ui/core/Fab'; import SpeedDialAction from '@material-ui/lab/SpeedDialAction'; import ContentSaveIcon from 'mdi-react/ContentSaveIcon'; import DeleteIcon from 'mdi-react/DeleteIcon'; -import Typography from '@material-ui/core/Typography'; import Dashboard from '../../../components/Dashboard'; import ErrorPanel from '../../../components/ErrorPanel'; import AutoCompleteText from '../../../components/AutoCompleteText'; @@ -35,13 +34,10 @@ import { import { getReleaseNames, getReleaseNamesV2 } from '../../../services/releases'; import { withUser } from '../../../utils/AuthContext'; import { - OBJECT_NAMES, EMPTY_MENU_ITEM_CHAR, SPLIT_WITH_NEWLINES_AND_COMMA_REGEX, RULE_PRODUCT_UNSUPPORTED_PROPERTIES, } from '../../../utils/constants'; -// ALL IMPORTS TO FETCH REQUIRED SIGNOFFS BELOW: -import { getRequiredSignoffs } from '../../../services/requiredSignoffs'; const initialRule = { alias: '', @@ -95,7 +91,6 @@ function Rule({ isNewRule, user, ...props }) { ? props.location.state.rulesFilter : []; const [rule, setRule] = useState(initialRule); - const [allRequiredSignOffs, setAllrequiredSignoffs] = useState([]); const [releaseNames, setReleaseNames] = useState([]); const [products, fetchProducts] = useAction(getProducts); const [channels, fetchChannels] = useAction(getChannels); @@ -400,87 +395,12 @@ function Rule({ isNewRule, user, ...props }) { return `Update Rule ${ruleId}${rule.alias ? ` (${rule.alias})` : ''}`; }; - // eslint-disable-next-line no-unused-vars - const [requiredSignoffs, fetchRequiredSignoffs] = useAction( - getRequiredSignoffs - ); - - useEffect(() => { - const myPromise = new Promise(res => { - res(fetchRequiredSignoffs(OBJECT_NAMES.PRODUCT_REQUIRED_SIGNOFF)); - }); - - myPromise.then(rs => { - setAllrequiredSignoffs(rs.data.data.required_signoffs); - }); - }, []); - - // SignOff style - const signoffStyle = { - div: { - display: 'flex', - flexFlow: 'row wrap', - width: '100%', - margin: '8px 0 8px 0', - alignItems: 'center', - }, - p1: { - marginRight: '8px', - color: 'gray', - }, - p2: { - color: 'black', - }, - }; - return ( {isLoading && } {error && } {!isLoading && ( - /* - THE SIGN OFF DETAIL SHOULD GO JUST UNDERNEATH THE OPENING FRAGMENT - It should be in the form : - "SignOffs Required : 1 signoff from a releng user" - */ - {/* SHOWS REQUIRED SIGNOFFS */} -
- - Required Signoff(s) : - - {allRequiredSignOffs.map((reqSignOff, index, all) => { - const no = index; - - if ( - rule.product === reqSignOff.product && - rule.channel === `${reqSignOff.channel}` - ) { - return ( - - {`${reqSignOff.signoffs_required} member${ - reqSignOff.signoffs_required > 1 ? 's' : '' - } of ${reqSignOff.role}${all[index + 1] ? ',' : ''}`} - - ); - } - - return ( - - None - - ); - })} - {/* END OF REQUIRED SIGNOFFS INFO */} -
Date: Mon, 16 Oct 2023 17:33:07 +0100 Subject: [PATCH 11/14] fixed eslint error- all-good --- ui/src/views/Rules/Rule/index.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/src/views/Rules/Rule/index.jsx b/ui/src/views/Rules/Rule/index.jsx index 342f8e9a15..a2242bb646 100644 --- a/ui/src/views/Rules/Rule/index.jsx +++ b/ui/src/views/Rules/Rule/index.jsx @@ -745,4 +745,4 @@ Rule.defaultProps = { isNewRule: false, }; -export default withUser(Rule); \ No newline at end of file +export default withUser(Rule); From 75605cd0cd31f6b04ef8b5b66067285cbd0628d7 Mon Sep 17 00:00:00 2001 From: amuzy Date: Tue, 17 Oct 2023 21:38:27 +0100 Subject: [PATCH 12/14] perfected-code --- ui/src/components/SignoffSummary/index.jsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ui/src/components/SignoffSummary/index.jsx b/ui/src/components/SignoffSummary/index.jsx index 60ab20f2f1..4d1ccebccb 100644 --- a/ui/src/components/SignoffSummary/index.jsx +++ b/ui/src/components/SignoffSummary/index.jsx @@ -77,9 +77,7 @@ function SignoffSummary(props) { const leftarr = []; const allleft = count - AllSigned.length; - // Disabled eslint because "i+1" runs loop till eternity - // eslint-disable-next-line no-plusplus - for (let i = 0; i < allleft; i++) { + for (let i in allleft) { leftarr.push([]); } From 9ae89d65c9ea8de4c2dcc0a1294bb50eaf988f69 Mon Sep 17 00:00:00 2001 From: AMUZY Date: Tue, 17 Oct 2023 21:47:46 +0100 Subject: [PATCH 13/14] finishing touches --- ui/src/components/SignoffSummary/index.jsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/ui/src/components/SignoffSummary/index.jsx b/ui/src/components/SignoffSummary/index.jsx index 4d1ccebccb..d9150e195d 100644 --- a/ui/src/components/SignoffSummary/index.jsx +++ b/ui/src/components/SignoffSummary/index.jsx @@ -75,9 +75,12 @@ function SignoffSummary(props) { // AllNotSigned() Gets and returns all that haven't signed const AllNotSigned = () => { const leftarr = []; - const allleft = count - AllSigned.length; + const allLeft = count - AllSigned.length; - for (let i in allleft) { + // Disabled eslint because "i+1" runs loop till eternity + // and for in loop only works on arrays + // eslint-disable-next-line no-plusplus + for (let i = 0; i < allLeft; i++) { leftarr.push([]); } From 5781c11d5b65f749214c9868a2d0a73d4b5a1d1b Mon Sep 17 00:00:00 2001 From: amuzy Date: Wed, 18 Oct 2023 15:08:02 +0100 Subject: [PATCH 14/14] Implemented changes requested --- ui/package.json | 2 +- ui/src/components/SignoffSummary/index.jsx | 52 ++++------------------ 2 files changed, 10 insertions(+), 44 deletions(-) diff --git a/ui/package.json b/ui/package.json index 6044bcf95b..cb54482ad0 100644 --- a/ui/package.json +++ b/ui/package.json @@ -4,7 +4,7 @@ "main": "index.js", "license": "MIT", "engines": { - "node": ">=16.0.0" + "node": ">=16.0.0 <17.0.0" }, "scripts": { "build": "dotenv webpack -- --mode production", diff --git a/ui/src/components/SignoffSummary/index.jsx b/ui/src/components/SignoffSummary/index.jsx index d9150e195d..355c88ea64 100644 --- a/ui/src/components/SignoffSummary/index.jsx +++ b/ui/src/components/SignoffSummary/index.jsx @@ -63,24 +63,23 @@ function SignoffSummary(props) { }> {theRequiredSignoffs.map(([role, count], index) => { const key = `${role}-${index}`; - // AllSigned Returns all that have signed - let AllSigned = []; + // allSigned Returns all that have signed + let allSigned = []; if (listOfSignoffs) { - AllSigned = listOfSignoffs.filter(arr => { + allSigned = listOfSignoffs.filter(arr => { return role === arr[1]; }); } - // AllNotSigned() Gets and returns all that haven't signed - const AllNotSigned = () => { + // allNotSigned() Gets and returns all that haven't signed + const allNotSigned = () => { const leftarr = []; - const allLeft = count - AllSigned.length; + const allleft = count - allSigned.length; // Disabled eslint because "i+1" runs loop till eternity - // and for in loop only works on arrays // eslint-disable-next-line no-plusplus - for (let i = 0; i < allLeft; i++) { + for (let i = 0; i < allleft; i++) { leftarr.push([]); } @@ -100,7 +99,7 @@ function SignoffSummary(props) { /> {listOfSignoffs && ( - {AllSigned.map((arr, index) => { + {allSigned.map((arr, index) => { const no = index; return ( @@ -115,7 +114,7 @@ function SignoffSummary(props) {
); })} - {AllNotSigned().map(arr => { + {allNotSigned().map(arr => { const no = arr; return ( @@ -137,39 +136,6 @@ function SignoffSummary(props) { ); })} - {/* {listOfSignoffs && Boolean(listOfSignoffs.length) && ( - - Signed By - - }> - {listOfSignoffs.map(([username, signoffRole]) => ( - - - {username} -   -   - - {signoffRole} - -
- } - className={classes.listItemText} - /> - - ))} - - )} */}
); }