@openmrs/esm-metadataexport-app 4.4.1-pre.877 → 4.4.1-pre.879
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 +1 -1
- package/dist/2173.js +1 -1
- package/dist/2173.js.map +1 -1
- package/dist/5065.js +1 -1
- package/dist/5065.js.map +1 -1
- package/dist/5117.js +1 -1
- package/dist/5117.js.map +1 -1
- package/dist/7121.js +1 -1
- package/dist/7121.js.map +1 -1
- package/dist/9503.js +1 -1
- package/dist/9503.js.map +1 -1
- package/dist/openmrs-esm-metadataexport-app.js +1 -1
- package/dist/openmrs-esm-metadataexport-app.js.buildmanifest.json +16 -16
- package/dist/routes.json +1 -1
- package/package.json +1 -1
- package/src/admin-card-link.component.tsx +1 -1
- package/src/components/dashboard/home-dashboard.component.tsx +1 -2
- package/src/components/metadata-package-form/add-package-action-button/add-package-action-button.component.tsx +3 -3
- package/src/components/metadata-package-form/add-package-action-button/add-package-action-button.test.tsx +5 -5
- package/src/components/metadata-package-form/metadata-package-form-utils.ts +3 -7
- package/src/components/metadata-package-form/metadata-package-form.workspace.test.tsx +58 -30
- package/src/components/metadata-package-form/metadata-package-form.workspace.tsx +104 -106
- package/src/components/packages-table/packages-table.component.tsx +1 -1
- package/src/components/view-metadata-package/view-metadata-package-utils.ts +2 -5
- package/src/components/view-metadata-package/view-metadata-package.workspace.test.tsx +31 -6
- package/src/components/view-metadata-package/view-metadata-package.workspace.tsx +103 -93
- package/src/root.component.tsx +1 -1
- package/src/routes.json +25 -10
- package/translations/en.json +2 -1
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { launchWorkspace2 } from '@openmrs/esm-framework';
|
|
2
2
|
import { type ExportPackage } from '../../types/index';
|
|
3
3
|
|
|
4
4
|
export const launchViewMetadataPackageWorkspace = (exportPackage: ExportPackage) => {
|
|
5
|
-
|
|
6
|
-
workspaceTitle: exportPackage.name,
|
|
7
|
-
exportPackage,
|
|
8
|
-
});
|
|
5
|
+
launchWorkspace2('view-metadata-package-workspace', { exportPackage });
|
|
9
6
|
};
|
|
@@ -34,8 +34,7 @@ const mockUserHasAccess = vi.mocked(esmFramework.userHasAccess);
|
|
|
34
34
|
const sessionWithUser = () =>
|
|
35
35
|
({ user: { uuid: 'cc8507b8-7c9a-486b-85dc-b8f25ad1e4cc' } }) as unknown as esmFramework.Session;
|
|
36
36
|
const mockCloseWorkspace = vi.fn();
|
|
37
|
-
const
|
|
38
|
-
const mockPromptBeforeClosing = vi.fn();
|
|
37
|
+
const mockLaunchWorkspace2 = vi.mocked(esmFramework.launchWorkspace2);
|
|
39
38
|
|
|
40
39
|
const build = (overrides: Partial<ExportPackageBuild> = {}): ExportPackageBuild => ({
|
|
41
40
|
uuid: '23dbfd25-eec7-4f4e-b26c-d95324346ce3',
|
|
@@ -78,11 +77,15 @@ function mockBuilds(overrides: Partial<ReturnType<typeof usePackageBuilds>> = {}
|
|
|
78
77
|
function renderWorkspace(pkg: ExportPackage = exportPackage) {
|
|
79
78
|
render(
|
|
80
79
|
<ViewMetadataPackageWorkspace
|
|
81
|
-
|
|
80
|
+
workspaceProps={{ exportPackage: pkg }}
|
|
81
|
+
windowProps={null}
|
|
82
|
+
groupProps={null}
|
|
82
83
|
closeWorkspace={mockCloseWorkspace}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
84
|
+
launchChildWorkspace={vi.fn()}
|
|
85
|
+
workspaceName="view-metadata-package-workspace"
|
|
86
|
+
windowName="view-metadata-package-window"
|
|
87
|
+
isRootWorkspace
|
|
88
|
+
showActionMenu={false}
|
|
86
89
|
/>,
|
|
87
90
|
);
|
|
88
91
|
}
|
|
@@ -211,6 +214,28 @@ describe('ViewPackageWorkspace', () => {
|
|
|
211
214
|
);
|
|
212
215
|
});
|
|
213
216
|
|
|
217
|
+
it('replaces the workspace with the edit form when Edit is clicked', async () => {
|
|
218
|
+
const user = userEvent.setup();
|
|
219
|
+
mockCloseWorkspace.mockResolvedValue(true);
|
|
220
|
+
renderWorkspace();
|
|
221
|
+
|
|
222
|
+
await user.click(screen.getByRole('button', { name: 'Edit' }));
|
|
223
|
+
|
|
224
|
+
expect(mockCloseWorkspace).toHaveBeenCalled();
|
|
225
|
+
expect(mockLaunchWorkspace2).toHaveBeenCalledWith('metadata-package-form-workspace', { uuid: exportPackage.uuid });
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
it('does not launch the edit form if the workspace stays open', async () => {
|
|
229
|
+
const user = userEvent.setup();
|
|
230
|
+
mockCloseWorkspace.mockResolvedValue(false);
|
|
231
|
+
renderWorkspace();
|
|
232
|
+
|
|
233
|
+
await user.click(screen.getByRole('button', { name: 'Edit' }));
|
|
234
|
+
|
|
235
|
+
expect(mockCloseWorkspace).toHaveBeenCalled();
|
|
236
|
+
expect(mockLaunchWorkspace2).not.toHaveBeenCalled();
|
|
237
|
+
});
|
|
238
|
+
|
|
214
239
|
it('launches the delete confirmation modal wired to close the workspace on success', async () => {
|
|
215
240
|
const user = userEvent.setup();
|
|
216
241
|
renderWorkspace();
|
|
@@ -4,7 +4,6 @@ import { Download } from '@carbon/react/icons';
|
|
|
4
4
|
import { Button, InlineLoading, Link, Tag } from '@carbon/react';
|
|
5
5
|
import { useSWRConfig } from 'swr';
|
|
6
6
|
import {
|
|
7
|
-
type DefaultWorkspaceProps,
|
|
8
7
|
ErrorState,
|
|
9
8
|
OpenmrsFetchError,
|
|
10
9
|
formatDurationBetween,
|
|
@@ -14,6 +13,8 @@ import {
|
|
|
14
13
|
showSnackbar,
|
|
15
14
|
useSession,
|
|
16
15
|
userHasAccess,
|
|
16
|
+
Workspace2,
|
|
17
|
+
type Workspace2DefinitionProps,
|
|
17
18
|
} from '@openmrs/esm-framework';
|
|
18
19
|
import { formatDomainLabel } from '../../domain-lookups/domain-lookups.resource';
|
|
19
20
|
import { isPackagesCacheKey, triggerBuild, usePackageBuilds } from '../../packages/packages.resource';
|
|
@@ -21,7 +22,7 @@ import type { ExportBuildStatus, ExportPackage } from '../../types';
|
|
|
21
22
|
import styles from './view-metadata-package.workspace.scss';
|
|
22
23
|
import { launchPackageFormWorkspace } from '../metadata-package-form/metadata-package-form-utils';
|
|
23
24
|
|
|
24
|
-
interface ViewPackageWorkspaceProps
|
|
25
|
+
interface ViewPackageWorkspaceProps {
|
|
25
26
|
exportPackage: ExportPackage;
|
|
26
27
|
}
|
|
27
28
|
|
|
@@ -32,7 +33,11 @@ const statusTagType: Record<ExportBuildStatus, 'gray' | 'blue' | 'green' | 'red'
|
|
|
32
33
|
FAILED: 'red',
|
|
33
34
|
};
|
|
34
35
|
|
|
35
|
-
const ViewMetadataPackageWorkspace: React.FC<ViewPackageWorkspaceProps
|
|
36
|
+
const ViewMetadataPackageWorkspace: React.FC<Workspace2DefinitionProps<ViewPackageWorkspaceProps>> = ({
|
|
37
|
+
workspaceProps,
|
|
38
|
+
closeWorkspace,
|
|
39
|
+
}) => {
|
|
40
|
+
const { exportPackage } = workspaceProps;
|
|
36
41
|
const { t } = useTranslation();
|
|
37
42
|
const session = useSession();
|
|
38
43
|
const { mutate: globalMutate } = useSWRConfig();
|
|
@@ -100,108 +105,113 @@ const ViewMetadataPackageWorkspace: React.FC<ViewPackageWorkspaceProps> = ({ exp
|
|
|
100
105
|
return exportPackage.entries.map((entry) => formatDomainLabel(entry.domain)).join(', ');
|
|
101
106
|
}, [exportPackage.entries, t]);
|
|
102
107
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
108
|
+
// Replace this workspace with the edit form so it doesn't reappear with stale package details
|
|
109
|
+
const editPackage = useCallback(async () => {
|
|
110
|
+
if (await closeWorkspace()) {
|
|
111
|
+
launchPackageFormWorkspace(exportPackage.uuid);
|
|
112
|
+
}
|
|
113
|
+
}, [closeWorkspace, exportPackage.uuid]);
|
|
106
114
|
|
|
107
115
|
return (
|
|
108
|
-
<
|
|
109
|
-
<div className={styles.
|
|
110
|
-
{
|
|
111
|
-
|
|
112
|
-
<
|
|
113
|
-
className={styles.triggerButton}
|
|
114
|
-
kind="primary"
|
|
115
|
-
onClick={handleTriggerBuild}
|
|
116
|
-
disabled={isTriggeringBuild}
|
|
117
|
-
>
|
|
118
|
-
{isTriggeringBuild ? (
|
|
119
|
-
<InlineLoading description={t('triggeringBuild', 'Triggering build') + '…'} />
|
|
120
|
-
) : (
|
|
121
|
-
t('triggerNewBuild', 'Trigger new build')
|
|
122
|
-
)}
|
|
123
|
-
</Button>
|
|
124
|
-
<div className={styles.secondaryActions}>
|
|
125
|
-
<Button
|
|
126
|
-
className={styles.secondaryButton}
|
|
127
|
-
kind="secondary"
|
|
128
|
-
onClick={editPackage}
|
|
129
|
-
disabled={isTriggeringBuild}
|
|
130
|
-
>
|
|
131
|
-
{t('edit', 'Edit')}
|
|
132
|
-
</Button>
|
|
116
|
+
<Workspace2 title={exportPackage.name}>
|
|
117
|
+
<div className={styles.container}>
|
|
118
|
+
<div className={styles.body}>
|
|
119
|
+
{canManage && (
|
|
120
|
+
<section className={styles.actionRow}>
|
|
133
121
|
<Button
|
|
134
|
-
className={styles.
|
|
135
|
-
kind="
|
|
136
|
-
onClick={
|
|
122
|
+
className={styles.triggerButton}
|
|
123
|
+
kind="primary"
|
|
124
|
+
onClick={handleTriggerBuild}
|
|
137
125
|
disabled={isTriggeringBuild}
|
|
138
126
|
>
|
|
139
|
-
{
|
|
127
|
+
{isTriggeringBuild ? (
|
|
128
|
+
<InlineLoading description={t('triggeringBuild', 'Triggering build') + '…'} />
|
|
129
|
+
) : (
|
|
130
|
+
t('triggerNewBuild', 'Trigger new build')
|
|
131
|
+
)}
|
|
140
132
|
</Button>
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
133
|
+
<div className={styles.secondaryActions}>
|
|
134
|
+
<Button
|
|
135
|
+
className={styles.secondaryButton}
|
|
136
|
+
kind="secondary"
|
|
137
|
+
onClick={editPackage}
|
|
138
|
+
disabled={isTriggeringBuild}
|
|
139
|
+
>
|
|
140
|
+
{t('edit', 'Edit')}
|
|
141
|
+
</Button>
|
|
142
|
+
<Button
|
|
143
|
+
className={styles.secondaryButton}
|
|
144
|
+
kind="danger--tertiary"
|
|
145
|
+
onClick={launchDeleteModal}
|
|
146
|
+
disabled={isTriggeringBuild}
|
|
147
|
+
>
|
|
148
|
+
{t('delete', 'Delete')}
|
|
149
|
+
</Button>
|
|
150
|
+
</div>
|
|
151
|
+
</section>
|
|
152
|
+
)}
|
|
144
153
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
154
|
+
<section className={styles.section}>
|
|
155
|
+
<span className={styles.sectionLabel}>{t('details', 'Details')}</span>
|
|
156
|
+
<dl className={styles.detailList}>
|
|
157
|
+
<dt className={styles.detailKey}>{t('domains', 'Domains')}</dt>
|
|
158
|
+
<dd className={styles.detailValue}>{domainsLabel}</dd>
|
|
159
|
+
</dl>
|
|
160
|
+
</section>
|
|
152
161
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
<span className={styles.buildMeta}>
|
|
175
|
-
{build.dateStarted
|
|
176
|
-
? t('startedAgo', 'Started {{time}} ago', { time: formatDurationBetween(build.dateStarted) })
|
|
177
|
-
: t('notStarted', 'Not started')}
|
|
178
|
-
</span>
|
|
179
|
-
{build.dateCompleted && (
|
|
162
|
+
<section className={styles.section}>
|
|
163
|
+
<span className={styles.sectionLabel}>{t('builds', 'Builds')}</span>
|
|
164
|
+
{isLoading ? (
|
|
165
|
+
<InlineLoading description={t('loadingBuilds', 'Loading builds…')} />
|
|
166
|
+
) : error ? (
|
|
167
|
+
<ErrorState error={error} headerTitle={t('builds', 'Builds')} />
|
|
168
|
+
) : builds.length === 0 ? (
|
|
169
|
+
<p className={styles.emptyBuilds}>{t('noBuildsYet', 'No builds yet')}</p>
|
|
170
|
+
) : (
|
|
171
|
+
<ul className={styles.buildList}>
|
|
172
|
+
{builds.map((build) => (
|
|
173
|
+
<li key={build.uuid} className={styles.buildItem}>
|
|
174
|
+
<div className={styles.buildRow}>
|
|
175
|
+
<span className={styles.buildVersion}>
|
|
176
|
+
{t('buildVersion', 'Build {{version}}', { version: build.version })}
|
|
177
|
+
</span>
|
|
178
|
+
<Tag type={statusTagType[build.status]} size="sm">
|
|
179
|
+
{t(build.status)}
|
|
180
|
+
</Tag>
|
|
181
|
+
</div>
|
|
182
|
+
<div className={styles.buildRow}>
|
|
180
183
|
<span className={styles.buildMeta}>
|
|
181
|
-
{
|
|
182
|
-
time: formatDurationBetween(build.
|
|
183
|
-
|
|
184
|
+
{build.dateStarted
|
|
185
|
+
? t('startedAgo', 'Started {{time}} ago', { time: formatDurationBetween(build.dateStarted) })
|
|
186
|
+
: t('notStarted', 'Not started')}
|
|
184
187
|
</span>
|
|
188
|
+
{build.dateCompleted && (
|
|
189
|
+
<span className={styles.buildMeta}>
|
|
190
|
+
{t('completedAgo', 'Completed {{time}} ago', {
|
|
191
|
+
time: formatDurationBetween(build.dateCompleted),
|
|
192
|
+
})}
|
|
193
|
+
</span>
|
|
194
|
+
)}
|
|
195
|
+
</div>
|
|
196
|
+
{build.status === 'FAILED' && build.errorMessage && (
|
|
197
|
+
<p className={styles.buildError}>{build.errorMessage}</p>
|
|
185
198
|
)}
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
</ul>
|
|
201
|
-
)}
|
|
202
|
-
</section>
|
|
199
|
+
{canManage && build.downloadUrl && (
|
|
200
|
+
<Link
|
|
201
|
+
href={makeUrl(`${restBaseUrl}/metadataexport/builds/${build.uuid}/download`)}
|
|
202
|
+
renderIcon={() => <Download size={16} />}
|
|
203
|
+
>
|
|
204
|
+
{t('download', 'Download')}
|
|
205
|
+
</Link>
|
|
206
|
+
)}
|
|
207
|
+
</li>
|
|
208
|
+
))}
|
|
209
|
+
</ul>
|
|
210
|
+
)}
|
|
211
|
+
</section>
|
|
212
|
+
</div>
|
|
203
213
|
</div>
|
|
204
|
-
</
|
|
214
|
+
</Workspace2>
|
|
205
215
|
);
|
|
206
216
|
};
|
|
207
217
|
|
package/src/root.component.tsx
CHANGED
|
@@ -5,7 +5,7 @@ import Dashboard from './components/dashboard/home-dashboard.component';
|
|
|
5
5
|
const Root: React.FC = () => (
|
|
6
6
|
<BrowserRouter basename={window.getOpenmrsSpaBase()}>
|
|
7
7
|
<Routes>
|
|
8
|
-
<Route path="
|
|
8
|
+
<Route path="metadata-export" element={<Dashboard />} />
|
|
9
9
|
</Routes>
|
|
10
10
|
</BrowserRouter>
|
|
11
11
|
);
|
package/src/routes.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
},
|
|
6
6
|
"pages": [
|
|
7
7
|
{
|
|
8
|
-
"route": "
|
|
8
|
+
"route": "metadata-export",
|
|
9
9
|
"component": "root",
|
|
10
10
|
"online": true
|
|
11
11
|
}
|
|
@@ -24,22 +24,37 @@
|
|
|
24
24
|
"component": "deleteMetadataPackageModal"
|
|
25
25
|
}
|
|
26
26
|
],
|
|
27
|
-
"
|
|
27
|
+
"workspaceGroups2": [
|
|
28
28
|
{
|
|
29
|
-
"name": "metadata-
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
|
|
29
|
+
"name": "metadata-export-group",
|
|
30
|
+
"scopePattern": "^/metadata-export",
|
|
31
|
+
"overlay": true
|
|
32
|
+
}
|
|
33
|
+
],
|
|
34
|
+
"workspaceWindows2": [
|
|
35
|
+
{
|
|
36
|
+
"name": "metadata-package-form-window",
|
|
37
|
+
"group": "metadata-export-group",
|
|
33
38
|
"canMaximize": true,
|
|
34
39
|
"width": "narrow"
|
|
35
40
|
},
|
|
36
41
|
{
|
|
37
|
-
"name": "view-metadata-package-
|
|
38
|
-
"
|
|
39
|
-
"title": "View package",
|
|
40
|
-
"type": "form",
|
|
42
|
+
"name": "view-metadata-package-window",
|
|
43
|
+
"group": "metadata-export-group",
|
|
41
44
|
"canMaximize": true,
|
|
42
45
|
"width": "narrow"
|
|
43
46
|
}
|
|
47
|
+
],
|
|
48
|
+
"workspaces2": [
|
|
49
|
+
{
|
|
50
|
+
"name": "metadata-package-form-workspace",
|
|
51
|
+
"component": "metadataPackageFormWorkspace",
|
|
52
|
+
"window": "metadata-package-form-window"
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"name": "view-metadata-package-workspace",
|
|
56
|
+
"component": "viewMetadataPackageWorkspace",
|
|
57
|
+
"window": "view-metadata-package-window"
|
|
58
|
+
}
|
|
44
59
|
]
|
|
45
60
|
}
|
package/translations/en.json
CHANGED
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
"domains": "Domains",
|
|
21
21
|
"download": "Download",
|
|
22
22
|
"edit": "Edit",
|
|
23
|
+
"editPackage": "Edit package",
|
|
23
24
|
"errorLoadingDomains": "Error loading domains",
|
|
24
25
|
"errorLoadingPackage": "Error loading package",
|
|
25
26
|
"FAILED": "Failed",
|
|
@@ -27,7 +28,7 @@
|
|
|
27
28
|
"loadingPackage": "Loading package…",
|
|
28
29
|
"managePackages": "Manage packages",
|
|
29
30
|
"metadataexport": "Metadata Export",
|
|
30
|
-
"
|
|
31
|
+
"newPackage": "New package",
|
|
31
32
|
"nextPage": "Next page",
|
|
32
33
|
"noBuilds": "No builds",
|
|
33
34
|
"noBuildsYet": "No builds yet",
|