Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/production' into add_delete_tree…
Browse files Browse the repository at this point in the history
…_rank_api
  • Loading branch information
CarolineDenis committed May 21, 2024
2 parents fb53e79 + a048403 commit 87182f0
Show file tree
Hide file tree
Showing 21 changed files with 292 additions and 58 deletions.
1 change: 1 addition & 0 deletions specifyweb/frontend/js_src/lib/components/Atoms/Icons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ export const icons = {
// This icon is not from heroicons. It was drawn by @maxpatiiuk
tree: <svg aria-hidden className={iconClassName} fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><rect height="10" rx="2" width="10"/><rect fillOpacity="0" height="8" rx="2" stroke="currentColor" strokeWidth="2" width="8" x="11" y="11"/><rect height="16" rx="1" width="2" x="4"/><rect height="2" rx="1" width="7" x="4" y="14"/></svg>,
// This icon is not from Heroicons. It was drawn by @grantfitzsimmons
truck: <svg aria-hidden className={iconClassName} fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="M3.375 4.5C2.339 4.5 1.5 5.34 1.5 6.375V13.5h12V6.375c0-1.036-.84-1.875-1.875-1.875h-8.25ZM13.5 15h-12v2.625c0 1.035.84 1.875 1.875 1.875h.375a3 3 0 1 1 6 0h3a.75.75 0 0 0 .75-.75V15Z" /><path d="M8.25 19.5a1.5 1.5 0 1 0-3 0 1.5 1.5 0 0 0 3 0ZM15.75 6.75a.75.75 0 0 0-.75.75v11.25c0 .087.015.17.042.248a3 3 0 0 1 5.958.464c.853-.175 1.522-.935 1.464-1.883a18.659 18.659 0 0 0-3.732-10.104 1.837 1.837 0 0 0-1.47-.725H15.75Z" /><path d="M19.5 19.5a1.5 1.5 0 1 0-3 0 1.5 1.5 0 0 0 3 0Z" /></svg>,
undoSynonym: <svg aria-hidden className={iconClassName} fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="M1.6,10.3c-0.4,0.4-0.4,1,0,1.4l6,6C8,18.1,9.3,18,9.3,17v-2.3V3c0-0.6-0.4-1-1-1s-1,0.4-1,1v11.6L3,10.3 C2.6,9.9,2,9.9,1.6,10.3z"/><path d="M18.4,9.7c0.4-0.4,0.4-1,0-1.4l-6-6C12,1.9,10.7,2,10.7,3v2.3V17c0,0.6,0.4,1,1,1s1-0.4,1-1V5.4L17,9.7 C17.4,10.1,18,10.1,18.4,9.7z"/></svg>,
upload: <svg aria-hidden className={iconClassName} fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path clipRule="evenodd" d="M3 17a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM6.293 6.707a1 1 0 010-1.414l3-3a1 1 0 011.414 0l3 3a1 1 0 01-1.414 1.414L11 5.414V13a1 1 0 11-2 0V5.414L7.707 6.707a1 1 0 01-1.414 0z" fillRule="evenodd" /></svg>,
userCircle: <svg aria-hidden className={iconClassName} fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path clipRule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-6-3a2 2 0 11-4 0 2 2 0 014 0zm-2 4a5 5 0 00-4.546 2.916A5.986 5.986 0 0010 16a5.986 5.986 0 004.546-2.084A5 5 0 0010 11z" fillRule="evenodd" /></svg>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,10 +177,10 @@ function resolveBackendLocalization(jsonResponseData: any): string {
operation: jsonResponseData.operation,
nodeModel: jsonResponseData.nodeModel,
});
else if (localizationKey === 'mergeAcrossTrees')
return backEndText.mergeAcrossTrees();
else if (localizationKey === 'synonymizeAcrossTrees')
return backEndText.synonymizeAcrossTrees();
else if (localizationKey === 'operationAcrossTrees')
return backEndText.operationAcrossTrees({
operation: jsonResponseData.operation,
});
else if (localizationKey === 'limitReachedDeterminingAccepted')
return backEndText.limitReachedDeterminingAccepted({
taxonId: jsonResponseData.taxonId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ import type { FormType } from '../FormParse';
import type { SubViewSortField } from '../FormParse/cells';
import { augmentMode, ResourceView } from '../Forms/ResourceView';
import { useFirstFocus } from '../Forms/SpecifyForm';
import type { InteractionWithPreps } from '../Interactions/helpers';
import { interactionPrepTables } from '../Interactions/helpers';
import {
interactionPrepTables,
InteractionWithPreps,
} from '../Interactions/helpers';
import { InteractionDialog } from '../Interactions/InteractionDialog';
import { hasTablePermission } from '../Permissions/helpers';
import { relationshipIsToMany } from '../WbPlanView/mappingHelpers';
Expand Down Expand Up @@ -152,7 +154,10 @@ export function IntegratedRecordSelector({
typeof collection.related === 'object' &&
isDialogOpen ? (
<InteractionDialog
actionTable={collection.related.specifyTable}
actionTable={
collection.related
.specifyTable as SpecifyTable<InteractionWithPreps>
}
interactionResource={interactionResource}
itemCollection={
collection as Collection<AnyInteractionPreparation>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,22 @@ import { H3 } from '../Atoms';
import { Button } from '../Atoms/Button';
import { Link } from '../Atoms/Link';
import { LoadingContext, ReadOnlyContext } from '../Core/Contexts';
import type { AnySchema, SerializedResource, AnyInteractionPreparation,
SerializedResource, } from '../DataModel/helperTypes';
import type {
AnySchema,
AnyInteractionPreparation,
SerializedResource,
} from '../DataModel/helperTypes';
import type { SpecifyResource } from '../DataModel/legacyTypes';
import { getResourceViewUrl } from '../DataModel/resource';
import type { LiteralField } from '../DataModel/specifyField';
import type { Collection, SpecifyTable } from '../DataModel/specifyTable';
import { tables } from '../DataModel/tables';
import type { RecordSet } from '../DataModel/types';
import type {
DisposalPreparation,
GiftPreparation,
LoanPreparation,
RecordSet,
} from '../DataModel/types';
import { AutoGrowTextArea } from '../Molecules/AutoGrowTextArea';
import { Dialog } from '../Molecules/Dialog';
import { userPreferences } from '../Preferences/userPreferences';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export const operationPolicies = {
'synonymize',
'desynonymize',
'repair',
'bulk_move',
],
'/tree/edit/geologictimeperiod': [
'merge',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ const auditLogActions = [
queryText.treeMove(),
queryText.treeSynonymize(),
queryText.treeDesynonymize(),
queryText.treeBulkMove(),
] as const;

const pickListSortTypes = f.store(() => [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ export function QueryFieldFormatter({
<div>
<Select
aria-label={queryText.chooseFormatter()}
className={`${customSelectElementBackground}`}
className={customSelectElementBackground}
disabled={handleChange === undefined}
id={id('list')}
value={formatter}
Expand All @@ -89,7 +89,7 @@ export function QueryFieldFormatter({
<option />
{availableFormatters.map(({ name, title, isDefault }, index) => (
<option key={index} value={name}>
{title} {isDefault ? resourcesText.defaultInline() : ''}
{`${title} ${isDefault ? resourcesText.defaultInline() : ''}`}
</option>
))}
</Select>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { className } from '../Atoms/className';
import { Input } from '../Atoms/Form';
import type { Tables } from '../DataModel/types';
import { getNoAccessTables } from '../QueryBuilder/helpers';
import { DeleteStatsCategory } from './DeleteCategory';
import { generateStatUrl, makeSerializedFieldsFromPaths } from './hooks';
import { StatItem } from './StatItems';
import { backEndStatsSpec, dynamicStatsSpec, statsSpec } from './StatsSpec';
Expand Down Expand Up @@ -142,6 +143,7 @@ export function Categories({
(items ?? []).some(
(item) => item.type === 'CustomStat' || item.isVisible === undefined
);

return pageLayout === undefined ? null : (
<>
{pageLayout.categories.map(
Expand Down Expand Up @@ -269,14 +271,12 @@ export function Categories({
) : null}
{typeof handleAdd === 'function' ? (
<div className="flex gap-2">
<Button.Small
variant={className.borderedGrayButton}
onClick={(): void =>
handleRemove?.(categoryIndex, undefined)
}
>
{statsText.deleteCategory()}
</Button.Small>
{typeof handleRemove === 'function' ? (
<DeleteStatsCategory
categoryLabel={label}
onDelete={() => handleRemove(categoryIndex, undefined)}
/>
) : null}
<span className="-ml-2 flex-1" />
<Button.Small
variant={className.infoButton}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import React from 'react';

import { useBooleanState } from '../../hooks/useBooleanState';
import { commonText } from '../../localization/common';
import { statsText } from '../../localization/stats';
import { StringToJsx } from '../../localization/utils';
import { localized } from '../../utils/types';
import { Button } from '../Atoms/Button';
import { className } from '../Atoms/className';
import { Dialog } from '../Molecules/Dialog';

export function DeleteStatsCategory({
onDelete: handleDelete,
categoryLabel,
}: {
readonly categoryLabel: string;
readonly onDelete: () => void;
}): JSX.Element {
const [triedToDelete, _, __, toggleTriedToDelete] = useBooleanState(false);
return (
<>
<Button.Small
variant={className.secondaryButton}
onClick={toggleTriedToDelete}
>
{statsText.deleteCategory()}
</Button.Small>
{triedToDelete && (
<Dialog
buttons={
<>
<Button.Danger
onClick={() => {
handleDelete();
toggleTriedToDelete();
}}
>
{commonText.delete()}
</Button.Danger>
<span className="-ml-2 flex-1" />
<Button.DialogClose>{commonText.cancel()}</Button.DialogClose>
</>
}
header={localized(
`${statsText.deleteCategory()} '${categoryLabel}'?`
)}
onClose={toggleTriedToDelete}
>
{statsText.deleteWarning()}{' '}
<StringToJsx
components={{
wrap: <i className="flex items-center gap-2">{categoryLabel}</i>,
}}
string={commonText.jsxColonLine({
label: statsText.categoryToDelete(),
})}
/>
</Dialog>
)}
</>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,7 @@ import { Http } from '../../utils/ajax/definitions';
import { throttledPromise } from '../../utils/ajax/throttledPromise';
import { localized } from '../../utils/types';
import { formatNumber } from '../Atoms/Internationalization';
import {
deserializeResource,
serializeResource,
} from '../DataModel/serializers';
import { serializeResource } from '../DataModel/serializers';
import { getNoAccessTables } from '../QueryBuilder/helpers';
import {
makeSerializedFieldsFromPaths,
Expand Down Expand Up @@ -244,7 +241,7 @@ function QueryItem({
async () =>
throttledPromise<AjaxResponseObject<{ readonly count: number }>>(
'queryStats',
queryCountPromiseGenerator(deserializeResource(serializedQuery)),
queryCountPromiseGenerator(serializedQuery),
JSON.stringify(querySpec)
).then((response) => {
if (response === undefined) return undefined;
Expand All @@ -253,8 +250,7 @@ function QueryItem({
setStatState('valid');
return formatNumber(data.count);
}
if (status === Http.FORBIDDEN) setStatState('noPermission');
setStatState('error');
setStatState(status === Http.FORBIDDEN ? 'noPermission' : 'error');
return undefined;
}),

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ export function useDefaultStatsToAdd(
}

export function queryCountPromiseGenerator(
query: SpecifyResource<SpQuery>
query: SerializedResource<SpQuery>
): () => Promise<AjaxResponseObject<{ readonly count: number }>> {
return async () =>
ajax<{
Expand All @@ -202,7 +202,7 @@ export function queryCountPromiseGenerator(
Accept: 'application/json',
},
body: keysToLowerCase({
...serializeResource(query),
...query,
countOnly: true,
}),
expectedErrors: Object.values(Http),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,10 +149,6 @@ function ProtectedStatsPage(): JSX.Element | null {
readonly categoryIndex: number;
}
>
| State<
'DeletingCategoryState',
{ readonly categoryContainsCustom: boolean }
>
| State<
'PageRenameState',
{
Expand Down
Loading

0 comments on commit 87182f0

Please sign in to comment.