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

Effort to improve tagging #52

Merged
merged 5 commits into from
Mar 13, 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
2 changes: 1 addition & 1 deletion app/Http/Controllers/PhotoItemTagsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public function store(PhotoItem $photoItem, StorePhotoItemTagRequest $request):
abort(404);
}

$photoItem->tags()->syncWithoutDetaching($request->input('tag_id'));
$photoItem->tags()->syncWithoutDetaching($request->input('tag_ids'));

return response()->json();
}
Expand Down
3 changes: 2 additions & 1 deletion app/Http/Requests/StorePhotoItemTagRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ class StorePhotoItemTagRequest extends FormRequest
public function rules(): array
{
return [
'tag_id' => 'required|exists:tags,id',
'tag_ids' => 'required|array',
'tag_ids.*' => 'required|integer|exists:tags,id',
];
}
}
13 changes: 9 additions & 4 deletions resources/js/Components/TagBox.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,13 @@ const props = defineProps({
type: Boolean,
default: false,
},
dropdownWidth: {
nullable: {
type: Boolean,
default: false,
},
placeholder: {
type: String,
default: 'w-full md:w-96 right-0',
default: '',
},
});

Expand Down Expand Up @@ -59,6 +63,7 @@ onMounted(() => {
:modelValue="modelValue"
@update:modelValue="value => $emit('update:modelValue', value)"
:multiple="multiple"
:nullable="nullable"
by="id"
>
<div class="relative">
Expand All @@ -67,6 +72,7 @@ onMounted(() => {
ref="input"
class="w-full rounded-md border-0 bg-white dark:bg-gray-900 py-1.5 pl-3 pr-12 text-gray-900 dark:text-gray-300 shadow-sm ring-1 ring-inset ring-gray-300 dark:ring-gray-700 focus:ring-2 focus:ring-inset focus:ring-indigo-500 dark:focus:ring-indigo-600 sm:text-sm sm:leading-6"
:displayValue="(item) => item?.name"
:placeholder="placeholder"
@change="query = $event.target.value"
@focus="$event.target.select()"
autocomplete="off"
Expand Down Expand Up @@ -96,8 +102,7 @@ onMounted(() => {
@after-leave="query = ''"
>
<ComboboxOptions
class="absolute z-10 mt-1 max-h-96 overflow-auto rounded-md bg-white py-1 text-base shadow-lg ring-1 ring-black/5 focus:outline-none sm:text-sm"
:class="dropdownWidth"
class="absolute z-10 mt-1 max-h-96 w-full overflow-auto rounded-md bg-white py-1 text-base shadow-lg ring-1 ring-black/5 focus:outline-none sm:text-sm"
>
<div
v-if="filteredItems.length === 0 && query !== ''"
Expand Down
206 changes: 91 additions & 115 deletions resources/js/Pages/Photos/Partials/NewPhotoItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,23 @@ const props = defineProps({

const item = ref(props.propItem);

const selectedMaterialTag = ref(props.tags.material[0]);
const selectedBrandTag = ref(props.tags.brand[0]);
const selectedEventTag = ref(props.tags.event[0]);
const selectedStateTag = ref(props.tags.state[0]);
const selectedContentTag = ref(props.tags.content[0]);
const selectedSizeTag = ref(props.tags.size[0]);
const selectedMaterialTag = ref(null);
const selectedBrandTag = ref(null);
const selectedEventTag = ref(null);
const selectedStateTag = ref(null);
const selectedContentTag = ref(null);
const selectedSizeTag = ref(null);

const selectedTagIds = computed(() => {
return [
selectedMaterialTag.value?.id,
selectedBrandTag.value?.id,
selectedEventTag.value?.id,
selectedStateTag.value?.id,
selectedContentTag.value?.id,
selectedSizeTag.value?.id,
].filter(tag => tag);
});

const tagNames = computed(() => {
return item.value.tag_ids.map(function (tagId) {
Expand All @@ -32,13 +43,17 @@ const tagNames = computed(() => {
});
});

const addTagToItem = (tag) => {
if (item.value.tag_ids.find(itemTag => itemTag === tag.id)) {
return;
}
const addTagsToItem = () => {
item.value.tag_ids = [...new Set([...item.value.tag_ids, ...selectedTagIds.value])];

item.value.tag_ids.push(tag.id);
emit('change', item.value);

selectedMaterialTag.value = null;
selectedBrandTag.value = null;
selectedEventTag.value = null;
selectedStateTag.value = null;
selectedContentTag.value = null;
selectedSizeTag.value = null;
};

const removeTagFromItem = (tagId) => {
Expand Down Expand Up @@ -75,110 +90,63 @@ const copyItem = () => {
<i class="fas fa-fw fa-trash-alt text-xs"></i>
</IconDangerButton>
</div>
<div class="mt-6">
<div class="flex flex-row justify-between space-x-2">
<TagBox
class="w-full"
dropdownWidth="w-full"
:items="tags.material"
v-model="selectedMaterialTag"
></TagBox>

<PrimaryButton
class="whitespace-nowrap"
@click="addTagToItem(selectedMaterialTag)"
:disabled="!selectedMaterialTag"
>
Add Material
</PrimaryButton>
</div>

<div class="mt-2 flex flex-row justify-between space-x-2">
<TagBox
class="w-full"
dropdownWidth="w-full"
:items="tags.brand"
v-model="selectedBrandTag"
></TagBox>

<PrimaryButton
class="whitespace-nowrap"
@click="addTagToItem(selectedBrandTag)"
:disabled="!selectedBrandTag"
>
Add Brand
</PrimaryButton>
</div>

<div class="mt-2 flex flex-row justify-between space-x-2">
<TagBox
class="w-full"
dropdownWidth="w-full"
:items="tags.content"
v-model="selectedContentTag"
></TagBox>

<PrimaryButton
class="whitespace-nowrap"
@click="addTagToItem(selectedContentTag)"
:disabled="!selectedContentTag"
>
Add Content
</PrimaryButton>
</div>

<div class="mt-2 flex flex-row justify-between space-x-2">
<TagBox
class="w-full"
dropdownWidth="w-full"
:items="tags.size"
v-model="selectedSizeTag"
></TagBox>

<PrimaryButton
class="whitespace-nowrap"
@click="addTagToItem(selectedSizeTag)"
:disabled="!selectedSizeTag"
>
Add Size
</PrimaryButton>
</div>

<div class="mt-2 flex flex-row justify-between space-x-2">
<TagBox
class="w-full"
dropdownWidth="w-full"
:items="tags.state"
v-model="selectedStateTag"
></TagBox>

<PrimaryButton
class="whitespace-nowrap"
@click="addTagToItem(selectedStateTag)"
:disabled="!selectedStateTag"
>
Add State
</PrimaryButton>
</div>

<div class="mt-2 flex flex-row justify-between space-x-2">
<TagBox
class="w-full"
dropdownWidth="w-full"
:items="tags.event"
v-model="selectedEventTag"
></TagBox>

<PrimaryButton
class="whitespace-nowrap"
@click="addTagToItem(selectedEventTag)"
:disabled="!selectedEventTag"
>
Add Event
</PrimaryButton>
</div>
<div class="mt-6 space-y-2">
<TagBox
class="w-full"
:items="tags.material"
v-model="selectedMaterialTag"
:nullable="true"
placeholder="Material"
@change="addTagsToItem"
></TagBox>

<TagBox
class="w-full"
:items="tags.brand"
v-model="selectedBrandTag"
:nullable="true"
placeholder="Brand"
@change="addTagsToItem"
></TagBox>

<TagBox
class="w-full"
:items="tags.content"
v-model="selectedContentTag"
:nullable="true"
placeholder="Content"
@change="addTagsToItem"
></TagBox>

<TagBox
class="w-full"
:items="tags.size"
v-model="selectedSizeTag"
:nullable="true"
placeholder="Size"
@change="addTagsToItem"
></TagBox>

<TagBox
class="w-full"
:items="tags.state"
v-model="selectedStateTag"
:nullable="true"
placeholder="State"
@change="addTagsToItem"
></TagBox>

<TagBox
class="w-full"
:items="tags.event"
v-model="selectedEventTag"
:nullable="true"
placeholder="Event"
@change="addTagsToItem"
></TagBox>
</div>

<div class="mt-4 text-sm text-gray-500 flex flex-wrap gap-1">
<div class="mt-4 text-sm text-gray-500 flex flex-wrap gap-1">
<span
v-for="tag in tagNames"
:key="tag.id"
Expand All @@ -189,7 +157,15 @@ const copyItem = () => {
aria-hidden="true"><circle cx="3" cy="3" r="3"/></svg>
{{ tag.name }}
</span>
</div>
</div>

<div v-if="selectedTagIds.length" class="mt-4 flex justify-center">
<PrimaryButton
class="whitespace-nowrap"
@click="addTagsToItem"
>
Add Selected Tags
</PrimaryButton>
</div>
</div>
<div class="px-4 py-5 sm:p-6 flex flex-row justify-between">
Expand Down
Loading