Skip to content
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
7 changes: 7 additions & 0 deletions .changeset/yummy-keys-hear.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@milaboratories/milaboratories.ui-examples.ui": patch
"@milaboratories/uikit": patch
"@platforma-sdk/ui-vue": patch
---

add helper with tooltip for table fast search
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
PlAccordion,
PlAccordionSection,
PlDropdownMulti,
PlSearchField,
} from "@platforma-sdk/ui-vue";
import { reactive } from "vue";

Expand Down Expand Up @@ -53,6 +54,11 @@ const options = listToOptions([
<PlCheckbox v-model="data.compactBtnGroup">Compact btn group component</PlCheckbox>
<PlTextField v-model="data.text" label="PlTextField" clearable />
<PlTextField v-model="data.text" label="PlTextField (password)" type="password" clearable />
<PlSearchField v-model="data.text">
<template #helper>
Helper text for search field. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</template>
</PlSearchField>
<PlDropdown v-model="data.single" label="PlDropdown" :options="options" />
<PlDropdownMulti v-model="data.multiple" label="PlDropdownMulti" :options="options" />
<PlDropdownMulti
Expand Down
39 changes: 22 additions & 17 deletions lib/ui/uikit/src/components/PlSearchField/PlSearchField.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,47 +2,52 @@
import { PlIcon16 } from "../PlIcon16";
import { PlIcon24 } from "../PlIcon24";
import { computed } from "vue";
import PlTooltip from "../PlTooltip/PlTooltip.vue";

const emit = defineEmits(["update:modelValue"]);
const model = defineModel<string>({ required: true });

const props = defineProps<{
modelValue?: string;
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The modelValue prop is redundant since defineModel is being used. It should be removed to avoid confusion and potential conflicts.

  clearable?: boolean;

clearable?: boolean;
placeholder?: string;
disabled?: boolean;
helper?: string;
}>();
const slots = defineSlots<{
helper: () => unknown;
}>();

const value = computed({
get() {
return props.modelValue ?? "";
},
set(v) {
emit("update:modelValue", v);
},
});

const nonEmpty = computed(() => !!props.modelValue);
const nonEmpty = computed(() => model.value != null && model.value.length > 0);
const hasHelper = computed(() => props.helper != null || slots.helper != null);

const clear = () => emit("update:modelValue", "");
const clear = () => (model.value = "");
</script>

<template>
<div ref="root" class="pl-search-field" :class="[$style.component]">
<div ref="root" :class="$style.component">
<PlIcon24 name="search" />
<input
ref="input"
v-model="value"
:disabled="disabled"
:placeholder="placeholder || 'Find...'"
v-model="model"
:disabled="props.disabled"
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The v-model binding should be to model directly, as value computed property is no longer needed with defineModel.

      v-model="model"

:placeholder="props.placeholder || 'Find...'"
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

When using props in the template, it's good practice to explicitly use props.disabled for clarity, even though it might work implicitly.

      :disabled="props.disabled"

type="text"
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

When using props in the template, it's good practice to explicitly use props.placeholder for clarity, even though it might work implicitly.

      :placeholder="props.placeholder || 'Find...'"

spellcheck="false"
/>
<PlIcon16
v-if="clearable && nonEmpty"
v-if="props.clearable && nonEmpty"
:class="$style.clear"
name="delete-clear"
@click.stop="clear"
/>

<PlTooltip v-if="hasHelper" class="info" position="bottom">
<template #tooltip>
<slot name="helper">
{{ props.helper }}
</slot>
</template>
</PlTooltip>
</div>
</template>

Expand Down
10 changes: 5 additions & 5 deletions lib/ui/uikit/src/components/PlTooltip/PlTooltip.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ export default {
</script>

<script lang="ts" setup>
import { uniqueId } from "@milaboratories/helpers";
import { onUnmounted, reactive, ref, watch } from "vue";
import { tMap } from "./global";
import * as utils from "../../helpers/utils";
import { useClickOutside } from "../../composition/useClickOutside";
import { tMap } from "./global";
import { uniqueId } from "@milaboratories/helpers";

const emit = defineEmits(["tooltip:close"]);

Expand Down Expand Up @@ -189,7 +189,7 @@ const anchorName = `--anchor-${uniqueId()}`;
'--anchorName': anchorName,
'--gap': gap + 'px',
'--offsetToTheEdge': offsetToTheEdge + 'px',
'--pl-tooltip-max-width': maxWidth,
'--plTooltipMaxWidth': maxWidth,
}"
>
<div :class="$style.plTooltipBox" @click.stop>
Expand Down Expand Up @@ -226,7 +226,7 @@ const anchorName = `--anchor-${uniqueId()}`;
}

.plTooltipContainer {
--pl-tooltip-max-width: 300px;
--plTooltipMaxWidth: 300px;
--gap: 8px;
--tailWidth: 8px;
--tailHeight: calc(var(--gap) + 2px);
Expand All @@ -252,7 +252,7 @@ const anchorName = `--anchor-${uniqueId()}`;
border-radius: 6px;
width: max-content;
word-break: normal;
max-width: var(--pl-tooltip-max-width);
max-width: var(--plTooltipMaxWidth);
color: #fff;
}

Expand Down
49 changes: 30 additions & 19 deletions sdk/ui-vue/src/components/PlTableFastSearch/PlTableFastSearch.vue
Original file line number Diff line number Diff line change
@@ -1,27 +1,38 @@
<script lang="ts" setup>
import { PlSearchField } from "@milaboratories/uikit";
import { ref, watch } from "vue";
import { useDebounceFn } from "@vueuse/core";

const model = defineModel<string>({ required: true });
Comment on lines 3 to 4
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The ref and useDebounceFn imports are no longer used after the refactoring. They should be removed to keep the code clean and avoid unused imports.


const localValue = ref(model.value ?? "");

const emitDebounced = useDebounceFn((value: string) => {
model.value = value;
}, 300);

watch(localValue, (value) => {
emitDebounced(value);
});

watch(model, (value) => {
if (value !== localValue.value) {
localValue.value = value ?? "";
}
});
</script>

<template>
<PlSearchField v-model="localValue" clearable placeholder="Search..." />
<PlSearchField v-model="model" clearable placeholder="Search...">
<template #helper>
<b>How table search works:</b>
<br />
<ul>
<li>
<b>Exact match only.</b><br />
No partials, wildcards, ranges, or regex.
</li>
<li>
<b>Scope:</b> Searches all visible columns. To include a column, make it visible in
Columns.
</li>
<li>
<b>Text columns:</b> Exact string equality. Characters must match exactly (including case,
Comment on lines 6 to +22
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The localValue, emitDebounced, and watch logic is no longer needed. The defineModel function in PlSearchField handles the debouncing internally, making this code redundant. Removing it simplifies the component.

spaces, and punctuation).
</li>
<li>
<b>Number columns:</b> Exact numeric equality. 71 matches 71 and 71.0; it does not match
715 or 0.71/0.85.
</li>
</ul>
<b>Examples:</b>
<br />
<ul>
<li>CASSLDRGTEAFF → shows rows where any visible column equals that full string.</li>
<li>85 → matches 85 / 85.0, not 0.85 or 850.</li>
</ul>
</template>
</PlSearchField>
</template>