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

[#31420] Edit Vocabulary #87

Merged
merged 35 commits into from
Sep 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
a60ef53
[#31420] Editing Sources - post rebase
bd-viget Sep 9, 2024
8239f26
[#31420] PR Feedback and spelling correction
bd-viget Sep 13, 2024
c44b84b
[#31420] WIP Sources CRUD
bd-viget Sep 13, 2024
6f60110
[#31420] Small tweaks and cleanup
bd-viget Sep 16, 2024
23e39f2
[#31420] WIP Sources CRUD
bd-viget Sep 16, 2024
d1f2225
[#31420] Small Tweak
bd-viget Sep 16, 2024
88d7158
[#31420] Adding/Editing Sources works!
bd-viget Sep 17, 2024
91f668a
[#31420] More global/dynamic dirty check
bd-viget Sep 17, 2024
423a6d7
[#31420] Categories CRUD working (not saving)
bd-viget Sep 18, 2024
b0dc38e
[#31420] Added Success Alert for Categories
bd-viget Sep 18, 2024
1f62896
[#31420] Adjustment to Saving Category
bd-viget Sep 18, 2024
0a7cb0f
[#31420] Save Concept Categories
bd-viget Sep 18, 2024
a1f0bc1
[#31420] Added type for $id
bd-viget Sep 19, 2024
dff8c5d
[#31420] Remove Primary Category functionality
bd-viget Sep 19, 2024
b791617
[#31420] Hide Add Category if no more categories to add
bd-viget Sep 19, 2024
fb6d14a
[#31420] Remove console log
bd-viget Sep 19, 2024
c453537
[#31420] Almost got Terms working again
bd-viget Sep 19, 2024
f2ec78a
[#31420] File re-organization
bd-viget Sep 19, 2024
3340772
[#31420] Prep Edit for removal
bd-viget Sep 19, 2024
4458f3c
[#31420] No change
bd-viget Sep 19, 2024
8528524
[#31420] Fixed editor permission check, added inline edit
bd-viget Sep 20, 2024
f20549c
[#31420] Inline Edit Stuff
bd-viget Sep 20, 2024
4e31dbe
[#31420] Fixed Edit/Delete Sources
bd-viget Sep 20, 2024
a8baa88
[#31420] Restore Add Term button
bd-viget Sep 20, 2024
336211f
[#31418] Remove ability to Delete Categories
bd-viget Sep 20, 2024
223db6b
[#31420] Use ConceptSourceService
bd-viget Sep 20, 2024
03ed05a
Revert "[#31418] Remove ability to Delete Categories"
bd-viget Sep 20, 2024
a972074
[#31420] Remove unused items
bd-viget Sep 20, 2024
0c76def
[#31420] Use ConceptSourceService
bd-viget Sep 20, 2024
38fb163
[#31420] Replace confirms with Modals, added Mixins
bd-viget Sep 20, 2024
a1b8b6c
[#31420] Source Modals
bd-viget Sep 20, 2024
ab8a200
[#31420] Confirm Dialog replacement
bd-viget Sep 20, 2024
f4d0039
[#31420] Last Confirm Dialog
bd-viget Sep 20, 2024
1326b2e
[#31420] Inline Edit Tweak
bd-viget Sep 20, 2024
3941cde
[#31420] Tweaks to inlineEdit
bd-viget Sep 23, 2024
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
21 changes: 19 additions & 2 deletions app/Http/Controllers/API/ConceptController.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use App\Models\Concept;
use App\Models\Term;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\DB;

class ConceptController extends Controller
Expand Down Expand Up @@ -130,9 +131,25 @@ public function show($id)
* @param int $id
* @return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
public function update(Request $request, int $id)
{
//
$concept = Concept::findOrFail($id);
$attributes = $request->all();

// Sync concept categories
if (array_key_exists('conceptCategories', $attributes)) {
$category_ids = array_map(function ($category) {
return $category['id'];
}, $attributes['conceptCategories']);

$concept->conceptCategories()->sync($category_ids);

unset($attributes['conceptCategories']);
}

$concept->update($attributes);

return new Response($concept);
}

/**
Expand Down
9 changes: 9 additions & 0 deletions resources/js/api/ConceptService.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,15 @@ export default {
}
},

async updateConcept(conceptId, conceptData) {
try {
const { data } = await apiClient.patch(`/${conceptId}`, conceptData);
return [null, data];
} catch (error) {
return [error];
}
},

async deleteConcept(conceptId) {
try {
const { data } = await apiClient.delete(`/${conceptId}`);
Expand Down
2 changes: 1 addition & 1 deletion resources/js/api/ConceptSourceService.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export default {

async updateConceptSource(conceptSourceId, conceptSourceData) {
try {
const { data } = await apiClient.post(
const { data } = await apiClient.patch(
`/${conceptSourceId}`,
conceptSourceData,
);
Expand Down
14 changes: 1 addition & 13 deletions resources/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import 'bootstrap-vue/dist/bootstrap-vue.css';
Vue.component('concept', require('./components/Concept.vue').default);
Vue.component('concept-list', require('./components/Concept/List.vue').default);
Vue.component('concept', require('./components/Concept/Default.vue').default);
Vue.component('concept-edit', require('./components/Concept/Edit.vue').default);
Vue.component('concept-edit', require('./components/Concept/LegacyEdit.vue').default);
Vue.component(
'concept-category',
require('./components/ConceptCategory.vue').default,
Expand All @@ -44,23 +44,11 @@ Vue.component(
'concept-create',
require('./components/Concept/Create.vue').default,
);
Vue.component(
'concept-source',
require('./components/Source/Default.vue').default,
);
Vue.component(
'concept-source-edit',
require('./components/Source/Edit.vue').default,
);
Vue.component(
'concept-search',
require('./components/ConceptSearch.vue').default,
);
Vue.component('term-list', require('./components/Term/List.vue').default);
Vue.component(
'category-list',
require('./components/Category/List.vue').default,
);
Vue.component('term-item', require('./components/TermItem.vue').default);
Vue.component('cpf-form', require('./components/CPFForm.vue').default);
Vue.component('b-table', BTable);
Expand Down
4 changes: 2 additions & 2 deletions resources/js/components/CPFForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -626,7 +626,7 @@
</template>

<script>
import { categories } from '../config/catgegories';
import { categories } from '../config/categories';

export default {
props: {
Expand Down Expand Up @@ -654,7 +654,7 @@ export default {
relationType: '',
propertyEditMode: true,
categories,
isVocabularyEditor: this.canEditVocabulary === true,
isVocabularyEditor: this.canEditVocabulary === 'true',
baseURL: '',
};
},
Expand Down
193 changes: 132 additions & 61 deletions resources/js/components/Category/Editable.vue
Original file line number Diff line number Diff line change
@@ -1,103 +1,174 @@
<template>
<BInputGroup>
<BFormSelect
v-model="originalId"
@input="updateCategory"
:options="getCategories"
:class="{ 'alert-info': isDirty }"
></BFormSelect>
<div>
<BInputGroup>
<div
v-if="originalId"
class="category-item custom-select"
:class="{ 'font-weight-bold': isPrimary }"
>
{{ selectedValue }}
</div>
<BFormSelect
v-else
v-model="selectedId"
@change="trackChanges"
:options="getCategories"
:class="{ 'alert-info': isDirty() }"
aria-placeholder="Select a category"
placeholder="Select a category"
></BFormSelect>

<BInputGroupAppend>
<BButton
@click="emitSaveCategory"
class="btn btn-info"
title="Save"
v-show="isDirty"
><i class="fa fa-floppy-o"></i
></BButton>
<BButton
@click="emitMakeCategoryPrimary"
v-if="!isPrimary"
class="btn btn-primary"
title="Make Primary"
><i class="fa fa-check-square-o"></i
></BButton>
<BButton
@click="emitDeleteCategory"
v-if="!isPrimary"
class="btn btn-danger"
title="Delete"
><i class="fa fa-trash"></i
></BButton>
</BInputGroupAppend>
</BInputGroup>
<BInputGroupAppend>
<BButton
@click="emitSaveCategory"
class="btn btn-info"
title="Save"
v-show="!originalId && isDirty()"
><i class="fa fa-floppy-o"></i
></BButton>
<BButton @click="showDeleteModal" class="btn btn-danger" title="Delete"
><i class="fa fa-trash"></i
></BButton>
</BInputGroupAppend>
</BInputGroup>

<BModal
id="delete-confirmation-modal"
ref="deleteModal"
title="Confirm Deletion"
@hide="resetCategory"
@shown="focusConfirmDeleteButton"
hide-footer
>
<div class="d-block text-center">
<p>Are you sure you want to delete this category?</p>
<BButton variant="danger" ref="confirmDeleteButton" @click="confirmDelete">Yes, delete</BButton>
<BButton variant="secondary" @click="hideDeleteModal">Cancel</BButton>
</div>
</BModal>
</div>
</template>

<script>
import {
BButton,
BFormInput,
BFormSelect,
BInputGroup,
BInputGroupAppend,
BModal,
} from 'bootstrap-vue';
import { categories } from '../../config/categories';

export default {
data() {
return {
originalId: this.category.id,
originalValue: this.category.value,
selectedId: this.category.id,
selectedId: this.categoryId,
originalId: this.categoryId,
selectedValue: this.categoryValue,
previous: null,
categories,
};
},
model: {
prop: 'category',
event: 'input',
},
props: {
category: Object,
isPrimary: Boolean,
categoryId: {
type: Number,
default: null,
},
isPrimary: {
type: Boolean,
default: false,
},
categoryValue: {
type: String,
default: null,
},
categoryIndex: {
type: Number,
default: null,
},
selectedCategories: {
type: Array,
default: () => [],
},
},
components: {
BFormInput,
BInputGroup,
BInputGroupAppend,
BFormSelect,
BButton,
},
computed: {
getCategories() {
return this.$parent.getCategories(this.getCategory.id);
},
isDirty() {
if(!this.category.value) {
return !!this.category.id;
const filtered = this.categories.filter((cat) => {
return (
this.selectedCategories.filter((currentCat) => {
return currentCat === parseInt(cat.value);
}).length === 0 || this.categoryId === parseInt(cat.value)
);
});

if (!this.selectedId && filtered.length) {
filtered.unshift({
value: null,
text: 'Select a category',
disabled: true,
});
}
return parseInt(this.originalId) !== this.category.id;
},
getCategory() {
return this.category;
},
resetCategory() {
this.originalId = this.getCategory.id;
this.originalValue = this.getCategory.value;

return filtered;
},
},
methods: {
updateCategory(categoryId) {
this.selectedId = parseInt(categoryId);
this.$emit('change', { ...this.getCategory, category: this.selectedId, dirty: this.isDirty });
trackChanges() {
const selectedId = parseInt(this.selectedId);

this.$emit('change', {
id: selectedId,
dirty: this.isDirty(),
previous: this.previous,
});
this.previous = selectedId;
},
emitSaveCategory() {
console.log('newId',categoryId);
console.log('oldId',this.category.id);

this.$emit('save-category', this.selectedId, this.category.id);
const selectedId = parseInt(this.selectedId);
this.$emit('save-category', selectedId, this.categoryIndex);
this.originalId = selectedId;
this.selectedValue = this.categories.find(
(cat) => parseInt(cat.value) === this.originalId,
).text;
},
showDeleteModal() {
this.$refs.deleteModal.show();
},
focusConfirmDeleteButton() {
this.$refs.confirmDeleteButton.focus();
},
emitMakeCategoryPrimary() {
this.$emit('make-category-primary', this.getCategory);
hideDeleteModal() {
this.$refs.deleteModal.hide();
},
emitDeleteCategory() {
this.$emit('delete-category', this.getCategory);
confirmDelete() {
this.$emit('delete-category', this.categoryId, this.categoryIndex);
this.hideDeleteModal();
},
isDirty() {
if (!this.selectedId) {
return !!this.categoryId;
}
return this.originalId !== parseInt(this.selectedId);
},
resetCategory() {
this.selectedId = this.categoryId;
},
},
};
</script>
<style>
.category-item.custom-select {
background-image: none;
}
</style>
Loading