Skip to content

Commit

Permalink
new defaults
Browse files Browse the repository at this point in the history
  • Loading branch information
David Nicholas authored and David Nicholas committed Oct 5, 2024
1 parent 34691bc commit a1baa69
Show file tree
Hide file tree
Showing 4 changed files with 142 additions and 13 deletions.
26 changes: 22 additions & 4 deletions public/react/Configure/Teams/ConfigureTeams.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type { NormalizedIssue } from "../../../jira/shared/types";
import type { NormalizeIssueConfig } from "../../../jira/normalized/normalize";
import type { TeamConfiguration } from "./services/team-configuration";

import React from "react";
import React, { useEffect } from "react";
import Form from "@atlaskit/form";
import { useForm } from "react-hook-form";
import { Flex } from "@atlaskit/primitives";
Expand All @@ -14,8 +14,13 @@ import Select from "./components/Select";
import Toggle from "./components/Toggle";
import Hr from "../../components/Hr";

import { useGlobalTeamConfiguration, useSaveGlobalTeamConfiguration } from "./services/team-configuration";
import {
addDefaultFormData,
useGlobalTeamConfiguration,
useSaveGlobalTeamConfiguration,
} from "./services/team-configuration";
import { useJiraIssueFields } from "./services/jira";
import { createNormalizeConfiguration } from "./shared/normalize";
// import EnableableTextField from "./components/EnableableTextField";

export interface ConfigureTeamsProps {
Expand All @@ -32,13 +37,19 @@ export interface FieldUpdates<TProperty extends keyof DefaultFormFields> {
}

const ConfigureTeams: FC<ConfigureTeamsProps> = ({ onUpdate, onInitialDefaultsLoad }) => {
const fieldValues = useGlobalTeamConfiguration({ onInitialDefaultsLoad });
const fieldValues = useGlobalTeamConfiguration();
const save = useSaveGlobalTeamConfiguration({ onUpdate });

const jiraFields = useJiraIssueFields();
const selectableFields = jiraFields.map(({ name }) => ({ value: name, label: name }));

const { register, handleSubmit, getValues, control } = useForm<DefaultFormFields>({ defaultValues: fieldValues });
const { register, handleSubmit, getValues, control } = useForm<DefaultFormFields>({
defaultValues: addDefaultFormData(jiraFields, fieldValues),
});

useOnMount(() => {
onInitialDefaultsLoad?.(createNormalizeConfiguration(getValues()));
});

function update<TProperty extends keyof DefaultFormFields>({ name, value }: FieldUpdates<TProperty>) {
const values = getValues();
Expand Down Expand Up @@ -123,3 +134,10 @@ const ConfigureTeams: FC<ConfigureTeamsProps> = ({ onUpdate, onInitialDefaultsLo
};

export default ConfigureTeams;

// Temporary - don't use
const useOnMount = (effect: () => void) => {
useEffect(() => {
effect();
}, []);
};
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ export * from "./defaults";
export * from "./useGlobalTeamConfiguration";
export * from "./useSaveGlobalTeamConfiguration";
export * from "./key-factory";
export * from "./reconcile";
112 changes: 112 additions & 0 deletions public/react/Configure/Teams/services/team-configuration/reconcile.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import { DefaultFormFields } from "../../ConfigureTeams";
import { StorageFactory } from "../../../../../jira/storage/common";

import { globalTeamConfigurationStorageKey } from ".";

import jiraOidcHelpers from "../../../../../jira-oidc-helpers";
type Jira = ReturnType<typeof jiraOidcHelpers>;

type IssueFields = Array<{
name: string;
key: string;
schema: Record<string, string>;
id: string;
custom: boolean;
clauseNames: string[];
searchable: boolean;
navigable: boolean;
orderable: boolean;
}>;

const nonFieldDefaults: Omit<
DefaultFormFields,
"estimateField" | "confidenceField" | "startDateField" | "dueDateField"
> = {
sprintLength: 10, //
velocityPerSprint: 21, //
tracks: 1,
};

const findFieldCalled = (name: string, jiraFields: IssueFields): string | undefined => {
return jiraFields.find((field) => field.name.toLowerCase() === name.toLowerCase())?.name;
};

const createDefaultJiraFieldGetter = <TFormField extends keyof DefaultFormFields>(
formField: TFormField,
possibleNames: string[],
nameFragments: string[] = []
) => {
return function (userData: Partial<DefaultFormFields>, jiraFields: IssueFields) {
const userDefinedFieldExists = findFieldCalled(formField, jiraFields);

if (userData?.[formField] && userDefinedFieldExists) {
return userData[formField];
}

for (const possibleName of possibleNames) {
const field = findFieldCalled(possibleName, jiraFields);

if (field) {
return field;
}
}

for (const fragment of nameFragments) {
const field = jiraFields.find(({ name }) => name.includes(fragment));

if (field) {
return field.name;
}
}

throw new Error(`Could not determine default value for ${formField}`);
};
};

const getEstimateField = createDefaultJiraFieldGetter(
"estimateField",
["story points median", "days median", "story points", "story point estimate"],
["median", "estimate"]
);

const getConfidenceField = createDefaultJiraFieldGetter(
"confidenceField",
["Story points confidence", "Estimate confidence", "Days confidence"],
["confidence"]
);

const getStartDateField = createDefaultJiraFieldGetter("startDateField", ["start date", "starting date"]);

const getDueDateField = createDefaultJiraFieldGetter("dueDateField", ["due date", "end date", "target date"]);

export const getFormData = async (jira: Jira, storage: ReturnType<StorageFactory>): Promise<DefaultFormFields> => {
const [jiraFields, userData] = await Promise.all([
jira.fetchJiraFields() as unknown as IssueFields,
storage.get<Partial<DefaultFormFields> | undefined>(globalTeamConfigurationStorageKey),
]);

return addDefaultFormData(jiraFields, userData ?? {});
};

export const addDefaultFormData = (
jiraFields: IssueFields,
userData: Partial<DefaultFormFields>
): DefaultFormFields => {
console.log({
...nonFieldDefaults,
...userData,
estimateField: getEstimateField(userData, jiraFields),
confidenceField: getConfidenceField(userData, jiraFields),
startDateField: getStartDateField(userData, jiraFields),
dueDateField: getDueDateField(userData, jiraFields),
});

return {
...nonFieldDefaults,
...userData,
estimateField: getEstimateField(userData, jiraFields),
confidenceField: getConfidenceField(userData, jiraFields),
startDateField: getStartDateField(userData, jiraFields),
dueDateField: getDueDateField(userData, jiraFields),
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,22 @@ import { useSuspenseQuery } from "@tanstack/react-query";
import { createNormalizeConfiguration } from "../../shared/normalize";
import { useStorage } from "../storage";
import { globalTeamConfigurationStorageKey, teamConfigurationKeys } from "./key-factory";
import { defaultGlobalTeamConfiguration } from "./defaults";

export type UseDefaultConfiguration = (config: {
onInitialDefaultsLoad?: (config: Partial<NormalizeIssueConfig>) => void;
}) => TeamConfiguration;
export type UseDefaultConfiguration = () => Partial<TeamConfiguration>;

export const useGlobalTeamConfiguration: UseDefaultConfiguration = ({ onInitialDefaultsLoad }) => {
export const useGlobalTeamConfiguration: UseDefaultConfiguration = () => {
const { get } = useStorage();

const { data } = useSuspenseQuery({
queryKey: teamConfigurationKeys.globalConfiguration(),
queryFn: async () => {
const loaded = await get<TeamConfiguration | undefined>(globalTeamConfigurationStorageKey);
const values = { ...defaultGlobalTeamConfiguration, ...(loaded ?? {}) };
const data = await get<Partial<TeamConfiguration> | undefined>(globalTeamConfigurationStorageKey);

onInitialDefaultsLoad?.(createNormalizeConfiguration(values));
if (!data) {
return {};
}

return values;
return data;
},
});

Expand Down

0 comments on commit a1baa69

Please sign in to comment.