Skip to content

Commit c2eec52

Browse files
authored
make schema selection lists a configurable setting (#867)
* make schema selection lists a configurable setting * apply formatting changes --------- Co-authored-by: Logende <[email protected]>
1 parent ad430c9 commit c2eec52

18 files changed

Lines changed: 231 additions & 2851 deletions

documentation_user/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* [MOF Synthesis Example](examples/mof_synthesis) (Demonstrates CSV Import, Schema Generation, Schema Editing, Data Editing, JSON Export)
66
* [Configurator Building](examples/configurator_building) (Shows how to use MetaConfigurator as a Configurator Builder, allowing users to create and share URLs that open MetaConfigurator with preloaded schema, data, and settings)
77
* [Code Generation](examples/code_generation) (Shows how to generate code in multiple programming languages from JSON schemas)
8+
* [Schema Selection List](examples/schema_selection_list) (Provide your users a pre-defined list of schemas to choose from; useful for organizations)
89

910
## Load a Schema
1011

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Schema Selection List
2+
3+
## Overview
4+
5+
You can provide one or more lists of pre-defined JSON schemas the user can load from.
6+
This is especially useful for organizations to give their teams quick access to their schemas.
7+
The lists of schemas to show to the user can be configured in the settings, under the `schemaSelectionLists` key.
8+
A list of schemas can be defined by a URL to a JSON file or by an inline array of schema definitions:
9+
10+
```json
11+
"schemaSelectionLists": [
12+
{
13+
"label": "Example Schemas",
14+
"schemas": [
15+
{
16+
"label": "Feature Testing Schema",
17+
"url": "https://github.com/MetaConfigurator/meta-configurator/blob/main/documentation_user/examples/schema_selection_list/example.schema.json"
18+
},
19+
{
20+
"label": "Strenda Schema",
21+
"url": "https://github.com/MetaConfigurator/meta-configurator/blob/main/documentation_user/examples/schema_selection_list/example.schema.json"
22+
},
23+
{
24+
"label": "EnzymeML Schema",
25+
"url": "https://github.com/MetaConfigurator/meta-configurator/blob/main/documentation_user/examples/schema_selection_list/enzymeMl.schema.json"
26+
},
27+
{
28+
"label": "Autonomous Vehicle Schema",
29+
"url": "https://github.com/MetaConfigurator/meta-configurator/blob/main/documentation_user/examples/schema_selection_list/autonomousVehicle.schema.json"
30+
}
31+
]
32+
},
33+
{
34+
"label": "preCICE Schemas",
35+
"schemas": "https://github.com/MetaConfigurator/meta-configurator/blob/main/documentation_user/examples/schema_selection_list/preCICESchemas.json"
36+
}
37+
]
38+
```

meta_configurator/src/components/toolbar/Toolbar.vue

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
import {ref} from 'vue';
33
import TopToolbar from '@/components/toolbar/TopToolbar.vue';
44
import {SessionMode} from '@/store/sessionMode';
5-
import {schemaCollection} from '@/packaged-schemas/schemaCollection';
65
import {fetchSchemasFromJSONSchemaStore} from '@/components/toolbar/fetchSchemasFromJsonSchemaStore';
76
import {openUploadSchemaDialog} from '@/components/toolbar/uploadFile';
87
import InitialSchemaSelectionDialog from '@/components/toolbar/dialogs/InitialSchemaSelectionDialog.vue';
@@ -18,6 +17,7 @@ import {useSettings} from '@/settings/useSettings';
1817
import {hasCurrentNewsChanged, setCurrentNewsHash} from '@/components/toolbar/currentNews';
1918
import DataExportDialog from '@/components/toolbar/dialogs/data-export/DataExportDialog.vue';
2019
import {useErrorService} from '@/utility/errorServiceInstance';
20+
import {fetchExternalContent} from '@/utility/fetchExternalContent';
2121
2222
const props = defineProps<{
2323
currentMode: SessionMode;
@@ -30,11 +30,8 @@ const emit = defineEmits<{
3030
const showAboutDialog = ref(false);
3131
const showNewsDialog = ref(false);
3232
33-
function handleUserSchemaDialogSelection(option: 'Example' | 'JsonStore' | 'File' | 'URL') {
33+
function handleUserSchemaDialogSelectionDefault(option: 'JsonStore' | 'File' | 'URL') {
3434
switch (option) {
35-
case 'Example':
36-
showExampleSchemasDialog();
37-
break;
3835
case 'JsonStore':
3936
showSchemaStoreDialog();
4037
break;
@@ -47,6 +44,41 @@ function handleUserSchemaDialogSelection(option: 'Example' | 'JsonStore' | 'File
4744
}
4845
}
4946
47+
async function handleUserSchemaDialogSelectionCustom(label: string) {
48+
const schemas = useSettings().value.schemaSelectionLists.find(
49+
list => list.label === label
50+
)?.schemas;
51+
if (!schemas) {
52+
useErrorService().onError(
53+
new Error(`Could not find schema selection list with label: ${label}`)
54+
);
55+
return;
56+
}
57+
// schemas is either an URL to a JSON document that specifies the schemas, or directly an array of schemas
58+
// if it is an URL, first resolve it and then proceed
59+
let schemaList: {label: string; url: string}[] = [];
60+
if (typeof schemas === 'string') {
61+
try {
62+
const fetchedContent = await fetchExternalContent(schemas);
63+
schemaList = await fetchedContent.json();
64+
} catch (error) {
65+
useErrorService().onError(
66+
new Error(`Could not fetch schema selection list from URL: ${schemas}`)
67+
);
68+
return;
69+
}
70+
} else if (Array.isArray(schemas)) {
71+
schemaList = schemas;
72+
} else {
73+
useErrorService().onError(
74+
new Error(`Invalid schema selection list format for label: ${label}`)
75+
);
76+
return;
77+
}
78+
fetchedSchemasSelectionDialog.value.setSchemas(schemaList);
79+
fetchedSchemasSelectionDialog.value.show();
80+
}
81+
5082
function showCodeGenerationDialog(schemaMode: boolean) {
5183
if (schemaMode) {
5284
codeGenerationDialog.value?.activateSchemaMode();
@@ -86,10 +118,6 @@ async function showSchemaStoreDialog(): Promise<void> {
86118
useErrorService().onError(error);
87119
}
88120
}
89-
function showExampleSchemasDialog() {
90-
fetchedSchemasSelectionDialog.value.setSchemas(schemaCollection);
91-
fetchedSchemasSelectionDialog.value.show();
92-
}
93121
94122
function showUrlDialog() {
95123
urlInputDialog.value?.show();
@@ -144,7 +172,8 @@ defineExpose({
144172

145173
<InitialSchemaSelectionDialog
146174
ref="initialSchemaSelectionDialog"
147-
@user_selected_option="option => handleUserSchemaDialogSelection(option)" />
175+
@user_selected_default_option="option => handleUserSchemaDialogSelectionDefault(option)"
176+
@user_selected_custom_option="label => handleUserSchemaDialogSelectionCustom(label)" />
148177

149178
<ImportCsvDialog ref="csvImportDialog" />
150179

@@ -166,12 +195,10 @@ defineExpose({
166195

167196
<TopToolbar
168197
:current-mode="props.currentMode"
169-
@show-url-dialog="() => showUrlDialog()"
170198
@show-about-dialog="() => (showAboutDialog = true)"
171-
@show-example-schemas-dialog="() => showExampleSchemasDialog()"
172199
@show-codegen-dialog="schemaMode => showCodeGenerationDialog(schemaMode)"
173200
@show-data-export-dialog="schemaMode => showDataExportDialog(schemaMode)"
174-
@show-schemastore-dialog="() => showSchemaStoreDialog()"
201+
@show-schema-selection-dialog="() => showSchemaSelectionDialog()"
175202
@show-import-csv-dialog="() => showCsvImportDialog()"
176203
@show-snapshot-dialog="() => showSnapshotDialog()"
177204
@show-data-mapping-dialog="() => showDataMappingDialog()"

meta_configurator/src/components/toolbar/TopToolbar.vue

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,7 @@ const props = defineProps<{
1919
2020
const emit = defineEmits<{
2121
(e: 'mode-selected', newMode: SessionMode): void;
22-
(e: 'show-url-dialog'): void;
23-
(e: 'show-example-schemas-dialog'): void;
24-
(e: 'show-schemastore-dialog'): void;
22+
(e: 'show-schema-selection-dialog'): void;
2523
(e: 'show-import-csv-dialog'): void;
2624
(e: 'show-snapshot-dialog'): void;
2725
(e: 'show-about-dialog'): void;
@@ -33,16 +31,8 @@ const emit = defineEmits<{
3331
const settings = useSettings();
3432
const dataFormatOptions = formatRegistry.getFormatNames();
3533
36-
async function showSchemaStoreDialog() {
37-
emit('show-schemastore-dialog');
38-
}
39-
40-
function showExampleSchemasDialog() {
41-
emit('show-example-schemas-dialog');
42-
}
43-
44-
function showUrlDialog() {
45-
emit('show-url-dialog');
34+
async function showSchemaSelectionDialog() {
35+
emit('show-schema-selection-dialog');
4636
}
4737
4838
function showCsvImportDialog() {
@@ -105,10 +95,8 @@ useMagicKeys({
10595
:current-mode="props.currentMode"
10696
@show-codegen-dialog="schemaMode => showCodeGenerationDialog(schemaMode)"
10797
@show-data-export-dialog="schemaMode => showDataExportDialog(schemaMode)"
108-
@show-url-dialog="() => showUrlDialog()"
109-
@show-example-schemas-dialog="() => showExampleSchemasDialog()"
11098
@show-import-csv-dialog="() => showCsvImportDialog()"
111-
@show-schemastore-dialog="() => showSchemaStoreDialog()"
99+
@show-schema-selection-dialog="() => showSchemaSelectionDialog()"
112100
@show-snapshot-dialog="() => showSnapshotDialog()"
113101
@show-data-mapping-dialog="() => showDataMappingDialog()" />
114102

@@ -174,10 +162,8 @@ useMagicKeys({
174162
:current-mode="props.currentMode"
175163
@show-codegen-dialog="schemaMode => showCodeGenerationDialog(schemaMode)"
176164
@show-data-export-dialog="schemaMode => showDataExportDialog(schemaMode)"
177-
@show-url-dialog="() => showUrlDialog()"
178-
@show-example-schemas-dialog="() => showExampleSchemasDialog()"
179165
@show-import-csv-dialog="() => showCsvImportDialog()"
180-
@show-schemastore-dialog="() => showSchemaStoreDialog()"
166+
@show-schema-selection-dialog="() => showSchemaSelectionDialog()"
181167
@show-snapshot-dialog="() => showSnapshotDialog()"
182168
@show-data-mapping-dialog="() => showDataMappingDialog()" />
183169
</div>

meta_configurator/src/components/toolbar/TopToolbarMenuButtons.vue

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,7 @@ const props = defineProps<{
1818
}>();
1919
2020
const emit = defineEmits<{
21-
(e: 'show-url-dialog'): void;
22-
(e: 'show-example-schemas-dialog'): void;
23-
(e: 'show-schemastore-dialog'): void;
21+
(e: 'show-schema-selection-dialog'): void;
2422
(e: 'show-import-csv-dialog'): void;
2523
(e: 'show-snapshot-dialog'): void;
2624
(e: 'show-codegen-dialog', schemaMode: boolean): void;
@@ -30,9 +28,7 @@ const emit = defineEmits<{
3028
3129
const settings = useSettings();
3230
const topMenuBar = new MenuItems(
33-
handleFromWebClick,
34-
handleFromOurExampleClick,
35-
showUrlDialog,
31+
showSchemaSelectionDialog,
3632
showCsvImportDialog,
3733
showSnapshotDialog,
3834
showCodeGenerationDialog,
@@ -41,16 +37,8 @@ const topMenuBar = new MenuItems(
4137
inferSchemaFromSampleData
4238
);
4339
44-
async function handleFromWebClick() {
45-
emit('show-schemastore-dialog');
46-
}
47-
48-
function handleFromOurExampleClick() {
49-
emit('show-example-schemas-dialog');
50-
}
51-
52-
function showUrlDialog() {
53-
emit('show-url-dialog');
40+
function showSchemaSelectionDialog() {
41+
emit('show-schema-selection-dialog');
5442
}
5543
5644
function showCsvImportDialog() {

meta_configurator/src/components/toolbar/dialogs/FetchedSchemasSelectionDialog.vue

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import Listbox from 'primevue/listbox';
66
import type {SchemaOption} from '@/packaged-schemas/schemaOption';
77
import {fetchSchemaFromUrl} from '@/components/toolbar/fetchSchemaFromUrl';
88
import {openClearDataEditorDialog} from '@/components/toolbar/clearFile';
9-
import {loadExampleSchema} from '@/components/toolbar/fetchExampleSchemas';
109
import {useErrorService} from '@/utility/errorServiceInstance';
1110
1211
const showDialog = ref(false);
@@ -27,13 +26,9 @@ watch(selectedSchema, async newSelectedSchema => {
2726
useErrorService().onError(error);
2827
}
2928
} else if (newSelectedSchema.key) {
30-
try {
31-
loadExampleSchema(newSelectedSchema.key);
32-
hideDialog();
33-
openClearDataEditorDialog();
34-
} catch (error) {
35-
useErrorService().onError(error);
36-
}
29+
useErrorService().onError(
30+
new Error(`Fetching schema by key is currently not supported: ${newSelectedSchema.key}`)
31+
);
3732
}
3833
});
3934

meta_configurator/src/components/toolbar/dialogs/InitialSchemaSelectionDialog.vue

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,13 @@
33
import {defineEmits, ref, watch} from 'vue';
44
import Button from 'primevue/button';
55
import Dialog from 'primevue/dialog';
6+
import {SCHEMA_SELECTION_CATEGORIES} from '@/components/toolbar/schemaSelectionCategories';
67
78
const showDialog = ref(false);
89
9-
const categories = ref<Array<{name: string; key: 'Example' | 'JsonStore' | 'File' | 'URL'}>>([
10-
{name: 'Example Schema', key: 'Example'},
11-
{name: 'From Json Schema Store', key: 'JsonStore'},
12-
{name: 'Open Schema File', key: 'File'},
13-
{name: 'Load Schema from URL', key: 'URL'},
14-
]);
15-
1610
defineEmits<{
17-
(e: 'user_selected_option', option: 'Example' | 'JsonStore' | 'File' | 'URL'): void;
11+
(e: 'user_selected_default_option', option: 'JsonStore' | 'File' | 'URL'): void;
12+
(e: 'user_selected_custom_option', label: string): void;
1813
}>();
1914
2015
const selectedCategory = ref();
@@ -40,7 +35,10 @@ defineExpose({show: openDialog, close: hideDialog});
4035
<template>
4136
<Dialog v-model:visible="showDialog" header="Select a Schema">
4237
<div class="flex flex-col gap-3 bigger-dialog-content">
43-
<div v-for="category in categories" :key="category.key" class="flex justify-center">
38+
<div
39+
v-for="category in SCHEMA_SELECTION_CATEGORIES"
40+
:key="category.key"
41+
class="flex justify-center">
4442
<Button
4543
v-model="selectedCategory"
4644
:label="category.name"
@@ -50,7 +48,11 @@ defineExpose({show: openDialog, close: hideDialog});
5048
class="w-full"
5149
@click="
5250
() => {
53-
$emit('user_selected_option', category.key);
51+
if (category.key === 'Custom') {
52+
$emit('user_selected_custom_option', category.name);
53+
} else {
54+
$emit('user_selected_default_option', category.key);
55+
}
5456
hideDialog();
5557
}
5658
" />

0 commit comments

Comments
 (0)