Skip to content
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

feat: setup CoreTimeInput. WF-8 #483

Merged
merged 1 commit into from
Jul 8, 2024
Merged
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
Binary file added docs/framework/public/components/timeinput.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions src/ui/src/core/templateMap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import CoreSelectInput from "../core_components/input/CoreSelectInput.vue";
import CoreSliderInput from "../core_components/input/CoreSliderInput.vue";
import CoreTextInput from "../core_components/input/CoreTextInput.vue";
import CoreTextareaInput from "../core_components/input/CoreTextareaInput.vue";
import CoreTimeInput from "../core_components/input/CoreTimeInput.vue";
import CoreRating from "../core_components/input/CoreRatingInput.vue";
import CoreSwitchInput from "../core_components/input/CoreSwitchInput.vue";
// layout
Expand Down Expand Up @@ -93,6 +94,7 @@ const templateMap = {
numberinput: CoreNumberInput,
sliderinput: CoreSliderInput,
dateinput: CoreDateInput,
timeinput: CoreTimeInput,
radioinput: CoreRadioInput,
checkboxinput: CoreCheckboxInput,
dropdowninput: CoreDropdownInput,
Expand Down
100 changes: 100 additions & 0 deletions src/ui/src/core_components/input/CoreTimeInput.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
<template>
<BaseInputWrapper
ref="rootInstance"
:label="fields.label.value"
class="CoreTimeInput"
>
<input
type="time"
:value="formValue"
@change="
($event) =>
handleInput(
($event.target as HTMLInputElement).value,
'wf-time-change',
)
"
/>
</BaseInputWrapper>
</template>

<script lang="ts">
import { ComponentPublicInstance } from "vue";
import { cssClasses } from "../../renderer/sharedStyleFields";
import { FieldType } from "../../writerTypes";
import BaseInputWrapper from "../base/BaseInputWrapper.vue";

const description =
"A user input component that allows users to select a time.";

const onChangeHandlerStub = `
def onchange_handler(state, payload):

# Set the state variable "new_time" to the new value, provided as a hh:mm string (in 24-hour format that includes leading zeros).

state["new_time"] = payload`;

export default {
writer: {
name: "Time Input",
description,
category: "Input",
fields: {
label: {
name: "Label",
init: "Input Label",
type: FieldType.Text,
},
cssClasses,
},
events: {
"wf-time-change": {
desc: "Capture changes to this control.",
stub: onChangeHandlerStub,
bindable: true,
},
},
},
};
</script>
<script setup lang="ts">
import { inject, ref } from "vue";
import injectionKeys from "../../injectionKeys";
import { useFormValueBroker } from "../../renderer/useFormValueBroker";

const fields = inject(injectionKeys.evaluatedFields);
const rootInstance = ref<ComponentPublicInstance | null>(null);
const wf = inject(injectionKeys.core);
const instancePath = inject(injectionKeys.instancePath);

const { formValue, handleInput } = useFormValueBroker(
wf,
instancePath,
rootInstance,
);
</script>

<style scoped>
@import "../../renderer/sharedStyles.css";
@import "../../renderer/colorTransformations.css";

.CoreTimeInput {
width: fit-content;
}

input {
width: 100%;
max-width: 20ch;
margin: 0;
border: 1px solid var(--separatorColor);
border-radius: 8px;
padding: 8.5px 12px 8.5px 12px;
font-size: 0.875rem;
outline: none;
}

input:focus {
border: 1px solid var(--softenedAccentColor);
box-shadow: 0px 0px 0px 3px rgba(81, 31, 255, 0.05);
}
</style>
13 changes: 13 additions & 0 deletions src/writer/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -1053,6 +1053,19 @@ def _transform_date_change(self, ev) -> str:

return payload

def _transform_time_change(self, ev) -> str:
payload = ev.payload

if not isinstance(payload, str):
raise ValueError("Time must be a string.")
try:
time.strptime(payload, '%H:%M')
except ValueError:
raise ValueError(
"Time must be in hh:mm format (in 24-hour format that includes leading zeros).")

return payload

def _transform_change_page_size(self, ev) -> Optional[int]:
try:
return int(ev.payload)
Expand Down
17 changes: 17 additions & 0 deletions tests/backend/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -595,6 +595,23 @@ def test_date_change(self) -> None:
self.ed.transform(ev_valid)
assert ev_valid.payload == "2019-11-23"

def test_time_change(self) -> None:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

ev_invalid = WriterEvent(
type="wf-time-change",
instancePath=self.root_instance_path,
payload="virus"
)
with pytest.raises(RuntimeError):
self.ed.transform(ev_invalid)

ev_valid = WriterEvent(
type="wf-time-change",
instancePath=self.root_instance_path,
payload="23:59"
)
self.ed.transform(ev_valid)
assert ev_valid.payload == "23:59"


class TestFileWrapper():

Expand Down
1 change: 1 addition & 0 deletions tests/e2e/tests/components.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const mapComponents = {
sidebar: {test: 'basic'},
fileinput: {locator: '.component.wf-type-fileinput label'},
dateinput: {locator: '.component.wf-type-dateinput label'},
timeinput: {locator: '.component.wf-type-timeinput label'},
sliderinput: {locator: '.component.wf-type-sliderinput label'},
numberinput: {locator: '.component.wf-type-numberinput label'},
textinput: {locator: '.component.wf-type-textinput label'},
Expand Down
Loading