@openmrs/esm-patient-flags-app 11.3.1-pre.9533 → 11.3.1-pre.9541
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +10 -10
- package/dist/4300.js +1 -1
- package/dist/4480.js +1 -0
- package/dist/4480.js.map +1 -0
- package/dist/597.js +1 -0
- package/dist/597.js.map +1 -0
- package/dist/7231.js +1 -0
- package/dist/7231.js.map +1 -0
- package/dist/8519.js +1 -1
- package/dist/8519.js.map +1 -1
- package/dist/8572.js +1 -0
- package/dist/8572.js.map +1 -0
- package/dist/9388.js +1 -0
- package/dist/9388.js.map +1 -0
- package/dist/main.js +1 -1
- package/dist/main.js.map +1 -1
- package/dist/openmrs-esm-patient-flags-app.js +1 -1
- package/dist/openmrs-esm-patient-flags-app.js.buildmanifest.json +129 -105
- package/dist/routes.json +1 -1
- package/package.json +2 -2
- package/src/config-schema.ts +13 -2
- package/src/flags/flags-list-extension/flags-list.extension.tsx +12 -0
- package/src/flags/flags-list.component.tsx +68 -0
- package/src/flags/flags-list.scss +43 -147
- package/src/flags/flags-list.test.tsx +50 -68
- package/src/flags/flags-risk-count-extension/extension-config-schema.ts +17 -0
- package/src/flags/flags-risk-count-extension/flags-risk-count.extension.tsx +84 -0
- package/src/flags/{flags-highlight-bar.scss → flags-risk-count-extension/flags-risk-count.scss} +14 -5
- package/src/flags/flags-risk-count-extension/flags-risk-count.test.tsx +99 -0
- package/src/flags/flags-workspace/flags-workspace.scss +167 -0
- package/src/flags/flags-workspace/flags-workspace.test.tsx +97 -0
- package/src/flags/flags-workspace/flags.workspace.tsx +255 -0
- package/src/flags/hooks/usePatientFlags.ts +19 -11
- package/src/index.ts +12 -7
- package/src/routes.json +18 -9
- package/translations/en.json +7 -15
- package/dist/1837.js +0 -1
- package/dist/1837.js.map +0 -1
- package/dist/5628.js +0 -1
- package/dist/5628.js.map +0 -1
- package/dist/6138.js +0 -1
- package/dist/6138.js.map +0 -1
- package/dist/6173.js +0 -1
- package/dist/6173.js.map +0 -1
- package/src/flags/flags-highlight-bar.component.tsx +0 -81
- package/src/flags/flags-highlight-bar.test.tsx +0 -85
- package/src/flags/flags.component.tsx +0 -82
- package/src/flags/flags.scss +0 -71
- package/src/flags/flags.test.tsx +0 -49
- package/src/flags/patient-flags.workspace.tsx +0 -234
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import React, { useCallback } from 'react';
|
|
2
|
-
import { useTranslation } from 'react-i18next';
|
|
3
|
-
import { Button, Tag, Toggletip, ToggletipButton, ToggletipContent } from '@carbon/react';
|
|
4
|
-
import { CloseIcon, EditIcon, launchWorkspace2 } from '@openmrs/esm-framework';
|
|
5
|
-
import { usePatientFlags } from './hooks/usePatientFlags';
|
|
6
|
-
import styles from './flags.scss';
|
|
7
|
-
|
|
8
|
-
interface FlagsProps {
|
|
9
|
-
patientUuid: string;
|
|
10
|
-
onHandleCloseHighlightBar: () => void;
|
|
11
|
-
showHighlightBar: boolean;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
type FlagWithPriority = ReturnType<typeof usePatientFlags>['flags'][0];
|
|
15
|
-
|
|
16
|
-
const Flags: React.FC<FlagsProps> = ({ patientUuid, onHandleCloseHighlightBar, showHighlightBar }) => {
|
|
17
|
-
const { t } = useTranslation();
|
|
18
|
-
const { flags, isLoading, error } = usePatientFlags(patientUuid);
|
|
19
|
-
const filteredFlags = flags.filter((flag: FlagWithPriority) => !flag.voided);
|
|
20
|
-
|
|
21
|
-
const handleClickEditFlags = useCallback(() => launchWorkspace2('patient-flags-workspace'), []);
|
|
22
|
-
|
|
23
|
-
const renderFlag = (flag: FlagWithPriority) => {
|
|
24
|
-
const hasPriority = flag.flagWithPriority?.priority?.name;
|
|
25
|
-
const priorityName = hasPriority ? hasPriority.toLowerCase() : '';
|
|
26
|
-
|
|
27
|
-
const isInfoFlag = priorityName === 'info';
|
|
28
|
-
const isRiskFlag = priorityName === 'risk';
|
|
29
|
-
|
|
30
|
-
return (
|
|
31
|
-
<Toggletip key={flag.uuid} align="bottom-start">
|
|
32
|
-
<ToggletipButton label={isRiskFlag ? t('riskFlag', 'Risk flag') : t('infoFlag', 'Info flag')}>
|
|
33
|
-
<Tag
|
|
34
|
-
className={isInfoFlag ? styles.infoFlagTag : isRiskFlag ? styles.flagTag : undefined}
|
|
35
|
-
type={isRiskFlag ? 'high-contrast' : undefined}
|
|
36
|
-
>
|
|
37
|
-
{isRiskFlag && <span className={styles.flagIcon}>🚩</span>}
|
|
38
|
-
{flag.flag.display}
|
|
39
|
-
</Tag>
|
|
40
|
-
</ToggletipButton>
|
|
41
|
-
<ToggletipContent>
|
|
42
|
-
<div className={styles.content}>
|
|
43
|
-
<p className={styles.title}>{flag.flag.display}</p>
|
|
44
|
-
<p className={styles.message}>{flag.message}</p>
|
|
45
|
-
</div>
|
|
46
|
-
</ToggletipContent>
|
|
47
|
-
</Toggletip>
|
|
48
|
-
);
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
if (!isLoading && !error) {
|
|
52
|
-
return (
|
|
53
|
-
<div className={styles.container}>
|
|
54
|
-
<div className={styles.flagsContainer}>{filteredFlags.map(renderFlag)}</div>
|
|
55
|
-
{filteredFlags.length > 0 ? (
|
|
56
|
-
<Button
|
|
57
|
-
className={styles.actionButton}
|
|
58
|
-
kind="ghost"
|
|
59
|
-
renderIcon={EditIcon}
|
|
60
|
-
onClick={handleClickEditFlags}
|
|
61
|
-
iconDescription={t('editFlags', 'Edit flags')}
|
|
62
|
-
>
|
|
63
|
-
{t('edit', 'Edit')}
|
|
64
|
-
</Button>
|
|
65
|
-
) : null}
|
|
66
|
-
{showHighlightBar ? (
|
|
67
|
-
<Button
|
|
68
|
-
className={styles.actionButton}
|
|
69
|
-
hasIconOnly
|
|
70
|
-
iconDescription={t('closeFlagsBar', 'Close flags bar')}
|
|
71
|
-
kind="ghost"
|
|
72
|
-
renderIcon={CloseIcon}
|
|
73
|
-
onClick={onHandleCloseHighlightBar}
|
|
74
|
-
/>
|
|
75
|
-
) : null}
|
|
76
|
-
</div>
|
|
77
|
-
);
|
|
78
|
-
}
|
|
79
|
-
return null;
|
|
80
|
-
};
|
|
81
|
-
|
|
82
|
-
export default Flags;
|
package/src/flags/flags.scss
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
@use '@carbon/colors';
|
|
2
|
-
@use '@carbon/layout';
|
|
3
|
-
@use '@carbon/type';
|
|
4
|
-
|
|
5
|
-
.container {
|
|
6
|
-
display: flex;
|
|
7
|
-
flex-flow: row wrap;
|
|
8
|
-
align-items: center;
|
|
9
|
-
justify-content: flex-end;
|
|
10
|
-
gap: layout.$spacing-03;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
.flagsContainer {
|
|
14
|
-
display: flex;
|
|
15
|
-
flex-flow: row wrap;
|
|
16
|
-
column-gap: layout.$spacing-02;
|
|
17
|
-
row-gap: layout.$spacing-03;
|
|
18
|
-
align-items: center;
|
|
19
|
-
flex: 1;
|
|
20
|
-
margin-right: auto;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
.actionButton {
|
|
24
|
-
max-height: layout.$spacing-08;
|
|
25
|
-
flex-shrink: 0;
|
|
26
|
-
align-self: center;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
.flagIcon {
|
|
30
|
-
margin-right: layout.$spacing-02;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
.flagTag {
|
|
34
|
-
padding: 0 layout.$spacing-03;
|
|
35
|
-
span {
|
|
36
|
-
display: flex;
|
|
37
|
-
align-items: center;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
.infoFlagTag {
|
|
42
|
-
padding: 0 layout.$spacing-03;
|
|
43
|
-
background-color: colors.$orange-20;
|
|
44
|
-
color: #934412;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
.highlightBarContainer {
|
|
48
|
-
display: flex;
|
|
49
|
-
align-items: center;
|
|
50
|
-
padding: layout.$spacing-03;
|
|
51
|
-
border-bottom: 1px solid colors.$gray-20;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
.tooltipPadding {
|
|
55
|
-
padding: layout.$spacing-02;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
.content {
|
|
59
|
-
p {
|
|
60
|
-
@include type.type-style('body-01');
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
.title {
|
|
64
|
-
@include type.type-style('heading-compact-01');
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
.message {
|
|
68
|
-
margin-top: layout.$spacing-03;
|
|
69
|
-
color: colors.$gray-30;
|
|
70
|
-
}
|
|
71
|
-
}
|
package/src/flags/flags.test.tsx
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import userEvent from '@testing-library/user-event';
|
|
3
|
-
import { screen, render } from '@testing-library/react';
|
|
4
|
-
import { launchWorkspace2 } from '@openmrs/esm-framework';
|
|
5
|
-
import { mockPatient } from 'tools';
|
|
6
|
-
import { mockPatientFlags } from '__mocks__';
|
|
7
|
-
import { usePatientFlags } from './hooks/usePatientFlags';
|
|
8
|
-
import Flags from './flags.component';
|
|
9
|
-
|
|
10
|
-
type FlagWithPriority = ReturnType<typeof usePatientFlags>['flags'][0];
|
|
11
|
-
|
|
12
|
-
const mockUsePatientFlags = jest.mocked(usePatientFlags);
|
|
13
|
-
const mockLaunchWorkspace = jest.mocked(launchWorkspace2);
|
|
14
|
-
|
|
15
|
-
jest.mock('./hooks/usePatientFlags', () => {
|
|
16
|
-
const originalModule = jest.requireActual('./hooks/usePatientFlags');
|
|
17
|
-
|
|
18
|
-
return {
|
|
19
|
-
...originalModule,
|
|
20
|
-
usePatientFlags: jest.fn(),
|
|
21
|
-
};
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
it('renders flags in the patient flags slot', async () => {
|
|
25
|
-
const user = userEvent.setup();
|
|
26
|
-
|
|
27
|
-
mockUsePatientFlags.mockReturnValue({
|
|
28
|
-
error: null,
|
|
29
|
-
flags: mockPatientFlags as FlagWithPriority[],
|
|
30
|
-
isLoading: false,
|
|
31
|
-
isValidating: false,
|
|
32
|
-
mutate: jest.fn(),
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
render(<Flags patientUuid={mockPatient.id} onHandleCloseHighlightBar={jest.fn()} showHighlightBar={false} />);
|
|
36
|
-
|
|
37
|
-
const flags = screen.getAllByRole('button', { name: /flag/i });
|
|
38
|
-
expect(flags).toHaveLength(3);
|
|
39
|
-
expect(screen.getByText(/patient needs to be followed up/i)).toBeInTheDocument();
|
|
40
|
-
expect(screen.getByText(/diagnosis for the patient is unknown/i)).toBeInTheDocument();
|
|
41
|
-
expect(screen.getByText(/patient has a future appointment scheduled/i)).toBeInTheDocument();
|
|
42
|
-
|
|
43
|
-
const editButton = screen.getByRole('button', { name: /edit/i });
|
|
44
|
-
expect(editButton).toBeInTheDocument();
|
|
45
|
-
|
|
46
|
-
await user.click(editButton);
|
|
47
|
-
|
|
48
|
-
expect(mockLaunchWorkspace).toHaveBeenCalledWith('patient-flags-workspace');
|
|
49
|
-
});
|
|
@@ -1,234 +0,0 @@
|
|
|
1
|
-
import React, { useMemo, useState } from 'react';
|
|
2
|
-
import { orderBy } from 'lodash-es';
|
|
3
|
-
import { useTranslation } from 'react-i18next';
|
|
4
|
-
import { Button, ButtonSet, Dropdown, Form, InlineLoading, Search, Tile, Toggle, Stack } from '@carbon/react';
|
|
5
|
-
import { type PatientWorkspace2DefinitionProps } from '@openmrs/esm-patient-common-lib';
|
|
6
|
-
import { useLayoutType, showSnackbar, parseDate, formatDate, ResponsiveWrapper } from '@openmrs/esm-framework';
|
|
7
|
-
import { usePatientFlags, enablePatientFlag, disablePatientFlag } from './hooks/usePatientFlags';
|
|
8
|
-
import { getFlagType } from './utils';
|
|
9
|
-
import styles from './flags-list.scss';
|
|
10
|
-
|
|
11
|
-
type SortKey = 'alpha' | 'active' | 'retired';
|
|
12
|
-
|
|
13
|
-
const FlagsList: React.FC<PatientWorkspace2DefinitionProps<{}, {}>> = ({
|
|
14
|
-
closeWorkspace,
|
|
15
|
-
groupProps: { patientUuid },
|
|
16
|
-
}) => {
|
|
17
|
-
const { t } = useTranslation();
|
|
18
|
-
const { flags, isLoading, error, mutate } = usePatientFlags(patientUuid);
|
|
19
|
-
const isTablet = useLayoutType() === 'tablet';
|
|
20
|
-
const [isEnabling, setIsEnabling] = useState(false);
|
|
21
|
-
const [isDisabling, setIsDisabling] = useState(false);
|
|
22
|
-
const [searchTerm, setSearchTerm] = useState('');
|
|
23
|
-
const [sortBy, setSortBy] = useState<SortKey>('alpha');
|
|
24
|
-
|
|
25
|
-
const sortItems = useMemo(
|
|
26
|
-
() => [
|
|
27
|
-
{ id: 'alpha' as const, label: t('alphabetically', 'A - Z') },
|
|
28
|
-
{ id: 'active' as const, label: t('activeFirst', 'Active first') },
|
|
29
|
-
{ id: 'retired' as const, label: t('retiredFirst', 'Retired first') },
|
|
30
|
-
],
|
|
31
|
-
[t],
|
|
32
|
-
);
|
|
33
|
-
|
|
34
|
-
const sortedRows = useMemo(() => {
|
|
35
|
-
if (!sortBy) {
|
|
36
|
-
return flags;
|
|
37
|
-
}
|
|
38
|
-
if (sortBy === 'active') {
|
|
39
|
-
return orderBy(flags, [(item) => Number(item.voided)], ['asc']);
|
|
40
|
-
}
|
|
41
|
-
if (sortBy === 'retired') {
|
|
42
|
-
return orderBy(flags, [(item) => Number(item.voided)], ['desc']);
|
|
43
|
-
}
|
|
44
|
-
return orderBy(flags, [(f) => f.flag.display], ['asc']);
|
|
45
|
-
}, [sortBy, flags]);
|
|
46
|
-
|
|
47
|
-
const searchResults = useMemo(() => {
|
|
48
|
-
const query = searchTerm.trim().toLowerCase();
|
|
49
|
-
if (query) {
|
|
50
|
-
return sortedRows.filter((f) => f.flag.display.toLowerCase().includes(query));
|
|
51
|
-
}
|
|
52
|
-
return sortedRows;
|
|
53
|
-
}, [searchTerm, sortedRows]);
|
|
54
|
-
|
|
55
|
-
const handleSortByChange = ({ selectedItem }) => setSortBy(selectedItem?.id as SortKey);
|
|
56
|
-
|
|
57
|
-
const handleEnableFlag = async (flagUuid) => {
|
|
58
|
-
setIsEnabling(true);
|
|
59
|
-
try {
|
|
60
|
-
const res = await enablePatientFlag(flagUuid);
|
|
61
|
-
if (!res.ok) {
|
|
62
|
-
throw new Error('Enable flag failed');
|
|
63
|
-
}
|
|
64
|
-
mutate();
|
|
65
|
-
showSnackbar({
|
|
66
|
-
isLowContrast: true,
|
|
67
|
-
kind: 'success',
|
|
68
|
-
subtitle: t('flagEnabledSuccessfully', 'Flag successfully enabled'),
|
|
69
|
-
title: t('enabledFlag', 'Enabled flag'),
|
|
70
|
-
});
|
|
71
|
-
} catch (e) {
|
|
72
|
-
showSnackbar({
|
|
73
|
-
isLowContrast: false,
|
|
74
|
-
kind: 'error',
|
|
75
|
-
subtitle: t('flagEnableError', 'Error enabling flag'),
|
|
76
|
-
title: t('enableFlagError', 'Enable flag error'),
|
|
77
|
-
});
|
|
78
|
-
} finally {
|
|
79
|
-
setIsEnabling(false);
|
|
80
|
-
}
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
const handleDisableFlag = async (flagUuid) => {
|
|
84
|
-
setIsDisabling(true);
|
|
85
|
-
try {
|
|
86
|
-
const res = await disablePatientFlag(flagUuid);
|
|
87
|
-
if (!res.ok) {
|
|
88
|
-
throw new Error('Disable flag failed');
|
|
89
|
-
}
|
|
90
|
-
mutate();
|
|
91
|
-
showSnackbar({
|
|
92
|
-
isLowContrast: true,
|
|
93
|
-
kind: 'success',
|
|
94
|
-
subtitle: t('flagDisabledSuccessfully', 'Flag successfully disabled'),
|
|
95
|
-
title: t('flagDisabled', 'Flag disabled'),
|
|
96
|
-
});
|
|
97
|
-
} catch (e) {
|
|
98
|
-
showSnackbar({
|
|
99
|
-
isLowContrast: false,
|
|
100
|
-
kind: 'error',
|
|
101
|
-
subtitle: t('flagDisableError', 'Error disabling the flag'),
|
|
102
|
-
title: t('disableFlagError', 'Disable flag error'),
|
|
103
|
-
});
|
|
104
|
-
} finally {
|
|
105
|
-
setIsDisabling(false);
|
|
106
|
-
}
|
|
107
|
-
};
|
|
108
|
-
|
|
109
|
-
if (isLoading) {
|
|
110
|
-
return <InlineLoading className={styles.loading} description={`${t('loading', 'Loading')} ...`} />;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
if (error) {
|
|
114
|
-
return <div>{error.message}</div>;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
return (
|
|
118
|
-
<Form className={styles.formWrapper}>
|
|
119
|
-
{/* The <div> below is required to maintain the page layout styling */}
|
|
120
|
-
<div>
|
|
121
|
-
<ResponsiveWrapper>
|
|
122
|
-
<Search
|
|
123
|
-
labelText={t('searchForAFlag', 'Search for a flag')}
|
|
124
|
-
placeholder={t('searchForAFlag', 'Search for a flag')}
|
|
125
|
-
value={searchTerm}
|
|
126
|
-
size={isTablet ? 'lg' : 'md'}
|
|
127
|
-
onChange={(e) => setSearchTerm(e.target.value)}
|
|
128
|
-
/>
|
|
129
|
-
</ResponsiveWrapper>
|
|
130
|
-
<Stack gap={4}>
|
|
131
|
-
<div className={styles.listWrapper}>
|
|
132
|
-
<div className={styles.flagsHeaderInfo}>
|
|
133
|
-
{searchResults.length > 0 ? (
|
|
134
|
-
<>
|
|
135
|
-
<span className={styles.resultsCount}>
|
|
136
|
-
{t('matchesForSearchTerm', '{{count}} flags', {
|
|
137
|
-
count: searchResults.length,
|
|
138
|
-
})}
|
|
139
|
-
</span>
|
|
140
|
-
<Dropdown
|
|
141
|
-
className={styles.sortDropdown}
|
|
142
|
-
id="sortBy"
|
|
143
|
-
label=""
|
|
144
|
-
type="inline"
|
|
145
|
-
items={sortItems}
|
|
146
|
-
itemToString={(item) => item?.label ?? ''}
|
|
147
|
-
selectedItem={sortItems.find((item) => item.id === sortBy)}
|
|
148
|
-
onChange={handleSortByChange}
|
|
149
|
-
titleText={t('sortBy', 'Sort by')}
|
|
150
|
-
/>
|
|
151
|
-
</>
|
|
152
|
-
) : null}
|
|
153
|
-
</div>
|
|
154
|
-
{searchResults.length > 0
|
|
155
|
-
? searchResults.map((result) => (
|
|
156
|
-
<div className={styles.flagTile} key={result.uuid}>
|
|
157
|
-
<div className={styles.flagHeader}>
|
|
158
|
-
<div className={styles.titleAndType}>
|
|
159
|
-
<div className={styles.flagTitle}>{result.flag.display}</div>·
|
|
160
|
-
<span className={styles.type}>
|
|
161
|
-
{(() => {
|
|
162
|
-
const typeLabel = getFlagType(result.tags);
|
|
163
|
-
return typeLabel ? t(typeLabel, typeLabel) : t('clinical', 'Clinical');
|
|
164
|
-
})()}
|
|
165
|
-
</span>
|
|
166
|
-
</div>
|
|
167
|
-
<Toggle
|
|
168
|
-
className={styles.flagToggle}
|
|
169
|
-
defaultToggled={!Boolean(result.voided)}
|
|
170
|
-
id={result.uuid}
|
|
171
|
-
labelA=""
|
|
172
|
-
labelB=""
|
|
173
|
-
onToggle={(on) => (on ? handleEnableFlag(result.uuid) : handleDisableFlag(result.uuid))}
|
|
174
|
-
size="sm"
|
|
175
|
-
/>
|
|
176
|
-
</div>
|
|
177
|
-
{result.voided ? null : (
|
|
178
|
-
<div className={styles.secondRow}>
|
|
179
|
-
<div className={styles.metadata}>
|
|
180
|
-
<span className={styles.label}>{t('assigned', 'Assigned')}</span>
|
|
181
|
-
<span className={styles.value}>
|
|
182
|
-
{formatDate(parseDate(result.auditInfo?.dateCreated), { time: false })}
|
|
183
|
-
</span>
|
|
184
|
-
</div>
|
|
185
|
-
</div>
|
|
186
|
-
)}
|
|
187
|
-
</div>
|
|
188
|
-
))
|
|
189
|
-
: null}
|
|
190
|
-
|
|
191
|
-
{searchResults.length === 0 ? (
|
|
192
|
-
<div className={styles.emptyState}>
|
|
193
|
-
<Tile className={styles.tile}>
|
|
194
|
-
<p className={styles.content}>{t('noFlagsFound', 'Sorry, no flags found matching your search')}</p>
|
|
195
|
-
<p className={styles.helper}>
|
|
196
|
-
<Button
|
|
197
|
-
kind="ghost"
|
|
198
|
-
size="sm"
|
|
199
|
-
onClick={() => {
|
|
200
|
-
setSearchTerm('');
|
|
201
|
-
}}
|
|
202
|
-
>
|
|
203
|
-
{t('clearSearch', 'Clear search')}
|
|
204
|
-
</Button>
|
|
205
|
-
</p>
|
|
206
|
-
</Tile>
|
|
207
|
-
</div>
|
|
208
|
-
) : null}
|
|
209
|
-
</div>
|
|
210
|
-
</Stack>
|
|
211
|
-
</div>
|
|
212
|
-
<ButtonSet className={isTablet ? styles.tabletButtonSet : styles.desktopButtonSet}>
|
|
213
|
-
<Button className={styles.button} kind="secondary" onClick={() => closeWorkspace()}>
|
|
214
|
-
{t('discard', 'Discard')}
|
|
215
|
-
</Button>
|
|
216
|
-
<Button
|
|
217
|
-
className={styles.button}
|
|
218
|
-
disabled={isEnabling || isDisabling}
|
|
219
|
-
kind="primary"
|
|
220
|
-
type="submit"
|
|
221
|
-
onClick={() => closeWorkspace({ discardUnsavedChanges: true })}
|
|
222
|
-
>
|
|
223
|
-
{(() => {
|
|
224
|
-
if (isEnabling) return t('enablingFlag', 'Enabling flag...');
|
|
225
|
-
if (isDisabling) return t('disablingFlag', 'Disabling flag...');
|
|
226
|
-
return t('saveAndClose', 'Save & close');
|
|
227
|
-
})()}
|
|
228
|
-
</Button>
|
|
229
|
-
</ButtonSet>
|
|
230
|
-
</Form>
|
|
231
|
-
);
|
|
232
|
-
};
|
|
233
|
-
|
|
234
|
-
export default FlagsList;
|