Skip to content

Commit

Permalink
Search Mode
Browse files Browse the repository at this point in the history
  • Loading branch information
ltouroumov committed Feb 5, 2024
1 parent 031532e commit e26e4f4
Show file tree
Hide file tree
Showing 7 changed files with 814 additions and 32 deletions.
34 changes: 24 additions & 10 deletions components/viewer/ViewProjectObj.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<div class="col" :class="objClass(row, obj)">
<div :class="objClass">
<div
class="project-obj"
:class="{ selected: isSelected, disabled: !isEnabled }"
Expand Down Expand Up @@ -61,32 +61,45 @@ import { ProjectObj, ProjectRow } from '~/composables/project';
import { useProjectRefs, useProjectStore } from '~/composables/store/project';
import { formatText } from '~/composables/text';
const { row, obj } = defineProps<{
const {
row,
obj,
preview = false,
} = defineProps<{
row: ProjectRow;
obj: ProjectObj;
preview?: boolean;
}>();
const objClass = (row: ProjectRow, obj: ProjectObj) => {
const objClass = computed(() => {
if (preview) return [];
let className = row.objectWidth;
if (obj.objectWidth) className = obj.objectWidth;
if (obj.objectWidth) {
className = obj.objectWidth;
}
return { [className]: true };
};
return ['col', { [className]: true }];
});
const store = useProjectStore();
const { selectedIds, selected } = useProjectRefs();
const condition = buildConditions(obj);
const isEnabled = computed<boolean>(() => condition(selectedIds.value));
const condition = computed(() => buildConditions(obj));
const isEnabled = computed<boolean>(() => condition.value(selectedIds.value));
const isSelected = computed<boolean>(() => R.has(obj.id, selected.value));
const selectedAmount = computed(() => {
if (obj.isSelectableMultiple) return selected.value[obj.id] ?? 0;
else return 0;
});
const minSelectedAmount = Number.parseInt(obj.numMultipleTimesMinus);
const maxSelectedAmount = Number.parseInt(obj.numMultipleTimesPluss);
const minSelectedAmount = computed(() =>
Number.parseInt(obj.numMultipleTimesMinus),
);
const maxSelectedAmount = computed(() =>
Number.parseInt(obj.numMultipleTimesPluss),
);
const toggle = () => {
if (isEnabled.value && !obj.isSelectableMultiple) {
Expand Down Expand Up @@ -131,6 +144,7 @@ const decrement = () => {
.obj-content {
padding: 0.5em;
overflow-x: auto;
.obj-title {
font-size: 1.2em;
Expand Down
1 change: 1 addition & 0 deletions components/viewer/ViewProjectRow.vue
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ const isVisible = computed(() => condition(selectedIds.value));
padding: 5px 0;
font-size: 1.5em;
font-weight: bold;
text-align: center;
}
.row-text {
Expand Down
94 changes: 77 additions & 17 deletions components/viewer/modal/ViewSearch.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<div class="search-base" :class="{ hidden: !isSearchVisible }">
<div class="search-modal">
<div class="search-modal" :class="{ 'show-view': !!searchView }">
<div class="search-header">
<input
v-model="searchText"
Expand All @@ -9,19 +9,34 @@
@input="search"
/>
</div>
<div class="search-results text-light">
<div class="search-result-list text-light">
<div
v-for="group in searchResults"
:key="group.row.id"
class="result-group"
>
<div class="group-title">{{ group.row.title }}</div>
<div v-for="obj in group.items" :key="obj.id" class="result-item">
<div
v-for="obj in group.items"
:key="obj.id"
class="result-item"
:class="{ selected: searchView?.obj.id === obj.id }"
@click="preview(obj, group.row)"
>
{{ obj.title }}
</div>
</div>
</div>
<div v-if="!!searchView" class="search-result-view text-light">
<ViewProjectObj
:key="searchView.obj.id"
:obj="searchView.obj"
:row="searchView.row"
preview
/>
</div>
</div>
<div class="search-shade" @click="toggleSearch(false)"></div>
</div>
</template>
Expand All @@ -31,23 +46,28 @@ import { isEmpty } from 'ramda';
import { Project, ProjectObj, ProjectRow } from '~/composables/project';
import { useProjectRefs } from '~/composables/store/project';
import { useViewerRefs } from '~/composables/store/viewer';
import { useViewerRefs, useViewerStore } from '~/composables/store/viewer';
const { toggleSearch } = useViewerStore();
const { isSearchVisible } = useViewerRefs();
const { project } = useProjectRefs();
type ResultGroup = {
row: ProjectRow;
items: ProjectObj[];
};
type ResultView = {
row: ProjectRow;
obj: ProjectObj;
};
const searchText = ref<string>('');
const searchResults = ref<ResultGroup[]>([]);
const searchView = ref<ResultView | null>(null);
const search = debounce(() => {
if (!project.value) return;
console.log('searching', searchText.value);
const searchTextLC = searchText.value.toLowerCase();
const results: ResultGroup[] = [];
Expand Down Expand Up @@ -77,6 +97,14 @@ const search = debounce(() => {
searchResults.value = results;
}, 200);
const preview = (obj: ProjectObj, row: ProjectRow) => {
if (!!searchView.value && searchView.value.obj.id === obj.id) {
searchView.value = null;
} else {
searchView.value = { obj, row };
}
};
</script>
<style scoped lang="scss">
Expand All @@ -88,9 +116,6 @@ const search = debounce(() => {
bottom: 0;
left: 0;
right: 0;
z-index: 9999;
background: rgba(50, 50, 50, 0.5);
display: flex;
justify-content: center;
Expand All @@ -101,28 +126,59 @@ const search = debounce(() => {
}
}
.search-shade {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
z-index: -1;
background: rgba(50, 50, 50, 0.5);
}
.search-modal {
min-width: 200px;
min-height: 200px;
width: 50%;
height: 70%;
width: 80%;
height: 80%;
padding: 0.75em;
border-radius: 1em;
background: $body-bg-dark;
display: flex;
flex-direction: column;
display: grid;
gap: 0.5em;
.search-results {
flex-grow: 1;
border: var(--bs-border-width) solid var(--bs-border-color);
border-radius: var(--bs-border-radius);
grid-template:
'header header' auto
'list list' 1fr
/ 1fr 1fr;
&.show-view {
grid-template:
'header header' auto
'list view' 1fr
/ 2fr 1fr;
}
.search-header {
grid-area: header;
}
.search-result-list {
grid-area: list;
overflow: auto;
}
.search-result-view {
grid-area: view;
overflow: auto;
display: flex;
align-items: stretch;
justify-content: stretch;
}
.result-group {
.group-title {
font-weight: bold;
Expand All @@ -131,6 +187,10 @@ const search = debounce(() => {
}
.result-item {
padding: 0.2rem 0.5rem;
&.selected {
background: var(--bs-primary);
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,5 @@ export default defineNuxtConfig({
pathPrefix: false,
},
],
modules: ['@unocss/nuxt', '@pinia/nuxt'],
modules: ['@unocss/nuxt', '@pinia/nuxt', '@vueuse/nuxt'],
});
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
"@types/ramda": "^0.29.3",
"@unocss/nuxt": "^0.55.2",
"@unocss/reset": "^0.55.2",
"@vueuse/core": "^10.7.2",
"@vueuse/nuxt": "^10.7.2",
"bootstrap": "5.3.*",
"perfect-debounce": "^1.0.0",
"pinia": "^2.1.6",
Expand Down
2 changes: 1 addition & 1 deletion pages/viewer.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<div v-if="project">
<div v-if="project" class="text-light">
<ViewMenuBar />
<div class="project">
<div class="rows">
Expand Down
Loading

0 comments on commit e26e4f4

Please sign in to comment.