Skip to content

Add multi-folder checkbox to list designer advanced settings #1672

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 7 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/build/webpack/app.view.template.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@
</permissions>
<% } %>
<% if (htmlWebpackPlugin.options.permissionClasses) { %>
<permissionClasses>
<requiresPermissions>
<% htmlWebpackPlugin.options.permissionClasses.forEach((permissionClass) => { %>
<permissionClass name="<%= permissionClass %>"/>
<% }); %>
</permissionClasses>
</requiresPermissions>
<% } %>
<% if (htmlWebpackPlugin.options.requiresLogin) { %>
<requiresLogin/>
Expand Down
2 changes: 1 addition & 1 deletion packages/build/webpack/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ const watchPort = process.env.WATCH_PORT || 3001;

// These minification options are a re-declaration of the default minification options
// for the HtmlWebpackPlugin with the addition of `caseSensitive` because LabKey's
// view templates can contain case-sensitive elements (e.g. `<permissionClasses>`).
// view templates can contain case-sensitive elements (e.g. `<requiresPermissions>`).
// For more information see https://github.com/jantimon/html-webpack-plugin#minification.
const minifyTemplateOptions = {
caseSensitive: true,
Expand Down
4 changes: 2 additions & 2 deletions packages/components/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/components/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@labkey/components",
"version": "6.11.2",
"version": "6.11.3-fb-multifolder.0",
"description": "Components, models, actions, and utility functions for LabKey applications and pages",
"sideEffects": false,
"files": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ describe('AdvancedSettings', () => {
field: field1,
onHide: jest.fn(),
onApply: jest.fn(),
phiLevelEnabled: true,
phiLevelDisabledReason: null,
showDefaultValueSettings: true,
allowUniqueConstraintProperties: true,
defaultDefaultValueType: DOMAIN_EDITABLE_DEFAULT,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ interface AdvancedSettingsProps {
maxPhiLevel: string;
onApply: (any) => any;
onHide: () => any;
phiLevelDisabledReason: string;
phiLevelEnabled: boolean;
showDefaultValueSettings: boolean;
}

Expand Down Expand Up @@ -352,7 +354,15 @@ export class AdvancedSettings extends React.PureComponent<AdvancedSettingsProps,
};

renderMiscOptions = () => {
const { index, field, domainIndex, domainFormDisplayOptions, allowUniqueConstraintProperties } = this.props;
const {
index,
field,
domainIndex,
domainFormDisplayOptions,
allowUniqueConstraintProperties,
phiLevelEnabled,
phiLevelDisabledReason,
} = this.props;
const {
measure,
dimension,
Expand All @@ -365,9 +375,7 @@ export class AdvancedSettings extends React.PureComponent<AdvancedSettingsProps,
} = this.state;
const currentValueExists = phiLevels?.find(level => level.value === PHI) !== undefined;
const disablePhiSelect =
domainFormDisplayOptions.phiLevelDisabled ||
field.disablePhiLevel ||
(PHI !== undefined && !currentValueExists);
!phiLevelEnabled || field.disablePhiLevel || (PHI !== undefined && !currentValueExists);

return (
<>
Expand All @@ -377,14 +385,15 @@ export class AdvancedSettings extends React.PureComponent<AdvancedSettingsProps,
<div className="col-xs-3">
<DomainFieldLabel label="PHI Level" helpTipBody={this.getPhiHelpText()} />
</div>
<div className="col-xs-6">
<div className="col-xs-7">
{!phiLevelEnabled && phiLevelDisabledReason && phiLevelDisabledReason + (PHI !== "NotPHI" ? ". Change this PHI Level to \"Not PHI\" before saving." : "")}
<select
className="form-control"
name={createFormInputName(DOMAIN_FIELD_PHI)}
id={createFormInputId(DOMAIN_FIELD_PHI, domainIndex, index)}
onChange={this.handleChange}
value={PHI}
disabled={disablePhiSelect}
disabled={disablePhiSelect && PHI === "NotPHI"} // Keep it enabled if PHI values are disallowed but something other than NotPHI is current set
>
{!currentValueExists && (
<option key={PHI} value={PHI}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1288,6 +1288,8 @@ export class DomainFormImpl extends React.PureComponent<DomainFormProps, State>
domainContainerPath={domain.container}
schemaName={schemaName ?? domain.schemaName}
queryName={queryName ?? domain.queryName}
phiLevelEnabled={domain.phiLevelEnabled}
phiLevelDisabledReason={domain.phiLevelDisabledReason}
/>
);
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ describe('DomainRow', () => {
onChange: jest.fn(),
onDelete: jest.fn(),
onExpand: jest.fn(),
phiLevelEnabled: true,
phiLevelDisabledReason: null,
showDefaultValueSettings: true,
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ export interface DomainRowProps {
onChange: DomainOnChange;
onDelete: (index?: number) => void;
onExpand: (index?: number) => void;
phiLevelEnabled: boolean;
phiLevelDisabledReason?: string;
queryName?: string;
schemaName?: string;
showDefaultValueSettings: boolean;
Expand Down Expand Up @@ -380,6 +382,8 @@ export class DomainRow extends React.PureComponent<DomainRowProps, DomainRowStat
domainContainerPath,
schemaName,
queryName,
phiLevelEnabled,
phiLevelDisabledReason,
} = this.props;
const { selected } = field;
const draggableId = createFormInputId('domaindrag', domainIndex, index);
Expand Down Expand Up @@ -420,6 +424,8 @@ export class DomainRow extends React.PureComponent<DomainRowProps, DomainRowStat
defaultDefaultValueType={defaultDefaultValueType}
defaultValueOptions={defaultValueOptions}
domainFormDisplayOptions={domainFormDisplayOptions}
phiLevelEnabled={phiLevelEnabled}
phiLevelDisabledReason={phiLevelDisabledReason}
/>
)}
<div
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,6 @@ export const DEFAULT_DOMAIN_FORM_DISPLAY_OPTIONS = {
hideValidators: false,
isDragDisabled: false,
hideTextOptions: false,
phiLevelDisabled: false,
hideAddFieldsButton: false,
disableMvEnabled: false,
hideImportData: false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ export const DISPLAY_TITLE_TIP = (
);
export const DISCUSSION_LINKS_TIP =
'Optionally allow one or more discussion links to be shown on the details view of each list item.';
export const SEARCH_INDEXING_TIP = 'Controls how this list is indexed for search within LabKey Server.';
export const SEARCH_INDEXING_TIP = 'Controls how this list is indexed for full-text search.';
export const MULTI_FOLDER_TIP =
'Allows data in this list to span multiple folders. Note that multi-folder lists do not allow PHI annotations on their fields.';

interface DisplayTitleProps {
model: ListModel;
Expand Down Expand Up @@ -259,6 +261,29 @@ export const SeparateDocumentIndexFields: FC<SeparateDocumentIndexFieldsProps> =
);
});

interface FolderSettingsProps {
multiFolder: boolean;
onCheckboxChange: (name, checked) => void;
}

export const FolderSettings: FC<FolderSettingsProps> = memo(({ multiFolder, onCheckboxChange }) => {
const onMultiFolderChange = useCallback(
(event: ChangeEvent<HTMLInputElement>): void => {
onCheckboxChange('multiFolder', event.target.checked);
},
[onCheckboxChange]
);

return (
<div className="list__advanced-settings-modal__index-checkbox">
<label>
<input checked={multiFolder} type="checkbox" onChange={onMultiFolderChange} />
Multi-folder <LabelHelpTip title="Multi-folder">{MULTI_FOLDER_TIP}</LabelHelpTip>
</label>
</div>
);
});

interface CollapsibleFieldsProps extends PropsWithChildren {
checked: boolean;
collapseFields: () => void;
Expand Down Expand Up @@ -383,7 +408,7 @@ export const SearchIndexing: FC<SearchIndexingProps> = memo(props => {
});

interface SettingsContainerProps extends PropsWithChildren {
tipBody: string | JSX.Element;
tipBody?: string | JSX.Element;
tipTitle?: string;
title: string;
}
Expand All @@ -392,7 +417,7 @@ const SettingsContainer: FC<SettingsContainerProps> = memo(({ children, title, t
<div className="list__advanced-settings-modal__section-container">
<div className="list__advanced-settings-modal__heading">
<span className="list__bold-text"> {title} </span>
<LabelHelpTip title={tipTitle || title}>{tipBody}</LabelHelpTip>
{tipBody && <LabelHelpTip title={tipTitle || title}>{tipBody}</LabelHelpTip>}
</div>

{children}
Expand Down Expand Up @@ -445,6 +470,8 @@ export class AdvancedSettings extends React.PureComponent<AdvancedSettingsProps,
// index
eachItemBodySetting: model.eachItemBodySetting,
eachItemBodyTemplate: model.eachItemBodyTemplate,

multiFolder: model.multiFolder,
};
};

Expand Down Expand Up @@ -505,6 +532,7 @@ export class AdvancedSettings extends React.PureComponent<AdvancedSettingsProps,
titleColumn,
entireListBodyTemplate,
eachItemBodyTemplate,
multiFolder,
} = this.state;
const { title, model } = this.props;
const entireListIndexSettings = {
Expand Down Expand Up @@ -577,6 +605,10 @@ export class AdvancedSettings extends React.PureComponent<AdvancedSettingsProps,
fileAttachmentIndex={fileAttachmentIndex}
/>
</SettingsContainer>

<SettingsContainer title="Folder settings">
<FolderSettings multiFolder={multiFolder} onCheckboxChange={this.onCheckboxChange} />
</SettingsContainer>
</Modal>
)}
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export interface AdvancedSettingsForm extends EachItemSettings, EntireListSettin
eachItemIndex: boolean;
entireListIndex: boolean;
fileAttachmentIndex: boolean;
multiFolder: boolean;
titleColumn: string;
}

Expand Down Expand Up @@ -74,6 +75,7 @@ export class ListModel extends Record({
eachItemBodySetting: undefined,
eachItemBodyTemplate: undefined,
fileAttachmentIndex: undefined,
multiFolder: undefined,
listId: undefined,
discussionSettingEnum: undefined,
containerPath: undefined,
Expand Down Expand Up @@ -103,6 +105,7 @@ export class ListModel extends Record({
declare eachItemBodySetting: number;
declare eachItemBodyTemplate: string;
declare fileAttachmentIndex: false;
declare multiFolder: false;
declare listId: number;
declare discussionSettingEnum: string;
declare containerPath: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,8 @@ interface IDomainDesign {
name: string;
// set of fields to initialize a manually created design
newDesignFields?: List<DomainField>;
phiLevelEnabled: boolean;
phiLevelDisabledReason?: string;
queryName?: string;
schemaName?: string;
showDefaultValueSettings: boolean;
Expand Down Expand Up @@ -199,6 +201,8 @@ export class DomainDesign
schemaName: undefined,
queryName: undefined,
disabledSystemFields: undefined,
phiLevelEnabled: true,
phiLevelDisabledReason: undefined,
})
implements IDomainDesign
{
Expand Down Expand Up @@ -230,6 +234,8 @@ export class DomainDesign
declare schemaName: string;
declare queryName: string;
declare disabledSystemFields?: string[];
declare phiLevelEnabled: boolean;
declare phiLevelDisabledReason?: string;

static create(rawModel: any, exception?: any): DomainDesign {
let fields = List<DomainField>();
Expand Down Expand Up @@ -2105,7 +2111,6 @@ export interface IDomainFormDisplayOptions {
hideTextOptions?: boolean;
hideValidators?: boolean;
isDragDisabled?: boolean;
phiLevelDisabled?: boolean;
retainReservedFields?: boolean;
showFilterCriteria?: boolean;
showScannableOption?: boolean;
Expand Down