mirror of
https://github.com/dbgate/dbgate
synced 2024-11-07 20:26:23 +00:00
set filter modal
This commit is contained in:
parent
1c7052810a
commit
bc54564d64
149
packages/web/src/datagrid/DataFilterControl.svelte
Normal file
149
packages/web/src/datagrid/DataFilterControl.svelte
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
<script lang="ts" context="module">
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { showModal } from '../modals/modalTools';
|
||||||
|
import SetFilterModal from '../modals/SetFilterModal.svelte';
|
||||||
|
import keycodes from '../utility/keycodes';
|
||||||
|
|
||||||
|
import DropDownButton from '../widgets/DropDownButton.svelte';
|
||||||
|
|
||||||
|
export let isReadOnly = false;
|
||||||
|
export let filterType;
|
||||||
|
export let filter;
|
||||||
|
export let setFilter;
|
||||||
|
|
||||||
|
let value;
|
||||||
|
|
||||||
|
function openFilterWindow(condition1) {
|
||||||
|
showModal(SetFilterModal, { condition1, filterType, onFilter: setFilter });
|
||||||
|
}
|
||||||
|
|
||||||
|
function createMenu() {
|
||||||
|
switch (filterType) {
|
||||||
|
case 'number':
|
||||||
|
return [
|
||||||
|
{ onClick: () => setFilter(''), text: 'Clear Filter' },
|
||||||
|
{ onClick: () => filterMultipleValues(), text: 'Filter multiple values' },
|
||||||
|
{ onClick: () => openFilterWindow('='), text: 'Equals...' },
|
||||||
|
{ onClick: () => openFilterWindow('['), text: 'Does Not Equal...' },
|
||||||
|
{ onClick: () => setFilter('NULL'), text: 'Is Null' },
|
||||||
|
{ onClick: () => setFilter('NOT NULL'), text: 'Is Not Null' },
|
||||||
|
{ onClick: () => openFilterWindow('>'), text: 'Greater Than...' },
|
||||||
|
{ onClick: () => openFilterWindow('>='), text: 'Greater Than Or Equal To...' },
|
||||||
|
{ onClick: () => openFilterWindow('<'), text: 'Less Than...' },
|
||||||
|
{ onClick: () => openFilterWindow('<='), text: 'Less Than Or Equal To...' },
|
||||||
|
];
|
||||||
|
case 'logical':
|
||||||
|
return [
|
||||||
|
{ onClick: () => setFilter(''), text: 'Clear Filter' },
|
||||||
|
{ onClick: () => filterMultipleValues(), text: 'Filter multiple values' },
|
||||||
|
{ onClick: () => setFilter('NULL'), text: 'Is Null' },
|
||||||
|
{ onClick: () => setFilter('NOT NULL'), text: 'Is Not Null' },
|
||||||
|
{ onClick: () => setFilter('TRUE'), text: 'Is True' },
|
||||||
|
{ onClick: () => setFilter('FALSE'), text: 'Is False' },
|
||||||
|
{ onClick: () => setFilter('TRUE, NULL'), text: 'Is True or NULL' },
|
||||||
|
{ onClick: () => setFilter('FALSE, NULL'), text: 'Is False or NULL' },
|
||||||
|
];
|
||||||
|
case 'datetime':
|
||||||
|
return [
|
||||||
|
{ onClick: () => setFilter(''), text: 'Clear Filter' },
|
||||||
|
{ onClick: () => filterMultipleValues(), text: 'Filter multiple values' },
|
||||||
|
{ onClick: () => setFilter('NULL'), text: 'Is Null' },
|
||||||
|
{ onClick: () => setFilter('NOT NULL'), text: 'Is Not Null' },
|
||||||
|
|
||||||
|
{ divider: true },
|
||||||
|
|
||||||
|
{ onClick: () => openFilterWindow('<='), text: 'Before...' },
|
||||||
|
{ onClick: () => openFilterWindow('>='), text: 'After...' },
|
||||||
|
{ onClick: () => openFilterWindow('>=;<='), text: 'Between...' },
|
||||||
|
|
||||||
|
{ divider: true },
|
||||||
|
|
||||||
|
{ onClick: () => setFilter('TOMORROW'), text: 'Tomorrow' },
|
||||||
|
{ onClick: () => setFilter('TODAY'), text: 'Today' },
|
||||||
|
{ onClick: () => setFilter('YESTERDAY'), text: 'Yesterday' },
|
||||||
|
|
||||||
|
{ divider: true },
|
||||||
|
|
||||||
|
{ onClick: () => setFilter('NEXT WEEK'), text: 'Next Week' },
|
||||||
|
{ onClick: () => setFilter('THIS WEEK'), text: 'This Week' },
|
||||||
|
{ onClick: () => setFilter('LAST WEEK'), text: 'Last Week' },
|
||||||
|
|
||||||
|
{ divider: true },
|
||||||
|
|
||||||
|
{ onClick: () => setFilter('NEXT MONTH'), text: 'Next Month' },
|
||||||
|
{ onClick: () => setFilter('THIS MONTH'), text: 'This Month' },
|
||||||
|
{ onClick: () => setFilter('LAST MONTH'), text: 'Last Month' },
|
||||||
|
|
||||||
|
{ divider: true },
|
||||||
|
|
||||||
|
{ onClick: () => setFilter('NEXT YEAR'), text: 'Next Year' },
|
||||||
|
{ onClick: () => setFilter('THIS YEAR'), text: 'This Year' },
|
||||||
|
{ onClick: () => setFilter('LAST YEAR'), text: 'Last Year' },
|
||||||
|
|
||||||
|
{ divider: true },
|
||||||
|
];
|
||||||
|
case 'string':
|
||||||
|
return [
|
||||||
|
{ onClick: () => setFilter(''), text: 'Clear Filter' },
|
||||||
|
{ onClick: () => filterMultipleValues(), text: 'Filter multiple values' },
|
||||||
|
|
||||||
|
{ onClick: () => openFilterWindow('='), text: 'Equals...' },
|
||||||
|
{ onClick: () => openFilterWindow('['), text: 'Does Not Equal...' },
|
||||||
|
{ onClick: () => setFilter('NULL'), text: 'Is Null' },
|
||||||
|
{ onClick: () => setFilter('NOT NULL'), text: 'Is Not Null' },
|
||||||
|
{ onClick: () => setFilter('EMPTY, NULL'), text: 'Is Empty Or Null' },
|
||||||
|
{ onClick: () => setFilter('NOT EMPTY NOT NULL'), text: 'Has Not Empty Value' },
|
||||||
|
|
||||||
|
{ divider: true },
|
||||||
|
|
||||||
|
{ onClick: () => openFilterWindow('+'), text: 'Contains...' },
|
||||||
|
{ onClick: () => openFilterWindow('~'), text: 'Does Not Contain...' },
|
||||||
|
{ onClick: () => openFilterWindow('^'), text: 'Begins With...' },
|
||||||
|
{ onClick: () => openFilterWindow('!^'), text: 'Does Not Begin With...' },
|
||||||
|
{ onClick: () => openFilterWindow('$'), text: 'Ends With...' },
|
||||||
|
{ onClick: () => openFilterWindow('!$'), text: 'Does Not End With...' },
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// return [
|
||||||
|
// { text: 'Clear filter', onClick: () => (value = '') },
|
||||||
|
// { text: 'Is Null', onClick: () => (value = 'NULL') },
|
||||||
|
// { text: 'Is Not Null', onClick: () => (value = 'NOT NULL') },
|
||||||
|
// ];
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleKeyDown = ev => {
|
||||||
|
if (isReadOnly) return;
|
||||||
|
if (ev.keyCode == keycodes.enter) {
|
||||||
|
setFilter(value);
|
||||||
|
}
|
||||||
|
if (ev.keyCode == keycodes.escape) {
|
||||||
|
setFilter('');
|
||||||
|
}
|
||||||
|
// if (ev.keyCode == keycodes.downArrow) {
|
||||||
|
// if (onFocusGrid) onFocusGrid();
|
||||||
|
// // ev.stopPropagation();
|
||||||
|
// ev.preventDefault();
|
||||||
|
// }
|
||||||
|
// if (ev.keyCode == KeyCodes.DownArrow || ev.keyCode == KeyCodes.UpArrow) {
|
||||||
|
// if (this.props.onControlKey) this.props.onControlKey(ev.keyCode);
|
||||||
|
// }
|
||||||
|
};
|
||||||
|
|
||||||
|
$: value = filter;
|
||||||
|
// $: if (value != filter) setFilter(value);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="flex">
|
||||||
|
<input type="text" readOnly={isReadOnly} bind:value on:keydown={handleKeyDown} />
|
||||||
|
<DropDownButton icon="icon filter" menu={createMenu} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
input {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
@ -45,6 +45,7 @@
|
|||||||
import registerCommand from '../commands/registerCommand';
|
import registerCommand from '../commands/registerCommand';
|
||||||
import ColumnHeaderControl from './ColumnHeaderControl.svelte';
|
import ColumnHeaderControl from './ColumnHeaderControl.svelte';
|
||||||
import DataGridRow from './DataGridRow.svelte';
|
import DataGridRow from './DataGridRow.svelte';
|
||||||
|
import { getFilterType, getFilterValueExpression } from 'dbgate-filterparser';
|
||||||
import {
|
import {
|
||||||
cellIsSelected,
|
cellIsSelected,
|
||||||
countColumnSizes,
|
countColumnSizes,
|
||||||
@ -56,6 +57,9 @@
|
|||||||
import { cellFromEvent, emptyCellArray, getCellRange, isRegularCell, nullCell, topLeftCell } from './selection';
|
import { cellFromEvent, emptyCellArray, getCellRange, isRegularCell, nullCell, topLeftCell } from './selection';
|
||||||
import VerticalScrollBar from './VerticalScrollBar.svelte';
|
import VerticalScrollBar from './VerticalScrollBar.svelte';
|
||||||
import LoadingInfo from '../widgets/LoadingInfo.svelte';
|
import LoadingInfo from '../widgets/LoadingInfo.svelte';
|
||||||
|
import InlineButton from '../widgets/InlineButton.svelte';
|
||||||
|
import FontIcon from '../icons/FontIcon.svelte';
|
||||||
|
import DataFilterControl from './DataFilterControl.svelte';
|
||||||
|
|
||||||
export let loadNextData = undefined;
|
export let loadNextData = undefined;
|
||||||
export let grider = undefined;
|
export let grider = undefined;
|
||||||
@ -296,6 +300,36 @@
|
|||||||
</td>
|
</td>
|
||||||
{/each}
|
{/each}
|
||||||
</tr>
|
</tr>
|
||||||
|
{#if display.filterable}
|
||||||
|
<tr>
|
||||||
|
<td
|
||||||
|
class="header-cell"
|
||||||
|
data-row="filter"
|
||||||
|
data-col="header"
|
||||||
|
style={`width:${headerColWidth}px; min-width:${headerColWidth}px; max-width:${headerColWidth}px`}
|
||||||
|
>
|
||||||
|
{#if display.filterCount > 0}
|
||||||
|
<InlineButton on:click={() => display.clearFilters()} square>
|
||||||
|
<FontIcon icon="icon filter-off" />
|
||||||
|
</InlineButton>
|
||||||
|
{/if}
|
||||||
|
</td>
|
||||||
|
{#each visibleRealColumns as col (col.uniqueName)}
|
||||||
|
<td
|
||||||
|
class="filter-cell"
|
||||||
|
data-row="filter"
|
||||||
|
data-col={col.colIndex}
|
||||||
|
style={`width:${col.width}px; min-width:${col.width}px; max-width:${col.width}px`}
|
||||||
|
>
|
||||||
|
<DataFilterControl
|
||||||
|
filterType={getFilterType(col.dataType)}
|
||||||
|
filter={display.getFilter(col.uniqueName)}
|
||||||
|
setFilter={value => display.setFilter(col.uniqueName, value)}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
{/each}
|
||||||
|
</tr>
|
||||||
|
{/if}
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{#each _.range(firstVisibleRowScrollIndex, Math.min(firstVisibleRowScrollIndex + visibleRowCountUpperBound, grider.rowCount)) as rowIndex (rowIndex)}
|
{#each _.range(firstVisibleRowScrollIndex, Math.min(firstVisibleRowScrollIndex + visibleRowCountUpperBound, grider.rowCount)) as rowIndex (rowIndex)}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { getFormContext } from './FormProviderCore.svelte';
|
import { getFormContext } from './FormProviderCore.svelte';
|
||||||
import FromCheckboxFieldRaw from './FromCheckboxFieldRaw.svelte';
|
import FormCheckboxFieldRaw from './FormCheckboxFieldRaw.svelte';
|
||||||
|
|
||||||
export let label;
|
export let label;
|
||||||
export let name;
|
export let name;
|
||||||
@ -18,5 +18,5 @@
|
|||||||
{...templateProps}
|
{...templateProps}
|
||||||
labelProps={disabled ? { disabled: true } : { onClick: () => setFieldValue(name, !$values[name]) }}
|
labelProps={disabled ? { disabled: true } : { onClick: () => setFieldValue(name, !$values[name]) }}
|
||||||
>
|
>
|
||||||
<FromCheckboxFieldRaw {name} {...$$restProps} {disabled} />
|
<FormCheckboxFieldRaw {name} {...$$restProps} {disabled} />
|
||||||
</svelte:component>
|
</svelte:component>
|
||||||
|
19
packages/web/src/forms/FormRadioGroupItem.svelte
Normal file
19
packages/web/src/forms/FormRadioGroupItem.svelte
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { getFormContext } from './FormProviderCore.svelte';
|
||||||
|
|
||||||
|
export let name;
|
||||||
|
export let value;
|
||||||
|
export let text;
|
||||||
|
|
||||||
|
const { values, setFieldValue } = getFormContext();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<input
|
||||||
|
type="radio"
|
||||||
|
{name}
|
||||||
|
checked={$values[name] == value}
|
||||||
|
on:click={() => setFieldValue(name, value)}
|
||||||
|
/>
|
||||||
|
<span on:click={() => setFieldValue(name, value)}>{text}</span>
|
||||||
|
</div>
|
@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { getFormContext } from './FormProviderCore.svelte';
|
import { getFormContext } from './FormProviderCore.svelte';
|
||||||
import FromSelectFieldRaw from './FromSelectFieldRaw.svelte';
|
import FormSelectFieldRaw from './FormSelectFieldRaw.svelte';
|
||||||
|
|
||||||
export let label;
|
export let label;
|
||||||
export let name;
|
export let name;
|
||||||
@ -10,5 +10,5 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:component this={template} type="select" {label} {...templateProps}>
|
<svelte:component this={template} type="select" {label} {...templateProps}>
|
||||||
<FromSelectFieldRaw {name} {...$$restProps} />
|
<FormSelectFieldRaw {name} {...$$restProps} />
|
||||||
</svelte:component>
|
</svelte:component>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { getFormContext } from './FormProviderCore.svelte';
|
import { getFormContext } from './FormProviderCore.svelte';
|
||||||
import FromTextFieldRaw from './FromTextFieldRaw.svelte';
|
import FormTextFieldRaw from './FormTextFieldRaw.svelte';
|
||||||
|
|
||||||
export let label;
|
export let label;
|
||||||
export let name;
|
export let name;
|
||||||
@ -11,5 +11,5 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:component this={template} type="text" {label} {...templateProps}>
|
<svelte:component this={template} type="text" {label} {...templateProps}>
|
||||||
<FromTextFieldRaw {name} {...$$restProps} {focused} />
|
<FormTextFieldRaw {name} {...$$restProps} {focused} />
|
||||||
</svelte:component>
|
</svelte:component>
|
||||||
|
@ -7,4 +7,4 @@
|
|||||||
const { values, setFieldValue } = getFormContext();
|
const { values, setFieldValue } = getFormContext();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<TextField {...$$restProps} value={$values[name]} on:change={e => setFieldValue(name, e.target['value'])} />
|
<TextField {...$$restProps} value={$values[name]} on:input={e => setFieldValue(name, e.target['value'])} />
|
@ -9,4 +9,4 @@
|
|||||||
if (focused) onMount(() => domEditor.focus());
|
if (focused) onMount(() => domEditor.focus());
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<input type="text" {...$$restProps} bind:value on:change bind:this={domEditor} />
|
<input type="text" {...$$restProps} bind:value on:change on:input bind:this={domEditor} />
|
||||||
|
@ -12,10 +12,9 @@
|
|||||||
import FormFieldTemplateLarge from './FormFieldTemplateLarge.svelte';
|
import FormFieldTemplateLarge from './FormFieldTemplateLarge.svelte';
|
||||||
|
|
||||||
import ModalBase from './ModalBase.svelte';
|
import ModalBase from './ModalBase.svelte';
|
||||||
import { closeModal } from './modalTools';
|
import { closeCurrentModal, closeModal } from './modalTools';
|
||||||
|
|
||||||
export let connection;
|
export let connection;
|
||||||
export let modalId;
|
|
||||||
|
|
||||||
let isTesting;
|
let isTesting;
|
||||||
let sqlConnectResult;
|
let sqlConnectResult;
|
||||||
@ -40,7 +39,7 @@
|
|||||||
|
|
||||||
async function handleSubmit(e) {
|
async function handleSubmit(e) {
|
||||||
axios.post('connections/save', e.detail);
|
axios.post('connections/save', e.detail);
|
||||||
closeModal(modalId);
|
closeCurrentModal();
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -48,7 +47,7 @@
|
|||||||
template={FormFieldTemplateLarge}
|
template={FormFieldTemplateLarge}
|
||||||
initialValues={connection || { server: 'localhost', engine: 'mssql@dbgate-plugin-mssql' }}
|
initialValues={connection || { server: 'localhost', engine: 'mssql@dbgate-plugin-mssql' }}
|
||||||
>
|
>
|
||||||
<ModalBase {...$$restProps} {modalId} noPadding>
|
<ModalBase {...$$restProps} noPadding>
|
||||||
<div slot="header">Add connection</div>
|
<div slot="header">Add connection</div>
|
||||||
|
|
||||||
<TabControl
|
<TabControl
|
||||||
|
77
packages/web/src/modals/SetFilterModal.svelte
Normal file
77
packages/web/src/modals/SetFilterModal.svelte
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import FormButton from '../forms/FormButton.svelte';
|
||||||
|
|
||||||
|
import FormProvider from '../forms/FormProvider.svelte';
|
||||||
|
import FormSubmit from '../forms/FormSubmit.svelte';
|
||||||
|
import FormTextFieldRaw from '../forms/FormTextFieldRaw.svelte';
|
||||||
|
import FormFieldTemplateLarge from './FormFieldTemplateLarge.svelte';
|
||||||
|
import SetFilterModal_Select from './SetFilterModal_Select.svelte';
|
||||||
|
import ModalBase from './ModalBase.svelte';
|
||||||
|
import { closeCurrentModal } from './modalTools';
|
||||||
|
import FormRadioGroupItem from '../forms/FormRadioGroupItem.svelte';
|
||||||
|
|
||||||
|
export let condition1;
|
||||||
|
export let onFilter;
|
||||||
|
export let filterType;
|
||||||
|
|
||||||
|
const createTerm = (condition, value) => {
|
||||||
|
if (!value) return null;
|
||||||
|
if (filterType == 'string') return `${condition}"${value}"`;
|
||||||
|
return `${condition}${value}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleOk = e => {
|
||||||
|
const values = e.detail;
|
||||||
|
const { value1, condition1, value2, condition2, joinOperator } = values;
|
||||||
|
const term1 = createTerm(condition1, value1);
|
||||||
|
const term2 = createTerm(condition2, value2);
|
||||||
|
if (term1 && term2) onFilter(`${term1}${joinOperator}${term2}`);
|
||||||
|
else if (term1) onFilter(term1);
|
||||||
|
else if (term2) onFilter(term2);
|
||||||
|
closeCurrentModal();
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<FormProvider initialValues={{ condition1, condition2: '=', joinOperator: ' ' }} template={FormFieldTemplateLarge}>
|
||||||
|
<ModalBase {...$$restProps}>
|
||||||
|
<div slot="header">Set filter</div>
|
||||||
|
|
||||||
|
<div class="largeFormMarker">
|
||||||
|
<div class="row">Show rows where</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-6 mr-1">
|
||||||
|
<SetFilterModal_Select {filterType} name="condition1" />
|
||||||
|
</div>
|
||||||
|
<div class="col-6 mr-1">
|
||||||
|
<FormTextFieldRaw name="value1" focused />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<FormRadioGroupItem name="joinOperator" value=" " text="And" />
|
||||||
|
<FormRadioGroupItem name="joinOperator" value="," text="Or" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-6 mr-1">
|
||||||
|
<SetFilterModal_Select {filterType} name="condition2" />
|
||||||
|
</div>
|
||||||
|
<div class="col-6 mr-1">
|
||||||
|
<FormTextFieldRaw name="value2" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div slot="footer">
|
||||||
|
<FormSubmit value="OK" on:click={handleOk} />
|
||||||
|
<FormButton type="button" value="Close" on:click={closeCurrentModal} />
|
||||||
|
</div>
|
||||||
|
</ModalBase>
|
||||||
|
</FormProvider>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.row {
|
||||||
|
margin: var(--dim-large-form-margin);
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
</style>
|
46
packages/web/src/modals/SetFilterModal_Select.svelte
Normal file
46
packages/web/src/modals/SetFilterModal_Select.svelte
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import FormSelectFieldRaw from '../forms/FormSelectFieldRaw.svelte';
|
||||||
|
|
||||||
|
export let name;
|
||||||
|
export let filterType;
|
||||||
|
|
||||||
|
function getOptions() {
|
||||||
|
switch (filterType) {
|
||||||
|
case 'number':
|
||||||
|
return [
|
||||||
|
{ value: '=', label: 'eqals' },
|
||||||
|
{ value: '<>', label: 'does not equal' },
|
||||||
|
{ value: '<', label: 'is smaller' },
|
||||||
|
{ value: '>', label: 'is greater' },
|
||||||
|
{ value: '<=', label: 'is smaller or equal' },
|
||||||
|
{ value: '>=', label: 'is greater or equal' },
|
||||||
|
];
|
||||||
|
case 'string':
|
||||||
|
return [
|
||||||
|
{ value: '+', label: 'contains' },
|
||||||
|
{ value: '~', label: 'does not contain' },
|
||||||
|
{ value: '^', label: 'begins with' },
|
||||||
|
{ value: '!^', label: 'does not begin with' },
|
||||||
|
{ value: '$', label: 'ends with' },
|
||||||
|
{ value: '!$', label: 'does not end with' },
|
||||||
|
{ value: '=', label: 'equals' },
|
||||||
|
{ value: '<>', label: 'does not equal' },
|
||||||
|
{ value: '<', label: 'is smaller' },
|
||||||
|
{ value: '>', label: 'is greater' },
|
||||||
|
{ value: '<=', label: 'is smaller or equal' },
|
||||||
|
{ value: '>=', label: 'is greater or equal' },
|
||||||
|
];
|
||||||
|
case 'datetime':
|
||||||
|
return [
|
||||||
|
{ value: '=', label: 'eqals' },
|
||||||
|
{ value: '<>', label: 'does not equal' },
|
||||||
|
{ value: '<', label: 'is before' },
|
||||||
|
{ value: '>', label: 'is after' },
|
||||||
|
{ value: '<=', label: 'is before or equal' },
|
||||||
|
{ value: '>=', label: 'is after or equal' },
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<FormSelectFieldRaw {name} options={getOptions()} />
|
@ -1,5 +1,6 @@
|
|||||||
import { openedModals } from '../stores';
|
import { openedModals } from '../stores';
|
||||||
import uuidv1 from 'uuid/v1';
|
import uuidv1 from 'uuid/v1';
|
||||||
|
import _ from 'lodash';
|
||||||
|
|
||||||
export function showModal(component, props = {}) {
|
export function showModal(component, props = {}) {
|
||||||
const modalId = uuidv1();
|
const modalId = uuidv1();
|
||||||
@ -9,3 +10,7 @@ export function showModal(component, props = {}) {
|
|||||||
export function closeModal(modalId) {
|
export function closeModal(modalId) {
|
||||||
openedModals.update(x => x.filter(y => y.modalId != modalId));
|
openedModals.update(x => x.filter(y => y.modalId != modalId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function closeCurrentModal() {
|
||||||
|
openedModals.update(x => _.dropRight(x));
|
||||||
|
}
|
||||||
|
@ -1,8 +1,22 @@
|
|||||||
<script>
|
<script lang="ts">
|
||||||
|
import _ from 'lodash';
|
||||||
|
|
||||||
import FontIcon from '../icons/FontIcon.svelte';
|
import FontIcon from '../icons/FontIcon.svelte';
|
||||||
|
import { currentDropDownMenu } from '../stores';
|
||||||
import InlineButton from './InlineButton.svelte';
|
import InlineButton from './InlineButton.svelte';
|
||||||
|
|
||||||
|
export let icon = 'icon chevron-down';
|
||||||
|
export let menu;
|
||||||
|
let domButton;
|
||||||
|
|
||||||
|
function handleClick() {
|
||||||
|
const rect = domButton.getBoundingClientRect();
|
||||||
|
const left = rect.left;
|
||||||
|
const top = rect.bottom;
|
||||||
|
currentDropDownMenu.set({ left, top, items: _.isFunction(menu) ? menu() : menu });
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<InlineButton square>
|
<InlineButton square on:click={handleClick} bind:this={domButton}>
|
||||||
<FontIcon icon="icon chevron-down" />
|
<FontIcon {icon} />
|
||||||
</InlineButton>
|
</InlineButton>
|
||||||
|
@ -1,9 +1,15 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
export let disabled = false;
|
export let disabled = false;
|
||||||
export let square = false;
|
export let square = false;
|
||||||
|
|
||||||
|
let domButton;
|
||||||
|
|
||||||
|
export function getBoundingClientRect() {
|
||||||
|
return domButton.getBoundingClientRect();
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="outer buttonLike" class:disabled class:square on:click>
|
<div class="outer buttonLike" class:disabled class:square on:click bind:this={domButton}>
|
||||||
<div class="inner">
|
<div class="inner">
|
||||||
<slot />
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
@ -41,7 +47,6 @@
|
|||||||
background-color: var(--bg-2);
|
background-color: var(--bg-2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.inner {
|
.inner {
|
||||||
margin: auto;
|
margin: auto;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
Loading…
Reference in New Issue
Block a user