mirror of
https://github.com/Unleash/unleash.git
synced 2025-07-21 13:47:39 +02:00
refactor: format files (#719)
* refactor: fix deprecated prettier config name * refactor: add fmt scripts * refactor: check fmt during CI * refactor: format files
This commit is contained in:
parent
46bf92124d
commit
016633dae9
4
frontend/.github/workflows/node.js.yml
vendored
4
frontend/.github/workflows/node.js.yml
vendored
@ -25,6 +25,4 @@ jobs:
|
|||||||
node-version: ${{ matrix.node-version }}
|
node-version: ${{ matrix.node-version }}
|
||||||
- run: yarn
|
- run: yarn
|
||||||
- run: yarn run test
|
- run: yarn run test
|
||||||
|
- run: yarn run fmt:check
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"singleQuote": true,
|
"singleQuote": true,
|
||||||
"bracketSpacing": true,
|
"bracketSpacing": true,
|
||||||
"jsxBracketSameLine": false,
|
"bracketSameLine": false,
|
||||||
"arrowParens": "avoid",
|
"arrowParens": "avoid",
|
||||||
"printWidth": 80
|
"printWidth": 80
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,8 @@
|
|||||||
"start:demo": "UNLEASH_API=http://unleash.herokuapp.com yarn run start",
|
"start:demo": "UNLEASH_API=http://unleash.herokuapp.com yarn run start",
|
||||||
"test": "react-scripts test",
|
"test": "react-scripts test",
|
||||||
"prepare": "yarn run build",
|
"prepare": "yarn run build",
|
||||||
|
"fmt": "prettier src --write --loglevel warn",
|
||||||
|
"fmt:check": "prettier src --check",
|
||||||
"e2e": "yarn run cypress open --config baseUrl='http://localhost:3000' --env PASSWORD_AUTH=true,AUTH_TOKEN=$AUTH_TOKEN",
|
"e2e": "yarn run cypress open --config baseUrl='http://localhost:3000' --env PASSWORD_AUTH=true,AUTH_TOKEN=$AUTH_TOKEN",
|
||||||
"e2e:heroku": "yarn run cypress open --config baseUrl='http://localhost:3000' --env PASSWORD_AUTH=false,AUTH_TOKEN=$AUTH_TOKEN",
|
"e2e:heroku": "yarn run cypress open --config baseUrl='http://localhost:3000' --env PASSWORD_AUTH=false,AUTH_TOKEN=$AUTH_TOKEN",
|
||||||
"e2e:enterprise": "yarn run cypress open --config baseUrl='http://localhost:3000' --env PASSWORD_AUTH=true,ENTERPRISE=true,AUTH_TOKEN=$AUTH_TOKEN"
|
"e2e:enterprise": "yarn run cypress open --config baseUrl='http://localhost:3000' --env PASSWORD_AUTH=true,ENTERPRISE=true,AUTH_TOKEN=$AUTH_TOKEN"
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
export default 'SvgrURL'
|
export default 'SvgrURL';
|
||||||
export const ReactComponent = 'div'
|
export const ReactComponent = 'div';
|
||||||
|
@ -5,10 +5,10 @@ import ReportProblemOutlinedIcon from '@material-ui/icons/ReportProblemOutlined'
|
|||||||
import ConditionallyRender from '../../common/ConditionallyRender/ConditionallyRender';
|
import ConditionallyRender from '../../common/ConditionallyRender/ConditionallyRender';
|
||||||
import styles from './ReportCard.module.scss';
|
import styles from './ReportCard.module.scss';
|
||||||
import ReactTimeAgo from 'react-timeago';
|
import ReactTimeAgo from 'react-timeago';
|
||||||
import { IProjectHealthReport } from "../../../interfaces/project";
|
import { IProjectHealthReport } from '../../../interfaces/project';
|
||||||
|
|
||||||
interface IReportCardProps {
|
interface IReportCardProps {
|
||||||
healthReport: IProjectHealthReport
|
healthReport: IProjectHealthReport;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ReportCard = ({ healthReport }: IReportCardProps) => {
|
export const ReportCard = ({ healthReport }: IReportCardProps) => {
|
||||||
@ -37,7 +37,9 @@ export const ReportCard = ({ healthReport }: IReportCardProps) => {
|
|||||||
const renderPotentiallyStaleToggles = () => (
|
const renderPotentiallyStaleToggles = () => (
|
||||||
<>
|
<>
|
||||||
<ReportProblemOutlinedIcon className={styles.danger} />
|
<ReportProblemOutlinedIcon className={styles.danger} />
|
||||||
<span>{healthReport.potentiallyStaleCount} potentially stale toggles</span>
|
<span>
|
||||||
|
{healthReport.potentiallyStaleCount} potentially stale toggles
|
||||||
|
</span>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -51,7 +53,9 @@ export const ReportCard = ({ healthReport }: IReportCardProps) => {
|
|||||||
condition={healthReport.health > -1}
|
condition={healthReport.health > -1}
|
||||||
show={
|
show={
|
||||||
<div>
|
<div>
|
||||||
<p className={healthClasses}>{healthReport.health}%</p>
|
<p className={healthClasses}>
|
||||||
|
{healthReport.health}%
|
||||||
|
</p>
|
||||||
<p className={styles.lastUpdate}>
|
<p className={styles.lastUpdate}>
|
||||||
Last updated:{' '}
|
Last updated:{' '}
|
||||||
<ReactTimeAgo
|
<ReactTimeAgo
|
||||||
@ -97,13 +101,17 @@ export const ReportCard = ({ healthReport }: IReportCardProps) => {
|
|||||||
<ul className={styles.reportCardList}>
|
<ul className={styles.reportCardList}>
|
||||||
<li>
|
<li>
|
||||||
<ConditionallyRender
|
<ConditionallyRender
|
||||||
condition={Boolean(healthReport.potentiallyStaleCount)}
|
condition={Boolean(
|
||||||
|
healthReport.potentiallyStaleCount
|
||||||
|
)}
|
||||||
show={renderPotentiallyStaleToggles}
|
show={renderPotentiallyStaleToggles}
|
||||||
/>
|
/>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<ConditionallyRender
|
<ConditionallyRender
|
||||||
condition={Boolean(healthReport.potentiallyStaleCount)}
|
condition={Boolean(
|
||||||
|
healthReport.potentiallyStaleCount
|
||||||
|
)}
|
||||||
show={
|
show={
|
||||||
<p className={styles.reportCardActionText}>
|
<p className={styles.reportCardActionText}>
|
||||||
Review your feature toggles and delete
|
Review your feature toggles and delete
|
||||||
|
@ -18,35 +18,35 @@ export const useStyles = makeStyles(theme => ({
|
|||||||
marginBottom: '1rem',
|
marginBottom: '1rem',
|
||||||
},
|
},
|
||||||
center: {
|
center: {
|
||||||
textAlign: 'center'
|
textAlign: 'center',
|
||||||
},
|
},
|
||||||
actionsContainer: {
|
actionsContainer: {
|
||||||
textAlign: 'center',
|
textAlign: 'center',
|
||||||
display: 'flex-inline',
|
display: 'flex-inline',
|
||||||
flexWrap: 'nowrap'
|
flexWrap: 'nowrap',
|
||||||
},
|
},
|
||||||
infoBoxContainer:{
|
infoBoxContainer: {
|
||||||
marginBottom:40
|
marginBottom: 40,
|
||||||
},
|
},
|
||||||
hideSM:{
|
hideSM: {
|
||||||
[theme.breakpoints.down('sm')]: {
|
[theme.breakpoints.down('sm')]: {
|
||||||
display: 'none'
|
display: 'none',
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
hideMD:{
|
hideMD: {
|
||||||
[theme.breakpoints.down('md')]: {
|
[theme.breakpoints.down('md')]: {
|
||||||
display: 'none'
|
display: 'none',
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
hideXS:{
|
hideXS: {
|
||||||
[theme.breakpoints.down('xs')]: {
|
[theme.breakpoints.down('xs')]: {
|
||||||
display: 'none'
|
display: 'none',
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
token:{
|
token: {
|
||||||
textAlign: 'left',
|
textAlign: 'left',
|
||||||
[theme.breakpoints.up('sm')]: {
|
[theme.breakpoints.up('sm')]: {
|
||||||
display: 'none'
|
display: 'none',
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}));
|
}));
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
function Secret({ value }) {
|
function Secret({ value }) {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<span style={{ width: '250px', display: 'inline-block' }}>************************************</span>
|
<span style={{ width: '250px', display: 'inline-block' }}>
|
||||||
|
************************************
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ const useApiToken = (
|
|||||||
setType(initialtype);
|
setType(initialtype);
|
||||||
if (type === 'ADMIN') {
|
if (type === 'ADMIN') {
|
||||||
setProject('*');
|
setProject('*');
|
||||||
setEnvironment('*')
|
setEnvironment('*');
|
||||||
}
|
}
|
||||||
//eslint-disable-next-line react-hooks/exhaustive-deps
|
//eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [initialtype]);
|
}, [initialtype]);
|
||||||
@ -35,11 +35,11 @@ const useApiToken = (
|
|||||||
|
|
||||||
const setTokenType = (value: string) => {
|
const setTokenType = (value: string) => {
|
||||||
if (value === 'ADMIN') {
|
if (value === 'ADMIN') {
|
||||||
setType(value)
|
setType(value);
|
||||||
setProject('*');
|
setProject('*');
|
||||||
setEnvironment('*');
|
setEnvironment('*');
|
||||||
} else {
|
} else {
|
||||||
setType(value)
|
setType(value);
|
||||||
setEnvironment(initialEnvironment);
|
setEnvironment(initialEnvironment);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -9,10 +9,7 @@ const ApiPage = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<ConditionallyRender
|
<ConditionallyRender condition={isAdmin} show={<AdminMenu />} />
|
||||||
condition={isAdmin}
|
|
||||||
show={<AdminMenu />}
|
|
||||||
/>
|
|
||||||
<ApiTokenList />
|
<ApiTokenList />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -7,4 +7,3 @@ export const useStyles = makeStyles(theme => ({
|
|||||||
position: 'relative',
|
position: 'relative',
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
@ -97,10 +97,7 @@ const CreateUser = () => {
|
|||||||
setRootRole={setRootRole}
|
setRootRole={setRootRole}
|
||||||
clearErrors={clearErrors}
|
clearErrors={clearErrors}
|
||||||
>
|
>
|
||||||
<PermissionButton
|
<PermissionButton permission={ADMIN} type="submit">
|
||||||
permission={ADMIN}
|
|
||||||
type="submit"
|
|
||||||
>
|
|
||||||
Create user
|
Create user
|
||||||
</PermissionButton>
|
</PermissionButton>
|
||||||
</UserForm>
|
</UserForm>
|
||||||
|
@ -35,11 +35,7 @@ const EditUser = () => {
|
|||||||
validateName,
|
validateName,
|
||||||
errors,
|
errors,
|
||||||
clearErrors,
|
clearErrors,
|
||||||
} = useAddUserForm(
|
} = useAddUserForm(user?.name, user?.email, user?.rootRole);
|
||||||
user?.name,
|
|
||||||
user?.email,
|
|
||||||
user?.rootRole
|
|
||||||
);
|
|
||||||
|
|
||||||
const formatApiCode = () => {
|
const formatApiCode = () => {
|
||||||
return `curl --location --request PUT '${
|
return `curl --location --request PUT '${
|
||||||
@ -98,10 +94,7 @@ const EditUser = () => {
|
|||||||
clearErrors={clearErrors}
|
clearErrors={clearErrors}
|
||||||
mode={EDIT}
|
mode={EDIT}
|
||||||
>
|
>
|
||||||
<PermissionButton
|
<PermissionButton permission={ADMIN} type="submit">
|
||||||
permission={ADMIN}
|
|
||||||
type="submit"
|
|
||||||
>
|
|
||||||
Edit user
|
Edit user
|
||||||
</PermissionButton>
|
</PermissionButton>
|
||||||
</UserForm>
|
</UserForm>
|
||||||
|
@ -6,7 +6,7 @@ export const useStyles = makeStyles(theme => ({
|
|||||||
backgroundColor: theme.palette.grey[200],
|
backgroundColor: theme.palette.grey[200],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
leftTableCell:{
|
leftTableCell: {
|
||||||
textAlign: 'left'
|
textAlign: 'left',
|
||||||
}
|
},
|
||||||
}));
|
}));
|
||||||
|
@ -14,7 +14,7 @@ import AccessContext from '../../../../../contexts/AccessContext';
|
|||||||
import { IUser } from '../../../../../interfaces/user';
|
import { IUser } from '../../../../../interfaces/user';
|
||||||
import { useStyles } from './UserListItem.styles';
|
import { useStyles } from './UserListItem.styles';
|
||||||
import { useHistory } from 'react-router-dom';
|
import { useHistory } from 'react-router-dom';
|
||||||
import { ILocationSettings } from "../../../../../hooks/useLocationSettings";
|
import { ILocationSettings } from '../../../../../hooks/useLocationSettings';
|
||||||
|
|
||||||
interface IUserListItemProps {
|
interface IUserListItemProps {
|
||||||
user: IUser;
|
user: IUser;
|
||||||
@ -34,7 +34,7 @@ const UserListItem = ({
|
|||||||
locationSettings,
|
locationSettings,
|
||||||
}: IUserListItemProps) => {
|
}: IUserListItemProps) => {
|
||||||
const { hasAccess } = useContext(AccessContext);
|
const { hasAccess } = useContext(AccessContext);
|
||||||
const history = useHistory()
|
const history = useHistory();
|
||||||
const styles = useStyles();
|
const styles = useStyles();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -51,7 +51,10 @@ const UserListItem = ({
|
|||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell>
|
<TableCell>
|
||||||
<span data-loading>
|
<span data-loading>
|
||||||
{formatDateWithLocale(user.createdAt, locationSettings.locale)}
|
{formatDateWithLocale(
|
||||||
|
user.createdAt,
|
||||||
|
locationSettings.locale
|
||||||
|
)}
|
||||||
</span>
|
</span>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell className={styles.leftTableCell}>
|
<TableCell className={styles.leftTableCell}>
|
||||||
@ -77,7 +80,9 @@ const UserListItem = ({
|
|||||||
data-loading
|
data-loading
|
||||||
aria-label="Edit"
|
aria-label="Edit"
|
||||||
title="Edit"
|
title="Edit"
|
||||||
onClick={()=> history.push(`/admin/users/${user.id}/edit`)}
|
onClick={() =>
|
||||||
|
history.push(`/admin/users/${user.id}/edit`)
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<Edit />
|
<Edit />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
|
@ -23,7 +23,7 @@ import PaginateUI from '../../../common/PaginateUI/PaginateUI';
|
|||||||
import { IUser } from '../../../../interfaces/user';
|
import { IUser } from '../../../../interfaces/user';
|
||||||
import IRole from '../../../../interfaces/role';
|
import IRole from '../../../../interfaces/role';
|
||||||
import useToast from '../../../../hooks/useToast';
|
import useToast from '../../../../hooks/useToast';
|
||||||
import { useLocationSettings } from "../../../../hooks/useLocationSettings";
|
import { useLocationSettings } from '../../../../hooks/useLocationSettings';
|
||||||
|
|
||||||
const UsersList = () => {
|
const UsersList = () => {
|
||||||
const { users, roles, refetch, loading } = useUsers();
|
const { users, roles, refetch, loading } = useUsers();
|
||||||
@ -36,7 +36,7 @@ const UsersList = () => {
|
|||||||
userApiErrors,
|
userApiErrors,
|
||||||
} = useAdminUsersApi();
|
} = useAdminUsersApi();
|
||||||
const { hasAccess } = useContext(AccessContext);
|
const { hasAccess } = useContext(AccessContext);
|
||||||
const { locationSettings } = useLocationSettings()
|
const { locationSettings } = useLocationSettings();
|
||||||
const [pwDialog, setPwDialog] = useState<{ open: boolean; user?: IUser }>({
|
const [pwDialog, setPwDialog] = useState<{ open: boolean; user?: IUser }>({
|
||||||
open: false,
|
open: false,
|
||||||
});
|
});
|
||||||
|
@ -26,9 +26,8 @@ const BreadcrumbNav = () => {
|
|||||||
item !== 'strategies' &&
|
item !== 'strategies' &&
|
||||||
item !== 'features' &&
|
item !== 'features' &&
|
||||||
item !== 'features2' &&
|
item !== 'features2' &&
|
||||||
item !== 'create-toggle'&&
|
item !== 'create-toggle' &&
|
||||||
item !== 'settings'
|
item !== 'settings'
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -52,7 +51,10 @@ const BreadcrumbNav = () => {
|
|||||||
styles.breadcrumbNavParagraph
|
styles.breadcrumbNavParagraph
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<StringTruncator text={path} maxWidth="200" />
|
<StringTruncator
|
||||||
|
text={path}
|
||||||
|
maxWidth="200"
|
||||||
|
/>
|
||||||
</p>
|
</p>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -73,7 +75,10 @@ const BreadcrumbNav = () => {
|
|||||||
className={styles.breadcrumbLink}
|
className={styles.breadcrumbLink}
|
||||||
to={link}
|
to={link}
|
||||||
>
|
>
|
||||||
<StringTruncator text={path} maxWidth="200" />
|
<StringTruncator
|
||||||
|
text={path}
|
||||||
|
maxWidth="200"
|
||||||
|
/>
|
||||||
</Link>
|
</Link>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
@ -71,9 +71,7 @@ const FormTemplate: React.FC<ICreateProps> = ({
|
|||||||
<>
|
<>
|
||||||
<h3 className={styles.subtitle}>
|
<h3 className={styles.subtitle}>
|
||||||
API Command{' '}
|
API Command{' '}
|
||||||
<IconButton
|
<IconButton onClick={copyCommand}>
|
||||||
onClick={copyCommand}
|
|
||||||
>
|
|
||||||
<FileCopy className={styles.icon} />
|
<FileCopy className={styles.icon} />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</h3>
|
</h3>
|
||||||
|
@ -11,6 +11,6 @@ export const useStyles = makeStyles(theme => ({
|
|||||||
envName: {
|
envName: {
|
||||||
position: 'relative',
|
position: 'relative',
|
||||||
top: '6px',
|
top: '6px',
|
||||||
fontWeight: 'bold'
|
fontWeight: 'bold',
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
@ -1,17 +1,35 @@
|
|||||||
import { formatFullDateTimeWithLocale } from '../util';
|
import { formatFullDateTimeWithLocale } from '../util';
|
||||||
|
|
||||||
test.skip('formats dates correctly', () => {
|
test.skip('formats dates correctly', () => {
|
||||||
expect(formatFullDateTimeWithLocale(1487861809466, 'nb-NO', 'UTC')).toEqual('2017-02-23 14:56:49');
|
expect(formatFullDateTimeWithLocale(1487861809466, 'nb-NO', 'UTC')).toEqual(
|
||||||
expect(formatFullDateTimeWithLocale(1487861809466, 'nb-NO', 'Europe/Paris')).toEqual('2017-02-23 15:56:49');
|
'2017-02-23 14:56:49'
|
||||||
expect(formatFullDateTimeWithLocale(1487861809466, 'nb-NO', 'Europe/Oslo')).toEqual('2017-02-23 15:56:49');
|
);
|
||||||
expect(formatFullDateTimeWithLocale(1487861809466, 'nb-NO', 'Europe/London')).toEqual('2017-02-23 14:56:49');
|
expect(
|
||||||
expect(formatFullDateTimeWithLocale(1487861809466, 'en-GB', 'Europe/Paris')).toEqual('02/23/2017, 3:56:49 PM');
|
formatFullDateTimeWithLocale(1487861809466, 'nb-NO', 'Europe/Paris')
|
||||||
expect(formatFullDateTimeWithLocale(1487861809466, 'en-GB', 'Europe/Oslo')).toEqual('02/23/2017, 3:56:49 PM');
|
).toEqual('2017-02-23 15:56:49');
|
||||||
expect(formatFullDateTimeWithLocale(1487861809466, 'en-GB', 'Europe/London')).toEqual('02/23/2017, 2:56:49 PM');
|
expect(
|
||||||
|
formatFullDateTimeWithLocale(1487861809466, 'nb-NO', 'Europe/Oslo')
|
||||||
|
).toEqual('2017-02-23 15:56:49');
|
||||||
|
expect(
|
||||||
|
formatFullDateTimeWithLocale(1487861809466, 'nb-NO', 'Europe/London')
|
||||||
|
).toEqual('2017-02-23 14:56:49');
|
||||||
|
expect(
|
||||||
|
formatFullDateTimeWithLocale(1487861809466, 'en-GB', 'Europe/Paris')
|
||||||
|
).toEqual('02/23/2017, 3:56:49 PM');
|
||||||
|
expect(
|
||||||
|
formatFullDateTimeWithLocale(1487861809466, 'en-GB', 'Europe/Oslo')
|
||||||
|
).toEqual('02/23/2017, 3:56:49 PM');
|
||||||
|
expect(
|
||||||
|
formatFullDateTimeWithLocale(1487861809466, 'en-GB', 'Europe/London')
|
||||||
|
).toEqual('02/23/2017, 2:56:49 PM');
|
||||||
|
|
||||||
expect(formatFullDateTimeWithLocale(1487861809466, 'nb-NO')).toEqual(
|
expect(formatFullDateTimeWithLocale(1487861809466, 'nb-NO')).toEqual(
|
||||||
expect.stringMatching(/(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})/)
|
expect.stringMatching(/(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})/)
|
||||||
);
|
);
|
||||||
expect(formatFullDateTimeWithLocale(1487861809466, 'en-GB')).toEqual(expect.stringContaining('02/23/2017'));
|
expect(formatFullDateTimeWithLocale(1487861809466, 'en-GB')).toEqual(
|
||||||
expect(formatFullDateTimeWithLocale(1487861809466, 'en-US')).toEqual(expect.stringContaining('02/23/2017'));
|
expect.stringContaining('02/23/2017')
|
||||||
|
);
|
||||||
|
expect(formatFullDateTimeWithLocale(1487861809466, 'en-US')).toEqual(
|
||||||
|
expect.stringContaining('02/23/2017')
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
@ -46,7 +46,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.dataTableHeader {
|
.dataTableHeader {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
@ -110,7 +110,7 @@ export const modalStyles = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const showPnpsFeedback = (feedbackList) => {
|
export const showPnpsFeedback = feedbackList => {
|
||||||
if (!feedbackList) return;
|
if (!feedbackList) return;
|
||||||
if (feedbackList.length > 0) {
|
if (feedbackList.length > 0) {
|
||||||
const feedback = feedbackList.find(
|
const feedback = feedbackList.find(
|
||||||
@ -135,4 +135,4 @@ export const showPnpsFeedback = (feedbackList) => {
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const PNPS_FEEDBACK_ID = 'pnps'
|
export const PNPS_FEEDBACK_ID = 'pnps';
|
||||||
|
@ -10,8 +10,8 @@ export const useStyles = makeStyles(theme => ({
|
|||||||
height: '100%',
|
height: '100%',
|
||||||
},
|
},
|
||||||
input: { width: '100%', marginBottom: '1rem' },
|
input: { width: '100%', marginBottom: '1rem' },
|
||||||
inputHeader:{
|
inputHeader: {
|
||||||
marginBottom: '0.3rem'
|
marginBottom: '0.3rem',
|
||||||
},
|
},
|
||||||
label: {
|
label: {
|
||||||
minWidth: '300px',
|
minWidth: '300px',
|
||||||
@ -22,7 +22,7 @@ export const useStyles = makeStyles(theme => ({
|
|||||||
tagContainer: {
|
tagContainer: {
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
alignItems: 'flex-start',
|
alignItems: 'flex-start',
|
||||||
marginBottom: '1rem'
|
marginBottom: '1rem',
|
||||||
},
|
},
|
||||||
tagInput: {
|
tagInput: {
|
||||||
width: '75%',
|
width: '75%',
|
||||||
@ -30,7 +30,7 @@ export const useStyles = makeStyles(theme => ({
|
|||||||
},
|
},
|
||||||
tagValue: {
|
tagValue: {
|
||||||
marginRight: '3px',
|
marginRight: '3px',
|
||||||
marginBottom: '1rem'
|
marginBottom: '1rem',
|
||||||
},
|
},
|
||||||
buttonContainer: {
|
buttonContainer: {
|
||||||
marginTop: 'auto',
|
marginTop: 'auto',
|
||||||
@ -62,6 +62,6 @@ export const useStyles = makeStyles(theme => ({
|
|||||||
switchContainer: {
|
switchContainer: {
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
marginLeft: '-9px'
|
marginLeft: '-9px',
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
@ -112,7 +112,7 @@ const ContextForm: React.FC<IContextForm> = ({
|
|||||||
autoFocus
|
autoFocus
|
||||||
/>
|
/>
|
||||||
<p className={styles.inputDescription}>
|
<p className={styles.inputDescription}>
|
||||||
What is this context for?
|
What is this context for?
|
||||||
</p>
|
</p>
|
||||||
<TextField
|
<TextField
|
||||||
className={styles.input}
|
className={styles.input}
|
||||||
|
@ -100,10 +100,7 @@ const CreateEnvironment = () => {
|
|||||||
mode="Create"
|
mode="Create"
|
||||||
clearErrors={clearErrors}
|
clearErrors={clearErrors}
|
||||||
>
|
>
|
||||||
<PermissionButton
|
<PermissionButton permission={ADMIN} type="submit">
|
||||||
permission={ADMIN}
|
|
||||||
type="submit"
|
|
||||||
>
|
|
||||||
Create environment
|
Create environment
|
||||||
</PermissionButton>
|
</PermissionButton>
|
||||||
</EnvironmentForm>
|
</EnvironmentForm>
|
||||||
|
@ -85,10 +85,7 @@ const EditEnvironment = () => {
|
|||||||
errors={errors}
|
errors={errors}
|
||||||
clearErrors={clearErrors}
|
clearErrors={clearErrors}
|
||||||
>
|
>
|
||||||
<PermissionButton
|
<PermissionButton permission={ADMIN} type="submit">
|
||||||
permission={ADMIN}
|
|
||||||
type="submit"
|
|
||||||
>
|
|
||||||
Edit environment
|
Edit environment
|
||||||
</PermissionButton>
|
</PermissionButton>
|
||||||
</EnvironmentForm>
|
</EnvironmentForm>
|
||||||
|
@ -1,10 +1,7 @@
|
|||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import useEnvironmentApi from '../../../hooks/api/actions/useEnvironmentApi/useEnvironmentApi';
|
import useEnvironmentApi from '../../../hooks/api/actions/useEnvironmentApi/useEnvironmentApi';
|
||||||
|
|
||||||
const useEnvironmentForm = (
|
const useEnvironmentForm = (initialName = '', initialType = 'development') => {
|
||||||
initialName = '',
|
|
||||||
initialType = 'development'
|
|
||||||
) => {
|
|
||||||
const NAME_EXISTS_ERROR = 'Error: Environment';
|
const NAME_EXISTS_ERROR = 'Error: Environment';
|
||||||
const [name, setName] = useState(initialName);
|
const [name, setName] = useState(initialName);
|
||||||
const [type, setType] = useState(initialType);
|
const [type, setType] = useState(initialType);
|
||||||
|
@ -9,7 +9,6 @@
|
|||||||
|
|
||||||
.content {
|
.content {
|
||||||
padding: var(--card-padding);
|
padding: var(--card-padding);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.content form {
|
.content form {
|
||||||
|
@ -1,21 +1,27 @@
|
|||||||
import { Tooltip } from '@material-ui/core';
|
import { Tooltip } from '@material-ui/core';
|
||||||
import { formatDateWithLocale, formatFullDateTimeWithLocale } from '../../../common/util';
|
import {
|
||||||
import { useLocationSettings } from "../../../../hooks/useLocationSettings";
|
formatDateWithLocale,
|
||||||
|
formatFullDateTimeWithLocale,
|
||||||
|
} from '../../../common/util';
|
||||||
|
import { useLocationSettings } from '../../../../hooks/useLocationSettings';
|
||||||
|
|
||||||
interface CreatedAtProps {
|
interface CreatedAtProps {
|
||||||
time: Date;
|
time: Date;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CreatedAt = ({time}: CreatedAtProps) => {
|
const CreatedAt = ({ time }: CreatedAtProps) => {
|
||||||
const { locationSettings } = useLocationSettings();
|
const { locationSettings } = useLocationSettings();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tooltip title={`Created at ${formatFullDateTimeWithLocale(time, locationSettings.locale)}`}>
|
<Tooltip
|
||||||
<span>
|
title={`Created at ${formatFullDateTimeWithLocale(
|
||||||
{formatDateWithLocale(time, locationSettings.locale)}
|
time,
|
||||||
</span>
|
locationSettings.locale
|
||||||
|
)}`}
|
||||||
|
>
|
||||||
|
<span>{formatDateWithLocale(time, locationSettings.locale)}</span>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
export default CreatedAt;
|
export default CreatedAt;
|
||||||
|
@ -10,7 +10,7 @@ const FeatureLog = () => {
|
|||||||
const { feature } = useFeature(projectId, featureId);
|
const { feature } = useFeature(projectId, featureId);
|
||||||
|
|
||||||
if (!feature.name) {
|
if (!feature.name) {
|
||||||
return null
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import PercentageCircle from '../../../../common/PercentageCircle/PercentageCircle';
|
import PercentageCircle from '../../../../common/PercentageCircle/PercentageCircle';
|
||||||
import { useStyles } from './FeatureEnvironmentMetrics.styles';
|
import { useStyles } from './FeatureEnvironmentMetrics.styles';
|
||||||
import {FiberManualRecord} from '@material-ui/icons';
|
import { FiberManualRecord } from '@material-ui/icons';
|
||||||
import { useMediaQuery } from '@material-ui/core';
|
import { useMediaQuery } from '@material-ui/core';
|
||||||
import { IFeatureEnvironmentMetrics } from '../../../../../interfaces/featureToggle';
|
import { IFeatureEnvironmentMetrics } from '../../../../../interfaces/featureToggle';
|
||||||
import { parseISO } from 'date-fns';
|
import { parseISO } from 'date-fns';
|
||||||
|
@ -11,5 +11,5 @@ export const useStyles = makeStyles(theme => ({
|
|||||||
whiteSpace: 'nowrap',
|
whiteSpace: 'nowrap',
|
||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
textOverflow: 'ellipsis',
|
textOverflow: 'ellipsis',
|
||||||
}
|
},
|
||||||
}));
|
}));
|
||||||
|
@ -12,24 +12,24 @@ const FeatureSeenApplications: React.FC = () => {
|
|||||||
const styles = useStyles();
|
const styles = useStyles();
|
||||||
const seenApplications = (seenApps: string[]) => {
|
const seenApplications = (seenApps: string[]) => {
|
||||||
return seenApps.map(appName => {
|
return seenApps.map(appName => {
|
||||||
return (<Grid item md={4} xs={6} xl={3}>
|
return (
|
||||||
<Link
|
<Grid item md={4} xs={6} xl={3}>
|
||||||
to={`/applications/${appName}`}
|
<Link
|
||||||
className={[
|
to={`/applications/${appName}`}
|
||||||
styles.listLink,
|
className={[styles.listLink, styles.truncate].join(' ')}
|
||||||
styles.truncate
|
>
|
||||||
].join(' ')}
|
{appName}
|
||||||
>
|
</Link>
|
||||||
{appName}
|
</Grid>
|
||||||
</Link>
|
);
|
||||||
</Grid>);
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const noApplications = (<Grid item xs={12}>
|
const noApplications = (
|
||||||
<div>{'Not seen in any applications'}</div>
|
<Grid item xs={12}>
|
||||||
</Grid>);
|
<div>{'Not seen in any applications'}</div>
|
||||||
|
</Grid>
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Grid container spacing={1}>
|
<Grid container spacing={1}>
|
||||||
@ -37,7 +37,8 @@ const FeatureSeenApplications: React.FC = () => {
|
|||||||
<ConditionallyRender
|
<ConditionallyRender
|
||||||
condition={metrics?.seenApplications?.length > 0}
|
condition={metrics?.seenApplications?.length > 0}
|
||||||
show={seenApplications(metrics.seenApplications)}
|
show={seenApplications(metrics.seenApplications)}
|
||||||
elseShow={noApplications} />
|
elseShow={noApplications}
|
||||||
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -21,12 +21,11 @@ const FeatureSettingsProject = () => {
|
|||||||
const [dirty, setDirty] = useState(false);
|
const [dirty, setDirty] = useState(false);
|
||||||
const [showConfirmDialog, setShowConfirmDialog] = useState(false);
|
const [showConfirmDialog, setShowConfirmDialog] = useState(false);
|
||||||
const editable = hasAccess(MOVE_FEATURE_TOGGLE, projectId);
|
const editable = hasAccess(MOVE_FEATURE_TOGGLE, projectId);
|
||||||
const { permissions = [] } = useAuthPermissions()
|
const { permissions = [] } = useAuthPermissions();
|
||||||
const { changeFeatureProject } = useFeatureApi();
|
const { changeFeatureProject } = useFeatureApi();
|
||||||
const { setToastData, setToastApiError } = useToast();
|
const { setToastData, setToastApiError } = useToast();
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (project !== feature.project) {
|
if (project !== feature.project) {
|
||||||
setDirty(true);
|
setDirty(true);
|
||||||
|
@ -148,16 +148,9 @@ const FeatureStrategyAccordionBody: React.FC<
|
|||||||
const { parameters } = strategy;
|
const { parameters } = strategy;
|
||||||
const ON = uiConfig.flags[C];
|
const ON = uiConfig.flags[C];
|
||||||
|
|
||||||
const editable = hasAccess(
|
const editable =
|
||||||
UPDATE_FEATURE_STRATEGY,
|
hasAccess(UPDATE_FEATURE_STRATEGY, projectId, activeEnvironment.name) ||
|
||||||
projectId,
|
hasAccess(CREATE_FEATURE_STRATEGY, projectId, activeEnvironment.name);
|
||||||
activeEnvironment.name
|
|
||||||
) ||
|
|
||||||
hasAccess(
|
|
||||||
CREATE_FEATURE_STRATEGY,
|
|
||||||
projectId,
|
|
||||||
activeEnvironment.name
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.accordionContainer}>
|
<div className={styles.accordionContainer}>
|
||||||
|
@ -29,7 +29,7 @@ const FlexibleStrategy = ({
|
|||||||
updateParameter,
|
updateParameter,
|
||||||
parameters,
|
parameters,
|
||||||
context,
|
context,
|
||||||
editable=true
|
editable = true,
|
||||||
}: IFlexibleStrategyProps) => {
|
}: IFlexibleStrategyProps) => {
|
||||||
const onUpdate =
|
const onUpdate =
|
||||||
(field: string) =>
|
(field: string) =>
|
||||||
|
@ -3,14 +3,13 @@ import { Tooltip } from '@material-ui/core';
|
|||||||
import { getFeatureTypeIcons } from '../../../../utils/get-feature-type-icons';
|
import { getFeatureTypeIcons } from '../../../../utils/get-feature-type-icons';
|
||||||
import useFeatureTypes from '../../../../hooks/api/getters/useFeatureTypes/useFeatureTypes';
|
import useFeatureTypes from '../../../../hooks/api/getters/useFeatureTypes/useFeatureTypes';
|
||||||
|
|
||||||
|
|
||||||
interface FeatureTypeProps {
|
interface FeatureTypeProps {
|
||||||
type: string;
|
type: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const FeatureStatus = ({ type }: FeatureTypeProps) => {
|
const FeatureStatus = ({ type }: FeatureTypeProps) => {
|
||||||
const styles = useStyles();
|
const styles = useStyles();
|
||||||
const { featureTypes } = useFeatureTypes()
|
const { featureTypes } = useFeatureTypes();
|
||||||
const IconComponent = getFeatureTypeIcons(type);
|
const IconComponent = getFeatureTypeIcons(type);
|
||||||
|
|
||||||
const typeName = featureTypes.filter(t => t.id === type).map(t => t.name);
|
const typeName = featureTypes.filter(t => t.id === type).map(t => t.name);
|
||||||
@ -19,10 +18,7 @@ const FeatureStatus = ({ type }: FeatureTypeProps) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Tooltip arrow placement="right" title={title}>
|
<Tooltip arrow placement="right" title={title}>
|
||||||
<IconComponent
|
<IconComponent data-loading className={styles.icon} />
|
||||||
data-loading
|
|
||||||
className={styles.icon}
|
|
||||||
/>
|
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -8,10 +8,10 @@ interface IUseDeleteVariantMarkupProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const useDeleteVariantMarkup = ({
|
const useDeleteVariantMarkup = ({
|
||||||
show,
|
show,
|
||||||
onClick,
|
onClick,
|
||||||
onClose,
|
onClose,
|
||||||
}: IUseDeleteVariantMarkupProps) => {
|
}: IUseDeleteVariantMarkupProps) => {
|
||||||
return (
|
return (
|
||||||
<Dialogue
|
<Dialogue
|
||||||
title="Are you sure you want to delete this variant?"
|
title="Are you sure you want to delete this variant?"
|
||||||
|
@ -45,6 +45,6 @@ export const useStyles = makeStyles(theme => ({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
featureId: {
|
featureId: {
|
||||||
wordBreak: 'break-all'
|
wordBreak: 'break-all',
|
||||||
}
|
},
|
||||||
}));
|
}));
|
||||||
|
@ -17,26 +17,34 @@ const EventCard = ({ entry, timeFormatted }) => {
|
|||||||
<dd>{entry.type}</dd>
|
<dd>{entry.type}</dd>
|
||||||
<dt className={styles.eventLogHeader}>Changed by: </dt>
|
<dt className={styles.eventLogHeader}>Changed by: </dt>
|
||||||
<dd title={entry.createdBy}>{entry.createdBy}</dd>
|
<dd title={entry.createdBy}>{entry.createdBy}</dd>
|
||||||
<ConditionallyRender condition={entry.project} show={
|
<ConditionallyRender
|
||||||
<>
|
condition={entry.project}
|
||||||
<dt className={styles.eventLogHeader}>Project: </dt>
|
show={
|
||||||
<dd>{entry.project}</dd>
|
<>
|
||||||
</>
|
<dt className={styles.eventLogHeader}>Project: </dt>
|
||||||
} />
|
<dd>{entry.project}</dd>
|
||||||
<ConditionallyRender condition={entry.featureName} show={
|
</>
|
||||||
<>
|
}
|
||||||
<dt className={styles.eventLogHeader}>Feature: </dt>
|
/>
|
||||||
<dd>{entry.featureName}</dd>
|
<ConditionallyRender
|
||||||
</>
|
condition={entry.featureName}
|
||||||
} />
|
show={
|
||||||
|
<>
|
||||||
|
<dt className={styles.eventLogHeader}>Feature: </dt>
|
||||||
|
<dd>{entry.featureName}</dd>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
/>
|
||||||
</dl>
|
</dl>
|
||||||
<ConditionallyRender condition={entry.data || entry.preData} show={
|
<ConditionallyRender
|
||||||
|
condition={entry.data || entry.preData}
|
||||||
|
show={
|
||||||
<>
|
<>
|
||||||
<strong>Change</strong>
|
<strong>Change</strong>
|
||||||
<EventDiff entry={entry} />
|
<EventDiff entry={entry} />
|
||||||
</>
|
</>
|
||||||
} />
|
}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -20,7 +20,10 @@ const EventDiff = ({ entry }) => {
|
|||||||
N: styles.positive, // added
|
N: styles.positive, // added
|
||||||
};
|
};
|
||||||
|
|
||||||
const diffs = entry.data && entry.preData ? diff(entry.preData, entry.data) : undefined;
|
const diffs =
|
||||||
|
entry.data && entry.preData
|
||||||
|
? diff(entry.preData, entry.data)
|
||||||
|
: undefined;
|
||||||
|
|
||||||
const buildItemDiff = (diff, key) => {
|
const buildItemDiff = (diff, key) => {
|
||||||
let change;
|
let change;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import EventLog from './EventLog';
|
import EventLog from './EventLog';
|
||||||
import { useEventSettings } from "../../../hooks/useEventSettings";
|
import { useEventSettings } from '../../../hooks/useEventSettings';
|
||||||
import { useLocationSettings } from "../../../hooks/useLocationSettings";
|
import { useLocationSettings } from '../../../hooks/useLocationSettings';
|
||||||
|
|
||||||
interface IEventLogContainerProps {
|
interface IEventLogContainerProps {
|
||||||
title: string;
|
title: string;
|
||||||
|
@ -11,7 +11,12 @@ export const Footer = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<footer className={styles.footer}>
|
<footer className={styles.footer}>
|
||||||
<Grid container justifyContent="center" spacing={10} style={{marginBottom: 0}}>
|
<Grid
|
||||||
|
container
|
||||||
|
justifyContent="center"
|
||||||
|
spacing={10}
|
||||||
|
style={{ marginBottom: 0 }}
|
||||||
|
>
|
||||||
<Grid item md={4} xs={12}>
|
<Grid item md={4} xs={12}>
|
||||||
<ApiDetails uiConfig={uiConfig} />
|
<ApiDetails uiConfig={uiConfig} />
|
||||||
</Grid>
|
</Grid>
|
||||||
|
@ -27,7 +27,7 @@ export const useStyles = makeStyles(theme => ({
|
|||||||
display: '-webkit-box',
|
display: '-webkit-box',
|
||||||
boxOrient: 'vertical',
|
boxOrient: 'vertical',
|
||||||
textOverflow: 'ellipsis',
|
textOverflow: 'ellipsis',
|
||||||
overflow: 'hidden'
|
overflow: 'hidden',
|
||||||
},
|
},
|
||||||
|
|
||||||
projectIcon: {
|
projectIcon: {
|
||||||
|
@ -9,7 +9,7 @@ export const useStyles = makeStyles(theme => ({
|
|||||||
},
|
},
|
||||||
'&:hover': {
|
'&:hover': {
|
||||||
backgroundColor: theme.palette.grey[200],
|
backgroundColor: theme.palette.grey[200],
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
deprecated: {
|
deprecated: {
|
||||||
'& a': {
|
'& a': {
|
||||||
|
@ -74,10 +74,7 @@ const EditTagType = () => {
|
|||||||
mode="Edit"
|
mode="Edit"
|
||||||
clearErrors={clearErrors}
|
clearErrors={clearErrors}
|
||||||
>
|
>
|
||||||
<PermissionButton
|
<PermissionButton permission={UPDATE_TAG_TYPE} type="submit">
|
||||||
permission={UPDATE_TAG_TYPE}
|
|
||||||
type="submit"
|
|
||||||
>
|
|
||||||
Edit type
|
Edit type
|
||||||
</PermissionButton>
|
</PermissionButton>
|
||||||
</TagForm>
|
</TagForm>
|
||||||
|
@ -41,7 +41,7 @@ const useTagTypeForm = (initialTagName = '', initialTagDesc = '') => {
|
|||||||
} catch (err: unknown) {
|
} catch (err: unknown) {
|
||||||
setErrors(prev => ({
|
setErrors(prev => ({
|
||||||
...prev,
|
...prev,
|
||||||
name: formatUnknownError(err)
|
name: formatUnknownError(err),
|
||||||
}));
|
}));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -7,13 +7,15 @@ import KeyboardArrowDownIcon from '@material-ui/icons/KeyboardArrowDown';
|
|||||||
import { useStyles } from './UserProfile.styles';
|
import { useStyles } from './UserProfile.styles';
|
||||||
import { useCommonStyles } from '../../../common.styles';
|
import { useCommonStyles } from '../../../common.styles';
|
||||||
import UserProfileContent from './UserProfileContent/UserProfileContent';
|
import UserProfileContent from './UserProfileContent/UserProfileContent';
|
||||||
import { IUser } from "../../../interfaces/user";
|
import { IUser } from '../../../interfaces/user';
|
||||||
import { ILocationSettings } from "../../../hooks/useLocationSettings";
|
import { ILocationSettings } from '../../../hooks/useLocationSettings';
|
||||||
|
|
||||||
interface IUserProfileProps {
|
interface IUserProfileProps {
|
||||||
profile: IUser
|
profile: IUser;
|
||||||
locationSettings: ILocationSettings
|
locationSettings: ILocationSettings;
|
||||||
setLocationSettings: React.Dispatch<React.SetStateAction<ILocationSettings>>
|
setLocationSettings: React.Dispatch<
|
||||||
|
React.SetStateAction<ILocationSettings>
|
||||||
|
>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const UserProfile = ({
|
const UserProfile = ({
|
||||||
|
@ -98,14 +98,19 @@ const UserProfileContent = ({
|
|||||||
condition={!editingProfile}
|
condition={!editingProfile}
|
||||||
show={
|
show={
|
||||||
<>
|
<>
|
||||||
<ConditionallyRender condition={!uiConfig.disablePasswordAuth} show={
|
<ConditionallyRender
|
||||||
<Button
|
condition={!uiConfig.disablePasswordAuth}
|
||||||
variant="contained"
|
show={
|
||||||
onClick={() => setEditingProfile(true)}
|
<Button
|
||||||
>
|
variant="contained"
|
||||||
Update password
|
onClick={() =>
|
||||||
</Button>
|
setEditingProfile(true)
|
||||||
} />
|
}
|
||||||
|
>
|
||||||
|
Update password
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
|
/>
|
||||||
<div className={commonStyles.divider} />
|
<div className={commonStyles.divider} />
|
||||||
<div className={legacyStyles.showUserSettings}>
|
<div className={legacyStyles.showUserSettings}>
|
||||||
<FormControl
|
<FormControl
|
||||||
|
@ -1 +1,2 @@
|
|||||||
export const ENVIRONMENT_STRATEGY_ERROR = 'You can not enable the environment before it has strategies';
|
export const ENVIRONMENT_STRATEGY_ERROR =
|
||||||
|
'You can not enable the environment before it has strategies';
|
||||||
|
@ -27,7 +27,10 @@ const useApiTokensApi = () => {
|
|||||||
|
|
||||||
const createToken = async (newToken: IApiTokenCreate) => {
|
const createToken = async (newToken: IApiTokenCreate) => {
|
||||||
const path = `api/admin/api-tokens`;
|
const path = `api/admin/api-tokens`;
|
||||||
const req = createRequest(path, { method: 'POST', body: JSON.stringify(newToken) });
|
const req = createRequest(path, {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify(newToken),
|
||||||
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await makeRequest(req.caller, req.id);
|
const res = await makeRequest(req.caller, req.id);
|
||||||
|
@ -7,12 +7,12 @@ export interface ISimpleAuthSettings {
|
|||||||
|
|
||||||
export const handleBadRequest = async (
|
export const handleBadRequest = async (
|
||||||
setErrors?: Dispatch<SetStateAction<{}>>,
|
setErrors?: Dispatch<SetStateAction<{}>>,
|
||||||
res?: Response,
|
res?: Response
|
||||||
) => {
|
) => {
|
||||||
if (!setErrors) return;
|
if (!setErrors) return;
|
||||||
if (res) {
|
if (res) {
|
||||||
const data = await res.json();
|
const data = await res.json();
|
||||||
setErrors({message: data.message});
|
setErrors({ message: data.message });
|
||||||
throw new Error(data.message);
|
throw new Error(data.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ const useContextsApi = () => {
|
|||||||
updateContext,
|
updateContext,
|
||||||
removeContext,
|
removeContext,
|
||||||
errors,
|
errors,
|
||||||
loading
|
loading,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ const useTagTypesApi = () => {
|
|||||||
updateTagType,
|
updateTagType,
|
||||||
deleteTagType,
|
deleteTagType,
|
||||||
errors,
|
errors,
|
||||||
loading
|
loading,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -30,7 +30,12 @@ const useContext = (name: string, options: SWRConfiguration = {}) => {
|
|||||||
}, [data, error]);
|
}, [data, error]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
context: data || { name: '', description: '', legalValues: [], stickiness: false },
|
context: data || {
|
||||||
|
name: '',
|
||||||
|
description: '',
|
||||||
|
legalValues: [],
|
||||||
|
stickiness: false,
|
||||||
|
},
|
||||||
error,
|
error,
|
||||||
loading,
|
loading,
|
||||||
refetch,
|
refetch,
|
||||||
|
@ -6,5 +6,5 @@ export const defaultEnvironment: IEnvironment = {
|
|||||||
createdAt: '',
|
createdAt: '',
|
||||||
sortOrder: 0,
|
sortOrder: 0,
|
||||||
enabled: false,
|
enabled: false,
|
||||||
protected: false
|
protected: false,
|
||||||
};
|
};
|
@ -6,14 +6,9 @@ import { IEnvironment } from '../../../../interfaces/environments';
|
|||||||
import handleErrorResponses from '../httpErrorResponseHandler';
|
import handleErrorResponses from '../httpErrorResponseHandler';
|
||||||
import { defaultEnvironment } from './defaultEnvironment';
|
import { defaultEnvironment } from './defaultEnvironment';
|
||||||
|
|
||||||
const useEnvironment = (
|
const useEnvironment = (id: string, options: SWRConfiguration = {}) => {
|
||||||
id: string,
|
|
||||||
options: SWRConfiguration = {}
|
|
||||||
) => {
|
|
||||||
const fetcher = async () => {
|
const fetcher = async () => {
|
||||||
const path = formatApiPath(
|
const path = formatApiPath(`api/admin/environments/${id}`);
|
||||||
`api/admin/environments/${id}`
|
|
||||||
);
|
|
||||||
return fetch(path, {
|
return fetch(path, {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
})
|
})
|
||||||
|
@ -6,7 +6,9 @@ export const getProjectFetcher = (id: string) => {
|
|||||||
const path = formatApiPath(`api/admin/projects/${id}`);
|
const path = formatApiPath(`api/admin/projects/${id}`);
|
||||||
return fetch(path, {
|
return fetch(path, {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
}).then(handleErrorResponses('Project overview')).then(res => res.json());
|
})
|
||||||
|
.then(handleErrorResponses('Project overview'))
|
||||||
|
.then(res => res.json());
|
||||||
};
|
};
|
||||||
|
|
||||||
const KEY = `api/admin/projects/${id}`;
|
const KEY = `api/admin/projects/${id}`;
|
||||||
|
@ -13,7 +13,11 @@ const useUserInfo = (id: string, options: SWRConfiguration = {}) => {
|
|||||||
.then(res => res.json());
|
.then(res => res.json());
|
||||||
};
|
};
|
||||||
|
|
||||||
const { data, error } = useSWR(`api/admin/user-admin/${id}`, fetcher, options);
|
const { data, error } = useSWR(
|
||||||
|
`api/admin/user-admin/${id}`,
|
||||||
|
fetcher,
|
||||||
|
options
|
||||||
|
);
|
||||||
const [loading, setLoading] = useState(!error && !data);
|
const [loading, setLoading] = useState(!error && !data);
|
||||||
|
|
||||||
const refetch = () => {
|
const refetch = () => {
|
||||||
|
@ -11,7 +11,7 @@ export interface IFeaturesFilter {
|
|||||||
export interface IFeaturesSortOutput {
|
export interface IFeaturesSortOutput {
|
||||||
filtered: IFeatureToggle[];
|
filtered: IFeatureToggle[];
|
||||||
filter: IFeaturesFilter;
|
filter: IFeaturesFilter;
|
||||||
setFilter: React.Dispatch<React.SetStateAction<IFeaturesFilter>>
|
setFilter: React.Dispatch<React.SetStateAction<IFeaturesFilter>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store the features filter state globally, and in localStorage.
|
// Store the features filter state globally, and in localStorage.
|
||||||
|
@ -19,7 +19,7 @@ interface IFeaturesSort {
|
|||||||
export interface IFeaturesSortOutput {
|
export interface IFeaturesSortOutput {
|
||||||
sort: IFeaturesSort;
|
sort: IFeaturesSort;
|
||||||
sorted: IFeatureToggle[];
|
sorted: IFeatureToggle[];
|
||||||
setSort: React.Dispatch<React.SetStateAction<IFeaturesSort>>
|
setSort: React.Dispatch<React.SetStateAction<IFeaturesSort>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IFeaturesFilterSortOption {
|
export interface IFeaturesFilterSortOption {
|
||||||
|
@ -71,6 +71,6 @@ export interface IFeatureEnvironmentMetrics {
|
|||||||
export interface IFeatureMetrics {
|
export interface IFeatureMetrics {
|
||||||
version: number;
|
version: number;
|
||||||
maturity: string;
|
maturity: string;
|
||||||
lastHourUsage: IFeatureEnvironmentMetrics[],
|
lastHourUsage: IFeatureEnvironmentMetrics[];
|
||||||
seenApplications: string[]
|
seenApplications: string[];
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ export interface IUiConfig {
|
|||||||
versionInfo: IVersionInfo;
|
versionInfo: IVersionInfo;
|
||||||
links: ILinks[];
|
links: ILinks[];
|
||||||
disablePasswordAuth?: boolean;
|
disablePasswordAuth?: boolean;
|
||||||
toast?: IProclamationToast
|
toast?: IProclamationToast;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IProclamationToast {
|
export interface IProclamationToast {
|
||||||
|
@ -2,26 +2,26 @@ const { createProxyMiddleware } = require('http-proxy-middleware');
|
|||||||
|
|
||||||
const API_URL = process.env.UNLEASH_API || 'http://localhost:4242';
|
const API_URL = process.env.UNLEASH_API || 'http://localhost:4242';
|
||||||
|
|
||||||
module.exports = function(app) {
|
module.exports = function (app) {
|
||||||
app.use(
|
app.use(
|
||||||
'/api',
|
'/api',
|
||||||
createProxyMiddleware({
|
createProxyMiddleware({
|
||||||
target: API_URL,
|
target: API_URL,
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
}),
|
})
|
||||||
);
|
);
|
||||||
app.use(
|
app.use(
|
||||||
'/auth',
|
'/auth',
|
||||||
createProxyMiddleware({
|
createProxyMiddleware({
|
||||||
target: API_URL,
|
target: API_URL,
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
}),
|
})
|
||||||
);
|
);
|
||||||
app.use(
|
app.use(
|
||||||
'/logout',
|
'/logout',
|
||||||
createProxyMiddleware({
|
createProxyMiddleware({
|
||||||
target: API_URL,
|
target: API_URL,
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
}),
|
})
|
||||||
);
|
);
|
||||||
};
|
};
|
@ -1,3 +1,3 @@
|
|||||||
import '@testing-library/jest-dom'
|
import '@testing-library/jest-dom';
|
||||||
|
|
||||||
process.env.TZ = 'UTC';
|
process.env.TZ = 'UTC';
|
||||||
|
Loading…
Reference in New Issue
Block a user