Skip to content

Commit

Permalink
Merge pull request #5284 from msupply-foundation/5137.2-Requisition-l…
Browse files Browse the repository at this point in the history
…ine-edit-+-UI-updates-to-line-columns

5137.2 requisition line edit + UI updates to line columns
  • Loading branch information
roxy-dao authored Nov 5, 2024
2 parents bdaeea7 + 27a6bfd commit 07cfa6f
Show file tree
Hide file tree
Showing 12 changed files with 263 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import React, { FC } from 'react';
import {
Autocomplete,
BasicTextInput,
Box,
defaultOptionMapper,
getDefaultOptionRenderer,
ReasonOptionNode,
ReasonOptionNodeType,
} from '@openmsupply-client/common';
import { reasonOptions } from '../api';

interface ReasonOptionsSearchInputProps {
value?: ReasonOptionNode | null;
width?: number | string;
onChange: (reasonOption: ReasonOptionNode | null) => void;
autoFocus?: boolean;
type: ReasonOptionNodeType;
isError?: boolean;
isDisabled?: boolean;
}

export const ReasonOptionsSearchInput: FC<ReasonOptionsSearchInputProps> = ({
value,
width,
onChange,
autoFocus = false,
type,
isError,
isDisabled,
}) => {
const { data, isLoading } = reasonOptions.document.listAllActive();

const reasonFilter = (reason: ReasonOptionNode) => {
switch (type) {
case ReasonOptionNodeType.PositiveInventoryAdjustment:
return reason.type === ReasonOptionNodeType.PositiveInventoryAdjustment;
case ReasonOptionNodeType.NegativeInventoryAdjustment:
return reason.type === ReasonOptionNodeType.NegativeInventoryAdjustment;
case ReasonOptionNodeType.RequisitionLineVariance:
return reason.type === ReasonOptionNodeType.RequisitionLineVariance;
case ReasonOptionNodeType.ReturnReason:
return reason.type === ReasonOptionNodeType.ReturnReason;
default:
return false;
}
};
const reasons = (data?.nodes ?? []).filter(reasonFilter);

const isRequired = reasons.length !== 0;

return (
<Box display="flex" flexDirection="row" width={120}>
<Autocomplete
autoFocus={autoFocus}
disabled={isDisabled || !isRequired}
width={`${width}px`}
clearable={false}
value={
value
? {
...value,
label: value.reason,
}
: null
}
loading={isLoading}
onChange={(_, reason) => {
onChange(reason);
}}
renderInput={props => (
<BasicTextInput
{...props}
autoFocus={autoFocus}
InputProps={{
disableUnderline: false,
style: props.disabled ? { paddingLeft: 0 } : {},
...props.InputProps,
}}
sx={{ minWidth: width }}
error={isError}
required={isRequired && !isDisabled}
/>
)}
options={defaultOptionMapper(reasons, 'reason')}
renderOption={getDefaultOptionRenderer('reason')}
isOptionEqualToValue={(option, value) => option?.id === value?.id}
/>
</Box>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './ReasonOptionsSearchInput';
31 changes: 31 additions & 0 deletions client/packages/system/src/ReasonOption/api/api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import {
SortBy,
ReasonOptionSortInput,
ReasonOptionSortFieldInput,
} from '@openmsupply-client/common';
import { Sdk, ReasonOptionRowFragment } from './operations.generated';

export type ListParams = { sortBy?: SortBy<ReasonOptionRowFragment> };

const reasonOptionParsers = {
toSortInput: (
sortBy: SortBy<ReasonOptionRowFragment>
): ReasonOptionSortInput => {
return {
desc: sortBy.isDesc,
key: sortBy.key as ReasonOptionSortFieldInput,
};
},
};

export const getReasonOptionsQuery = (sdk: Sdk) => ({
get: {
listAllActive: async ({ sortBy }: ListParams) => {
const response = await sdk.reasonOptions({
sort: sortBy ? reasonOptionParsers.toSortInput(sortBy) : undefined,
filter: { isActive: true },
});
return response?.reasonOptions;
},
},
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { useReasonOptions } from './useReasonOptions';

export const Document = {
useReasonOptions,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { SortBy, useQuery } from '@openmsupply-client/common';
import { ReasonOptionRowFragment } from '../../operations.generated';
import { useReasonOptionsApi } from '../utils/useReasonOptionsApi';

export const useReasonOptions = (sortBy?: SortBy<ReasonOptionRowFragment>) => {
const api = useReasonOptionsApi();
const result = useQuery(api.keys.sortedList(sortBy), () =>
api.get.listAllActive({ sortBy })
);

return { ...result };
};
11 changes: 11 additions & 0 deletions client/packages/system/src/ReasonOption/api/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Document } from './document';
import { Utils } from './utils';

export const reasonOptions = {
document: {
listAllActive: Document.useReasonOptions,
},
utils: {
api: Utils.useReasonOptionsApi,
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { useReasonOptionsApi } from './useReasonOptionsApi';

export const Utils = {
useReasonOptionsApi,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { useGql, SortBy } from '@openmsupply-client/common';
import { getSdk, ReasonOptionRowFragment } from '../../operations.generated';
import { getReasonOptionsQuery } from '../../api';

export const useReasonOptionsApi = () => {
const keys = {
base: () => ['reasonOptions'] as const,
list: () => [...keys.base(), 'list'] as const,
sortedList: (sortBy?: SortBy<ReasonOptionRowFragment>) =>
[...keys.list(), sortBy] as const,
sortedListActive: (
isActive: boolean,
sortBy?: SortBy<ReasonOptionRowFragment>
) => [...keys.sortedList(sortBy), isActive] as const,
};
const { client } = useGql();
const sdk = getSdk(client);
const queries = getReasonOptionsQuery(sdk);
return { ...queries, keys };
};
2 changes: 2 additions & 0 deletions client/packages/system/src/ReasonOption/api/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './hooks';
export { ReasonOptionRowFragment } from './operations.generated';
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import * as Types from '@openmsupply-client/common';

import { GraphQLClient, RequestOptions } from 'graphql-request';
import gql from 'graphql-tag';
type GraphQLClientRequestHeaders = RequestOptions['requestHeaders'];
export type ReasonOptionRowFragment = { __typename: 'ReasonOptionNode', id: string, type: Types.ReasonOptionNodeType, reason: string, isActive: boolean };

export type ReasonOptionsQueryVariables = Types.Exact<{
sort?: Types.InputMaybe<Array<Types.ReasonOptionSortInput> | Types.ReasonOptionSortInput>;
filter?: Types.InputMaybe<Types.ReasonOptionFilterInput>;
}>;


export type ReasonOptionsQuery = { __typename: 'Queries', reasonOptions: { __typename: 'ReasonOptionConnector', totalCount: number, nodes: Array<{ __typename: 'ReasonOptionNode', id: string, type: Types.ReasonOptionNodeType, reason: string, isActive: boolean }> } };

export const ReasonOptionRowFragmentDoc = gql`
fragment ReasonOptionRow on ReasonOptionNode {
__typename
id
type
reason
isActive
}
`;
export const ReasonOptionsDocument = gql`
query reasonOptions($sort: [ReasonOptionSortInput!], $filter: ReasonOptionFilterInput) {
reasonOptions(sort: $sort, filter: $filter) {
__typename
... on ReasonOptionConnector {
__typename
totalCount
nodes {
__typename
id
type
reason
isActive
}
}
}
}
`;

export type SdkFunctionWrapper = <T>(action: (requestHeaders?:Record<string, string>) => Promise<T>, operationName: string, operationType?: string, variables?: any) => Promise<T>;


const defaultWrapper: SdkFunctionWrapper = (action, _operationName, _operationType, _variables) => action();

export function getSdk(client: GraphQLClient, withWrapper: SdkFunctionWrapper = defaultWrapper) {
return {
reasonOptions(variables?: ReasonOptionsQueryVariables, requestHeaders?: GraphQLClientRequestHeaders): Promise<ReasonOptionsQuery> {
return withWrapper((wrappedRequestHeaders) => client.request<ReasonOptionsQuery>(ReasonOptionsDocument, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'reasonOptions', 'query', variables);
}
};
}
export type Sdk = ReturnType<typeof getSdk>;
27 changes: 27 additions & 0 deletions client/packages/system/src/ReasonOption/api/operations.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
fragment ReasonOptionRow on ReasonOptionNode {
__typename
id
type
reason
isActive
}

query reasonOptions(
$sort: [ReasonOptionSortInput!]
$filter: ReasonOptionFilterInput
) {
reasonOptions(sort: $sort, filter: $filter) {
__typename
... on ReasonOptionConnector {
__typename
totalCount
nodes {
__typename
id
type
reason
isActive
}
}
}
}
2 changes: 2 additions & 0 deletions client/packages/system/src/ReasonOption/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './api'
export * from './Components'

0 comments on commit 07cfa6f

Please sign in to comment.