Skip to content

Commit

Permalink
chore: step 6
Browse files Browse the repository at this point in the history
  • Loading branch information
ssiyad committed Nov 6, 2023
1 parent bbe4b47 commit d4ec5e7
Show file tree
Hide file tree
Showing 6 changed files with 449 additions and 178 deletions.
296 changes: 161 additions & 135 deletions desk/src/components/FilterPopover.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,176 +5,202 @@
<template #prefix>
<LucideListFilter class="h-4 w-4" />
</template>
<template v-if="storage.size" #suffix>
<Badge :label="storage.size" theme="gray" variant="subtle" />
<template v-if="resource.filters" #suffix>
<Badge
:label="Object.keys(resource.filters).length"
theme="gray"
variant="subtle"
/>
</template>
</Button>
</template>
<template #body="{ close }">
<div class="my-2 rounded bg-white shadow">
<div class="min-w-[400px] p-2">
<div class="my-2 rounded-lg bg-white shadow-lg">
<div class="min-w-[300px] space-y-2 p-2">
<div
v-for="(f, i) in storage"
v-if="storage.size"
id="filter-list"
:key="i"
class="mb-3 flex items-center justify-between gap-2"
v-for="(v, f) in resource.filters"
:key="f"
:set="
(m = metaState[doctype]?.fields.find((_f) => _f.fieldname === f))
"
>
<div class="flex items-center gap-2">
<div class="w-13 pl-2 text-end text-base text-gray-600">
{{ i == 0 ? "Where" : "And" }}
</div>
<div id="fieldname" class="!min-w-[140px]">
<Autocomplete
:value="f.field.fieldname"
:options="fields"
placeholder="Filter by..."
@change="(e) => updateFilter(e, i)"
/>
</div>
<div id="operator">
<div v-if="m" class="flex items-center gap-2">
<div class="!w-[140px]">
<FormControl
v-model="f.operator"
type="select"
:options="getOperators(f.field.fieldtype)"
placeholder="Operator"
:value="m.label"
:model-value="m.label"
:options="fields"
placeholder="Filter by..."
/>
</div>
<div id="value" class="!min-w-[140px]">
<div class="text-base">is</div>
<div class="!w-[140px]">
<SearchComplete
v-if="typeLink.includes(f.field.fieldtype)"
:doctype="f.field.options"
:value="f.value"
v-if="typeLink.includes(m.fieldtype)"
placeholder="Value"
@change="(v) => (f.value = v.value)"
:doctype="m.options"
:value="v"
@change="(val) => (resource.filters[f] = val.value)"

Check failure on line 44 in desk/src/components/FilterPopover.vue

View workflow job for this annotation

GitHub Actions / ESLint - Reviewdog

[eslint] reported by reviewdog 🐶 Unexpected mutation of "resource" prop. Raw Output: {"ruleId":"vue/no-mutating-props","severity":2,"message":"Unexpected mutation of \"resource\" prop.","line":44,"column":38,"nodeType":"AssignmentExpression","endLine":44,"endColumn":69}
/>
<component
:is="getValSelect(f.field.fieldtype, f.field.options)"
:is="getValSelect(m.fieldtype, m.options)"
v-else
v-model="f.value"
placeholder="Value"
:model-value="v"
@update:model-value="(val) => (resource.filters[f] = val)"

Check failure on line 51 in desk/src/components/FilterPopover.vue

View workflow job for this annotation

GitHub Actions / ESLint - Reviewdog

[eslint] reported by reviewdog 🐶 Unexpected mutation of "resource" prop. Raw Output: {"ruleId":"vue/no-mutating-props","severity":2,"message":"Unexpected mutation of \"resource\" prop.","line":51,"column":50,"nodeType":"AssignmentExpression","endLine":51,"endColumn":75}
/>
</div>
<Button
variant="subtle"
@click="() => delete resource.filters[f]"

Check failure on line 56 in desk/src/components/FilterPopover.vue

View workflow job for this annotation

GitHub Actions / ESLint - Reviewdog

[eslint] reported by reviewdog 🐶 Unexpected mutation of "resource" prop. Raw Output: {"ruleId":"vue/no-mutating-props","severity":2,"message":"Unexpected mutation of \"resource\" prop.","line":56,"column":31,"nodeType":"UnaryExpression","endLine":56,"endColumn":57}
>
<template #icon>
<LucideX class="h-4 w-4" />
</template>
</Button>
</div>
<Button variant="ghost" icon="x" @click="removeFilter(i)" />
</div>
<div
v-else
class="mb-3 flex h-7 items-center px-3 text-sm text-gray-600"
>
Empty - Choose a field to filter by
</div>
<div class="flex items-center justify-between gap-2">
<div class="flex items-center justify-end gap-2">
<Button variant="subtle" @click="() => resource.fetch()">
<template #icon>
<LucideCheck class="h-4 w-4" />
</template>
</Button>
<Autocomplete
value=""
:options="fields"
:options="[]"
placeholder="Filter by..."
@change="(e) => setfilter(e)"
>
<template #target="{ togglePopover }">
<Button
class="!text-gray-600"
variant="ghost"
label="Add filter"
@click="() => togglePopover()"
>
<template #prefix>
<Button variant="subtle" @click="() => togglePopover()">
<template #icon>
<LucidePlus class="h-4 w-4" />
</template>
</Button>
</template>
</Autocomplete>
<Button
v-if="storage.size"
class="!text-gray-600"
variant="ghost"
label="Clear all filter"
@click="() => clearfilter(close)"
/>
variant="subtle"
@click="
() => {
resource.filters = undefined;

Check failure on line 88 in desk/src/components/FilterPopover.vue

View workflow job for this annotation

GitHub Actions / ESLint - Reviewdog

[eslint] reported by reviewdog 🐶 Unexpected mutation of "resource" prop. Raw Output: {"ruleId":"vue/no-mutating-props","severity":2,"message":"Unexpected mutation of \"resource\" prop.","line":88,"column":19,"nodeType":"AssignmentExpression","endLine":88,"endColumn":47}
resource.fetch();
}
"
>
<template #icon>
<LucideX class="h-4 w-4" />
</template>
</Button>
<!-- <Button -->
<!-- v-if="storage.size" -->
<!-- class="!text-gray-600" -->
<!-- variant="ghost" -->
<!-- label="Clear all filter" -->
<!-- @click="() => clearfilter(close)" -->
<!-- /> -->
</div>
</div>
</div>
</template>
</NestedPopover>
</template>
<script setup>
import { h, watch } from "vue";
import { Badge, Autocomplete, FormControl } from "frappe-ui";
import { useDebounceFn } from "@vueuse/core";
import { useFilter } from "@/composables/filter";
import { NestedPopover, SearchComplete } from "@/components";
<script setup lang="ts">
import { computed, h, watch } from 'vue';

Check warning on line 111 in desk/src/components/FilterPopover.vue

View workflow job for this annotation

GitHub Actions / ESLint - Reviewdog

[eslint] reported by reviewdog 🐶 'watch' is defined but never used. Raw Output: {"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'watch' is defined but never used.","line":111,"column":23,"nodeType":"Identifier","messageId":"unusedVar","endLine":111,"endColumn":28}
import { Autocomplete, Badge, Dropdown, FormControl } from 'frappe-ui';

Check warning on line 112 in desk/src/components/FilterPopover.vue

View workflow job for this annotation

GitHub Actions / ESLint - Reviewdog

[eslint] reported by reviewdog 🐶 'Dropdown' is defined but never used. Raw Output: {"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'Dropdown' is defined but never used.","line":112,"column":31,"nodeType":"Identifier","messageId":"unusedVar","endLine":112,"endColumn":39}
import { useDebounceFn } from '@vueuse/core';

Check warning on line 113 in desk/src/components/FilterPopover.vue

View workflow job for this annotation

GitHub Actions / ESLint - Reviewdog

[eslint] reported by reviewdog 🐶 'useDebounceFn' is defined but never used. Raw Output: {"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'useDebounceFn' is defined but never used.","line":113,"column":10,"nodeType":"Identifier","messageId":"unusedVar","endLine":113,"endColumn":23}
import { useFilter } from '@/composables/filter';

Check warning on line 114 in desk/src/components/FilterPopover.vue

View workflow job for this annotation

GitHub Actions / ESLint - Reviewdog

[eslint] reported by reviewdog 🐶 'useFilter' is defined but never used. Raw Output: {"ruleId":"@typescript-eslint/no-unused-vars","severity":1,"message":"'useFilter' is defined but never used.","line":114,"column":10,"nodeType":"Identifier","messageId":"unusedVar","endLine":114,"endColumn":19}
import { NestedPopover, SearchComplete } from '@/components';
import { metaState } from '@/resources';
const props = defineProps({
doctype: {
type: String,
required: true,
},
});
// const props = defineProps({
// doctype: {
// type: String,
// required: true,
// },
// resource: {}
// });
const { apply, fields, storage } = useFilter(props.doctype);
const typeCheck = ["Check"];
const typeLink = ["Link"];
const typeNumber = ["Float", "Int"];
const typeSelect = ["Select"];
const typeString = ["Data", "Long Text", "Small Text", "Text Editor", "Text"];
const props = defineProps<{
doctype: string;
resource: any;

Check warning on line 128 in desk/src/components/FilterPopover.vue

View workflow job for this annotation

GitHub Actions / ESLint - Reviewdog

[eslint] reported by reviewdog 🐶 Unexpected any. Specify a different type. Raw Output: {"ruleId":"@typescript-eslint/no-explicit-any","severity":1,"message":"Unexpected any. Specify a different type.","line":128,"column":13,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":128,"endColumn":16,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[4132,4135],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[4132,4135],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}]}
}>();
watch(
storage,
useDebounceFn(() => apply(), 300),
{ deep: true }
// const { apply, fields, storage } = useFilter(props.doctype);
const typeCheck = ['Check'];
const typeLink = ['Link'];
const typeNumber = ['Float', 'Int'];
const typeSelect = ['Select'];
const typeString = ['Data', 'Long Text', 'Small Text', 'Text Editor', 'Text'];
const fields = computed(() =>
metaState[props.doctype]?.fields
.filter((f) => ['Link', 'Select'].includes(f.fieldtype))
.map((f) => ({
label: f.label,
value: f.fieldname,
}))
.sort((a, b) => a.label.localeCompare(b.label))
);
// watch(
// storage,
// useDebounceFn(() => apply(), 300),
// { deep: true }
// );
function getOperators(fieldtype) {
let options = [];
if (typeString.includes(fieldtype)) {
options.push(
...[
{ label: "Equals", value: "equals" },
{ label: "Not Equals", value: "not equals" },
{ label: "Like", value: "like" },
{ label: "Not Like", value: "not like" },
{ label: 'Equals', value: 'equals' },
{ label: 'Not Equals', value: 'not equals' },
{ label: 'Like', value: 'like' },
{ label: 'Not Like', value: 'not like' },
]
);
}
if (typeNumber.includes(fieldtype)) {
options.push(
...[
{ label: "<", value: "<" },
{ label: ">", value: ">" },
{ label: "<=", value: "<=" },
{ label: ">=", value: ">=" },
{ label: "Equals", value: "equals" },
{ label: "Not Equals", value: "not equals" },
{ label: '<', value: '<' },
{ label: '>', value: '>' },
{ label: '<=', value: '<=' },
{ label: '>=', value: '>=' },
{ label: 'Equals', value: 'equals' },
{ label: 'Not Equals', value: 'not equals' },
]
);
}
if (typeSelect.includes(fieldtype) || typeLink.includes(fieldtype)) {
options.push(
...[
{ label: "Is", value: "is" },
{ label: "Is Not", value: "is not" },
{ label: 'Is', value: 'is' },
{ label: 'Is Not', value: 'is not' },
]
);
}
if (typeCheck.includes(fieldtype)) {
options.push(...[{ label: "Equals", value: "equals" }]);
options.push(...[{ label: 'Equals', value: 'equals' }]);
}
return options;
}
function getValSelect(fieldtype, options) {
if (typeSelect.includes(fieldtype) || typeCheck.includes(fieldtype)) {
const _options =
fieldtype == "Check" ? ["Yes", "No"] : getSelectOptions(options);
fieldtype == 'Check' ? ['Yes', 'No'] : getSelectOptions(options);
return h(FormControl, {
type: "select",
type: 'select',
options: _options.map((o) => ({
label: o,
value: o,
})),
});
} else {
return h(FormControl, { type: "text" });
return h(FormControl, { type: 'text' });
}
}
Expand All @@ -183,60 +209,60 @@ function getDefaultValue(field) {
return getSelectOptions(field.options)[0];
}
if (typeCheck.includes(field.fieldtype)) {
return "Yes";
return 'Yes';
}
return "";
return '';
}
function getDefaultOperator(fieldtype) {
if (typeSelect.includes(fieldtype) || typeLink.includes(fieldtype)) {
return "is";
return 'is';
}
if (typeCheck.includes(fieldtype) || typeNumber.includes(fieldtype)) {
return "equals";
return 'equals';
}
return "like";
return 'like';
}
function getSelectOptions(options) {
return options.split("\n");
}
function setfilter(data) {
storage.value.add({
field: {
label: data.label,
fieldname: data.value,
fieldtype: data.fieldtype,
options: data.options,
},
fieldname: data.value,
operator: getDefaultOperator(data.fieldtype),
value: getDefaultValue(data),
});
return options.split('\n');
}
function updateFilter(data, index) {
storage.value.delete(Array.from(storage.value)[index]);
storage.value.add({
fieldname: data.value,
operator: getDefaultOperator(data.fieldtype),
value: getDefaultValue(data),
field: {
label: data.label,
fieldname: data.value,
fieldtype: data.fieldtype,
options: data.options,
},
});
}
function removeFilter(index) {
storage.value.delete(Array.from(storage.value)[index]);
}
function clearfilter(close) {
storage.value.clear();
close();
}
// function setfilter(data) {
// storage.value.add({
// field: {
// label: data.label,
// fieldname: data.value,
// fieldtype: data.fieldtype,
// options: data.options,
// },
// fieldname: data.value,
// operator: getDefaultOperator(data.fieldtype),
// value: getDefaultValue(data),
// });
// }
//
// function updateFilter(data, index) {
// storage.value.delete(Array.from(storage.value)[index]);
// storage.value.add({
// fieldname: data.value,
// operator: getDefaultOperator(data.fieldtype),
// value: getDefaultValue(data),
// field: {
// label: data.label,
// fieldname: data.value,
// fieldtype: data.fieldtype,
// options: data.options,
// },
// });
// }
//
// function removeFilter(index) {
// storage.value.delete(Array.from(storage.value)[index]);
// }
//
// function clearfilter(close) {
// storage.value.clear();
// close();
// }
</script>
Loading

0 comments on commit d4ec5e7

Please sign in to comment.