From e4907279dc4d0585935d79c6fec8d9d33ab18171 Mon Sep 17 00:00:00 2001 From: Stefano Ricci Date: Wed, 23 Oct 2024 12:13:20 +0200 Subject: [PATCH 1/4] Survey clone: divide surveys and templates; sort by name --- core/i18n/i18nFactory.js | 7 +- core/i18n/resources/en/common.js | 24 +------ core/i18n/resources/en/index.js | 2 + core/i18n/resources/en/surveyCreate.js | 27 ++++++++ webapp/components/form/Dropdown/Dropdown.js | 4 +- .../components/form/Dropdown/useDropdown.js | 2 +- .../survey/SurveyCreate/SurveyCreate.js | 64 +++++++++++-------- .../survey/SurveyCreate/SurveyCreate.scss | 4 ++ .../SurveyCreate/store/actions/useOnCreate.js | 4 +- .../SurveyCreate/store/useCreateSurvey.js | 3 + .../survey/SurveyDropdown/SurveyDropdown.js | 16 +++-- .../survey/SurveyDropdown/SurveyDropdown.scss | 2 - .../useSurveyDropdownOptions.js | 55 +++++++--------- webapp/model/SurveyType.js | 4 ++ webapp/model/index.js | 1 + .../App/Header/UserPopupMenu/UserPopupMenu.js | 4 +- .../Home/TemplateCreate/TemplateCreate.js | 2 +- 17 files changed, 128 insertions(+), 97 deletions(-) create mode 100644 core/i18n/resources/en/surveyCreate.js create mode 100644 webapp/model/SurveyType.js diff --git a/core/i18n/i18nFactory.js b/core/i18n/i18nFactory.js index e7829b661a..7049ef3719 100644 --- a/core/i18n/i18nFactory.js +++ b/core/i18n/i18nFactory.js @@ -8,6 +8,9 @@ export const Trans = i18nTrans const defaultLanguage = 'en' +const namespaces = ['common', 'appErrors', 'jobs', 'surveyCreate'] +const defaultNamespace = 'common' + const createParams = (lang) => ({ fallbackLng: defaultLanguage, debug: ProcessUtils.isEnvDevelopment, @@ -18,8 +21,8 @@ const createParams = (lang) => ({ nsMode: 'default', // Set it to fallback to let passed namespaces to translated hoc act as fallbacks }, lng: lang, - ns: ['common', 'appErrors', 'jobs'], - defaultNS: 'common', + ns: namespaces, + defaultNS: defaultNamespace, resources: { en: enTranslation, }, diff --git a/core/i18n/resources/en/common.js b/core/i18n/resources/en/common.js index fa2be672d0..95162bff13 100644 --- a/core/i18n/resources/en/common.js +++ b/core/i18n/resources/en/common.js @@ -255,6 +255,7 @@ Do you want to proceed?`, boolean: 'Boolean', code: 'Code', coordinate: 'Coordinate', + geo: 'Geospatial', taxon: 'Taxon', file: 'File', entity: 'Entity', @@ -479,29 +480,6 @@ $t(common.cantUndoWarning)`, active: '$t(common.active)', activate: 'Activate', }, - surveyCreate: { - createSurvey: 'Create Survey', - createTemplate: 'Create Template', - newSurvey: 'New Survey', - newSurveyFromScratch: 'New Survey From Scratch', - newTemplate: 'New Template', - newTemplateFromScratch: 'New Template From Scratch', - source: { - label: 'Source', - arena: 'Arena (.zip)', - collect: 'Collect (.collect, .collect-backup, .collect-data)', - }, - startImport: 'Start import', - survey: 'Survey', - survey_other: 'Surveys', - template: 'Template', - template_other: 'Templates', - error: 'Error creating new survey', - errorMaxSurveysCountExceeded: `Error creating survey; please check that the maximum number of surveys that you can creeate ({{maxSurveysCount}}) has not been exceeded.`, - options: { - includeData: 'Include data', - }, - }, collectImportReport: { excludeResolvedItems: 'Exclude resolved items', expression: 'Expression', diff --git a/core/i18n/resources/en/index.js b/core/i18n/resources/en/index.js index d2f070e6ff..428855aaea 100644 --- a/core/i18n/resources/en/index.js +++ b/core/i18n/resources/en/index.js @@ -2,10 +2,12 @@ import activityLog from './activityLog' import appErrors from './appErrors' import common from './common' import jobs from './jobs' +import surveyCreate from './surveyCreate' export default { activityLog, appErrors, common, jobs, + surveyCreate, } diff --git a/core/i18n/resources/en/surveyCreate.js b/core/i18n/resources/en/surveyCreate.js new file mode 100644 index 0000000000..ff9d605870 --- /dev/null +++ b/core/i18n/resources/en/surveyCreate.js @@ -0,0 +1,27 @@ +export default { + cloneFromType: { + survey: 'Survey', + template: 'Template', + }, + createSurvey: 'Create Survey', + createTemplate: 'Create Template', + newSurvey: 'New Survey', + newSurveyFromScratch: 'New Survey From Scratch', + newTemplate: 'New Template', + newTemplateFromScratch: 'New Template From Scratch', + source: { + label: 'Source', + arena: 'Arena (.zip)', + collect: 'Collect (.collect, .collect-backup, .collect-data)', + }, + startImport: 'Start import', + survey: 'Survey', + survey_other: 'Surveys', + template: 'Template', + template_other: 'Templates', + error: 'Error creating new survey', + errorMaxSurveysCountExceeded: `Error creating survey; please check that the maximum number of surveys that you can creeate ({{maxSurveysCount}}) has not been exceeded.`, + options: { + includeData: 'Include data', + }, +} diff --git a/webapp/components/form/Dropdown/Dropdown.js b/webapp/components/form/Dropdown/Dropdown.js index 3c47058f0b..ea85454c76 100644 --- a/webapp/components/form/Dropdown/Dropdown.js +++ b/webapp/components/form/Dropdown/Dropdown.js @@ -55,6 +55,7 @@ const Dropdown = (props) => { itemLabel = 'label', itemValue = 'value', items: itemsProp, + loading: loadingProp = false, menuPlacement = 'auto', menuPosition = 'fixed', multiple = false, @@ -116,7 +117,7 @@ const Dropdown = (props) => { inputId={inputId} isClearable={clearable && !readOnly} isDisabled={disabled} - isLoading={loading} + isLoading={loading || loadingProp} isMulti={multiple} isSearchable={searchable && !readOnly} onChange={onChange} @@ -147,6 +148,7 @@ Dropdown.propTypes = { itemLabel: PropTypes.oneOfType([PropTypes.string, PropTypes.func]), // item label function or property name itemValue: PropTypes.oneOfType([PropTypes.string, PropTypes.func]), items: PropTypes.oneOfType([PropTypes.array, PropTypes.func]).isRequired, + loading: PropTypes.bool, menuPlacement: PropTypes.oneOf(['auto', 'top', 'bottom']), menuPosition: PropTypes.oneOf(['absolute', 'fixed']), multiple: PropTypes.bool, diff --git a/webapp/components/form/Dropdown/useDropdown.js b/webapp/components/form/Dropdown/useDropdown.js index 0a1e532ba9..636b18ac4a 100644 --- a/webapp/components/form/Dropdown/useDropdown.js +++ b/webapp/components/form/Dropdown/useDropdown.js @@ -123,11 +123,11 @@ export const useDropdown = ({ const itemToOption = useCallback( (item) => ({ + ...item, description: getOptionDescription(item), icon: getOptionIcon(item), label: getOptionLabel(item), value: getOptionValue(item), - ...(item.options ? { options: item.options } : {}), }), [getOptionDescription, getOptionIcon, getOptionLabel, getOptionValue] ) diff --git a/webapp/components/survey/SurveyCreate/SurveyCreate.js b/webapp/components/survey/SurveyCreate/SurveyCreate.js index b1b2b5149b..7f488e8517 100644 --- a/webapp/components/survey/SurveyCreate/SurveyCreate.js +++ b/webapp/components/survey/SurveyCreate/SurveyCreate.js @@ -25,6 +25,7 @@ import LanguageDropdown from '@webapp/components/form/languageDropdown' import { useOnUpdate } from '@webapp/components/hooks' import { Checkbox, Dropdown } from '@webapp/components/form' import { Button, Dropzone, ProgressBar, RadioButtonGroup } from '@webapp/components' +import { SurveyType } from '@webapp/model' import { createTypes, importSources, useCreateSurvey } from './store' import { SurveyDropdown } from '../SurveyDropdown' @@ -32,8 +33,20 @@ import { SurveyDropdown } from '../SurveyDropdown' const fileMaxSizeDefault = 1000 // 1GB const fileMaxSizeSystemAdmin = 2000 // 2GB +const importSourceButtonGroupItems = Object.values(importSources).map((key) => ({ + key, + label: `surveyCreate:source.${key}`, +})) + +const cloneFromTypeButtonGroupItems = Object.values(SurveyType) + .reverse() + .map((key) => ({ + key, + label: `surveyCreate:cloneFromType.${key}`, + })) + const SurveyCreate = (props) => { - const { showImport = true, submitButtonLabel = 'homeView.surveyCreate.createSurvey', template = false } = props + const { showImport = true, submitButtonLabel = 'surveyCreate:createSurvey', template = false } = props const surveyInfo = useSurveyInfo() const i18n = useI18n() @@ -52,6 +65,7 @@ const SurveyCreate = (props) => { source, validation, cloneFrom, + cloneFromType, cloneFromCycle, options, file, @@ -77,9 +91,7 @@ const SurveyCreate = (props) => { items={[ { key: createTypes.fromScratch, - label: template - ? 'homeView.surveyCreate.newTemplateFromScratch' - : 'homeView.surveyCreate.newSurveyFromScratch', + label: template ? 'surveyCreate:newTemplateFromScratch' : 'surveyCreate:newSurveyFromScratch', }, { key: createTypes.clone, @@ -128,15 +140,25 @@ const SurveyCreate = (props) => { {createType === createTypes.clone && ( <> - - { - const cycles = value?.cycles || [] - const lastCycleKey = cycles[cycles.length - 1] - onUpdate({ name: 'cloneFrom', value }, { name: 'cloneFromCycle', value: lastCycleKey }) - }} - /> + +
+ {i18n.t('common.cloneFrom')} + onUpdate({ name: 'cloneFromType', value })} + row + value={cloneFromType} + /> + { + const cycles = value?.cycles || [] + const lastCycleKey = cycles[cycles.length - 1] + onUpdate({ name: 'cloneFrom', value }, { name: 'cloneFromCycle', value: lastCycleKey }) + }} + selection={cloneFrom?.value} + type={cloneFromType} + /> +
{cloneFrom?.cycles?.length > 1 && ( @@ -181,22 +203,14 @@ const SurveyCreate = (props) => { onOptionChange({ key: 'includeData', value })} /> - - ({ - key, - label: `homeView.surveyCreate.source.${key}`, - }))} - onChange={onSourceChange} - row - value={source} - /> + +
{