Skip to content

Commit

Permalink
merge locally
Browse files Browse the repository at this point in the history
  • Loading branch information
pksorensen committed May 31, 2024
2 parents 0cd96b4 + 3b933c9 commit 0e9e0a4
Show file tree
Hide file tree
Showing 31 changed files with 817 additions and 93 deletions.
46 changes: 23 additions & 23 deletions 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/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"react-dom": "^18.2.0"
},
"peerDependencies": {
"@griffel/react": "1.5.20",
"@griffel/react": "1.5.23",
"@opentelemetry/api": "^1.8.0"
},
"devDependencies": {
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/components/button/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export const Button: React.FC<PropsWithChildren<BtnContainerProps>> = ({ childre

</button>
{!disabled && !isOnMobile && showPressEnter && (
<span style={{ color: quickformtokens.onPrimary, fontSize: quickformtokens.btnEnterKeyTextFontSize }}>
<span style={{ color: quickformtokens.onSurface, fontSize: quickformtokens.btnEnterKeyTextFontSize }}>
<>Tryk <strong style={{ fontWeight: 'bolder', letterSpacing: '0.04em', }}>Enter ↵</strong></>
</span>
)}
Expand Down
11 changes: 6 additions & 5 deletions packages/core/src/components/icons/IconResolver.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,18 @@ import { EmailIcon } from "./EmailIcon";
import { TelephoneIcon } from "./TelephoneIcon";
import { UserIcon } from "./UserIcon";
import { IconProps } from "./iconProps";
import { Checkmark } from '../icons/Checkmark';

export type IconType = "Email" | "Phone" | "User";
export type IconResolverProps = {
type: IconType,
} & IconProps

export const IconResolver: React.FC<IconResolverProps> = ({ type, color, className, size }) => {
export const IconResolver: React.FC<IconResolverProps> = ({ type, color, className, size, style }): JSX.Element => {
switch (type) {
case "Email": return <EmailIcon className={className} color={color} size={size} />
case "Phone": return <TelephoneIcon className={className} color={color} size={size} />
case "User": return <UserIcon className={className} color={color} size={size} />
default: return <UserIcon className={className} color={color} size={size} />
case "Email": return <EmailIcon className={className} color={color} size={size} style={style} />
case "Phone": return <TelephoneIcon className={className} color={color} size={size} style={style} />
case "User": return <UserIcon className={className} color={color} size={size} style={style} />
default: return <Checkmark className={className} color={color} size={size} style={style} />;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export const BaseInputComponent: React.FC<BaseInputComponentProps> = ({ question
span.addEvent("BaseInputComponent:render");
}



const resize = () => {
const input = ref.current;
Expand All @@ -104,7 +104,7 @@ export const BaseInputComponent: React.FC<BaseInputComponentProps> = ({ question
}

const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
console.log("BaseInputComponent:handleChange", event.target.value);
console.log("BaseInputComponent:handleChange", event.target.value);
if (span) {
span.addEvent("BaseInputComponent:handleChange", { 'value': event.target.value });
}
Expand All @@ -119,9 +119,9 @@ export const BaseInputComponent: React.FC<BaseInputComponentProps> = ({ question
}

/**
* The input control is responsible of setting it self focus when becoming active.
* - We should also listen to input controls being focused and if not active, trigger a reducer that its set active.
* Ultimatly removing active from other questions. This happens right now when an answer is given (intermediate or not), so not critical.
* The input control is responsible of setting itself focused when becoming active.
* - We should also listen to inputcontrols being focused and if not active, trigger a reducer that sets it to active. Ultimately removing active from other questions.
* This happens right now when an answer is given (intermediate or not), so not critical.
*/
useEffect(() => {
if (questionModel.isActive)
Expand All @@ -132,7 +132,7 @@ export const BaseInputComponent: React.FC<BaseInputComponentProps> = ({ question
* While a base input component is active we should answer the question upon enter.
*/
useHandleEnterKeypress("baseinput", !questionModel.isActive, () => {
answerQuestion(questionModel.logicalName, text,false);
answerQuestion(questionModel.logicalName, text, false);
});

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,22 +43,26 @@ const useInputTextStyles = makeStyles({

export const MultilineInput: InputComponentType<MultilineProperties> = ({ questionModel }) => {
const styles = useInputTextStyles();
const { isFirstQuestionInCurrentSlide, answerQuestion } = useQuickForm();
const { isFirstQuestionInCurrentSlide, answerQuestion, state } = useQuickForm();
const { placeholder, output } = questionModel;
const [text, setText] = useState<string>(output || '');
const ref = useRef<HTMLTextAreaElement>(null);

const handleChange = (event: ChangeEvent<HTMLTextAreaElement>) => {
const newValue = event.target.value.replace(/\r?\n/g, '\n'); // Normalize newline characters
setText(newValue);
answerQuestion(questionModel.logicalName, newValue, true);
};

const ref = useRef<HTMLTextAreaElement>(null);
/**
* The input control is responsible of setting itself focused when becoming active.
* - We should also listen to inputcontrols being focused and if not active, trigger a reducer that sets it to active. Ultimately removing active from other questions.
* This happens right now when an answer is given (intermediate or not), so not critical.
*/
useEffect(() => {
if (ref.current && isFirstQuestionInCurrentSlide(questionModel.logicalName)) {
ref.current.focus();
}
}, [ref, isFirstQuestionInCurrentSlide, questionModel.logicalName]);
if (questionModel.isActive || ref.current && isFirstQuestionInCurrentSlide(questionModel.logicalName))
ref.current?.focus();
}, [ref, isFirstQuestionInCurrentSlide, questionModel.logicalName, questionModel.isActive]);

return (
<textarea onBlur={() => answerQuestion(questionModel.logicalName, text, false)}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,31 @@
"use client";
import React, { useEffect, useRef, useState } from 'react';
import { useQuickForm } from '../../../state/QuickFormContext';
import { Button } from '../../button/Button';
import { Button, Slide } from '../../index';
import { useHandleEnterKeypress } from '../../../hooks';
import { Slide } from '../../slide/Slide';
import { Checkmark } from '../../icons';
import { quickformtokens } from '../../../style/quickFormTokensDefinition';
import { quickformtokens } from "../../../style";
import { mergeClasses } from '@griffel/react';


import { IconResolver } from '../../icons/IconResolver';
import { SlideModel } from '../../../model';

export const SlideRenderer: React.FC = () => {

const { state, goToNextSlide } = useQuickForm();
const currentSlide = state.slides[state.currIdx];
const [className, setClassName] = useState(state.classes.slide);

const currentSlide: SlideModel = state.slides[state.currIdx];
const buttonText: string = currentSlide.buttonText ?? "OK";
const showPressEnter: boolean = currentSlide.questions.some(q => q.inputType === "multilinetext" && q.isActive) === false;

/* KBA - Leaving this for now - have to get back to it since we never actually set .isActive property on question.. so we cant use it to condition with at the moment.. */
// const showPressEnter: boolean = currentSlide.questions.some(q => q.inputType === "multilinetext" && q.isActive) === false;
console.log("showPressEnter", showPressEnter);
console.log("showPressEnterCondition", currentSlide.questions.some(q => q.inputType === "multilinetext" && q.isActive));
console.log("showPressEnterCurrentSlide", currentSlide);

console.log("SlideRenderer", currentSlide);
/* Listens to enter key pressed */
const enterKeyDisabled = currentSlide.questions.some(q => q.inputType === "multilinetext" && q.isActive);
useHandleEnterKeypress("slide", enterKeyDisabled, goToNextSlide);
useHandleEnterKeypress("slide", !showPressEnter, goToNextSlide);

const [className, setClassName] = useState(state.classes.slide);
let nextAllowedEffectTime = useRef(new Date().getTime());
useEffect(() => {
const timeout = setTimeout(() => {
Expand All @@ -40,8 +46,13 @@ export const SlideRenderer: React.FC = () => {
<Button
style={{ display: 'flex', alignItems: 'center', justifyContent: 'start' }}
onClick={goToNextSlide}
showPressEnter={!enterKeyDisabled}
children={<>OK<Checkmark style={{ height: '100%', marginLeft: quickformtokens.gap1 }} color={quickformtokens.onPrimary} size={24} /></>} />
showPressEnter={showPressEnter}
children={
<>
{buttonText}<IconResolver type={currentSlide.icon} style={{ height: '100%', marginLeft: quickformtokens.gap1 }} color={quickformtokens.onPrimary} size={24} />
</>
}
/>
</div>
);
};
Expand Down
3 changes: 3 additions & 0 deletions packages/core/src/model/SlideModel.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { IconType } from "../components/icons/IconResolver";
import { resolveQuickFormService } from "../services/QuickFormServices";
import { QuestionModel } from "./QuestionModel";
import { QuestionJsonModel } from "./json-definitions/JsonDataModels";
import { QuestionRef } from "./json-definitions/Layout";

export class SlideModel {
displayName?: string;
buttonText?: string;
icon?: IconType;
questions: QuestionModel[] = [];
rows: Row[];

Expand Down
5 changes: 4 additions & 1 deletion packages/core/src/model/json-definitions/Layout.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { QuickFormTokens } from "../../style/quickFormTokensDefinition";
import { QuickformClassNames } from "../../state/QuickformState";
import { IconType } from "../../components/icons/IconResolver";

export type LayoutDefinition = {
classes?: Partial<QuickformClassNames>,
Expand All @@ -19,7 +20,9 @@ export type SlideLayout = {
style?: React.CSSProperties;
rows?: SlideElements;
schemaName?: string;
logicalName?: string
logicalName?: string;
buttonText?: string;
icon?: IconType;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,8 @@ const parseInputProperties = (questionJsonModel: QuestionJsonModel): InputProper
.filter(([key]) => !['text', 'paragraph', 'placeholder'].includes(key))
.map(([key, schema]) => [key, questionJsonModel[key as keyof QuestionJsonModel] ?? getDefaultValue(schema)])) as InputPropertiesTypes;
}
//This will always return {} , do we know what we are doing here? KBA?
const inputTypePropertiesMap: { [key: string]: () => InputPropertiesTypes } = {};

return inputType in inputTypePropertiesMap ? inputTypePropertiesMap[inputType]() : {};
return {};
};

registerQuickFormService("inputTypePropertiesTransformer", parseInputProperties);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ const validateEmail = (output: any): ValidationResult => {

const validatePhone = async (output: any): Promise<ValidationResult> => {
// Wait for 2 seconds to demo
await new Promise(resolve => setTimeout(resolve, 2000));
// await new Promise(resolve => setTimeout(resolve, 2000));

const phoneRegex = /^[0-9]{8,}$/;
const valid = typeof output === 'string' && phoneRegex.test(output);
Expand Down
11 changes: 7 additions & 4 deletions packages/core/src/services/defaults/DefaultModelTransformer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ function handleLayout(layout: LayoutDefinition, questions: QuickFormQuestionsDef
Object.values(layout.slides).forEach(slide => {
const slideModel = new SlideModel();
slideModel.displayName = slide.title;
slideModel.buttonText = slide.buttonText;
slideModel.icon = slide.icon;

if (slide.rows) {
slideModel.rows = processRows(slide.rows, slideModel, questions, payload);
}
Expand All @@ -112,9 +115,9 @@ function defaultLayout(questions: QuickFormQuestionsDefinition, payload: any): S
Object.keys(questions).map((key, index) => [key, index] as [string, number])
.sort(([q1, i1], [q2, i2]) => (questions[q1].order ?? i1) - (questions[q2].order ?? i2))
.map(([questionKey]) => {
let slide: SlideModel = createSlide({ [questionKey]: questions[questionKey] }, payload);
slides.push(slide);
});
let slide: SlideModel = createSlide({ [questionKey]: questions[questionKey] }, payload);
slides.push(slide);
});

logger.log("Generated {@slides} from layout", slides);

Expand Down Expand Up @@ -189,7 +192,7 @@ const transformJSONInput: QuickFormModelTransformer = (definition, payload): Qui

// Transform questions into slides with rows and columns
if (isDefined(definition.questions)) {
if (definition.layout && definition.layout.slides && Object.keys(definition.layout.slides).length>0) {
if (definition.layout && definition.layout.slides && Object.keys(definition.layout.slides).length > 0) {
// If layout is defined, assign slides as per layout
slides = handleLayout(definition.layout!, definition.questions, payload);
} else {
Expand Down
5 changes: 1 addition & 4 deletions packages/core/src/state/QuickformProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,9 @@ import { ErrorPopup, QuickFormContainer } from "../components";
import { QuickFormTokens, defineQuickFormTokens } from "../style/quickFormTokensDefinition";
import { QuickFormDefinition } from "../model";
import { resolveQuickFormService } from "../services/QuickFormServices";
import { kbaQuickFormTokens } from "../style/kbaQuickFormTokens";
import { isFirstQInCurrentSlide } from "../utils/isFirstQuestionInSlide";

type QuickFormProviderProps = {
className?: string,
children: React.ReactNode;
definition: QuickFormDefinition;
tokens?: Partial<QuickFormTokens>;
Expand All @@ -21,7 +19,6 @@ type QuickFormProviderProps = {

export const QuickFormProvider: React.FC<QuickFormProviderProps> = (
{
className,
children,
definition,
payload,
Expand All @@ -34,7 +31,7 @@ export const QuickFormProvider: React.FC<QuickFormProviderProps> = (
const logger = resolveQuickFormService("logger");
const cssVariables = defineQuickFormTokens(tokens ?? {}, definition?.layout?.tokens ?? {});


logger.log("cssVariables", cssVariables);
const transform = resolveQuickFormService("modeltransformer");
const defaultStateObj = useMemo(() => { return defaultState(transform(definition, payload), definition.layout) }, []);
Expand Down
2 changes: 1 addition & 1 deletion packages/designer/src/Hooks/useDocument.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export const useDocument = (entityName: string, attributeName: string, designerL
}
}, [quickformpayload, old, formData, column.logicalName]);

const view = quickformpayload.__designer?.activeView ?? "settings";
const view = quickformpayload.__designer?.activeView ?? "intro";
const activeQuestion = quickformpayload.__designer?.activeQuestion;
const activeSlide = quickformpayload.__designer?.activeSlide;
const setActiveSlide = (slide?: string) => updateQuickFormPayload(old => { if (!old.__designer) { old.__designer = {} }; old.__designer.activeSlide = slide; return { ...old }; });
Expand Down
Loading

0 comments on commit 0e9e0a4

Please sign in to comment.