mirror of
https://github.com/verdigado/organization_folders.git
synced 2024-12-03 18:02:50 +01:00
improved resource settings view
This commit is contained in:
parent
baf5d30f8b
commit
9f14ca2179
8 changed files with 363 additions and 181 deletions
|
@ -10,6 +10,8 @@ return [
|
|||
['name' => 'resource#update', 'url' => '/resources/{resourceId}', 'verb' => 'PUT'],
|
||||
['name' => 'resource_member#index', 'url' => '/resources/{resourceId}/members', 'verb' => 'GET'],
|
||||
['name' => 'resource_member#create', 'url' => '/resources/{resourceId}/members', 'verb' => 'POST'],
|
||||
['name' => 'resource_member#update', 'url' => '/resources/members/{id}', 'verb' => 'PUT'],
|
||||
['name' => 'resource_member#destroy', 'url' => '/resources/members/{id}', 'verb' => 'DELETE'],
|
||||
['name' => 'organization#getOrganizationProviders', 'url' => '/organizationProviders', 'verb' => 'GET'],
|
||||
['name' => 'organization#getOrganization', 'url' => '/organizationProviders/{organizationProviderId}/organizations/{organizationId}', 'verb' => 'GET'],
|
||||
['name' => 'organization#getSubOrganizations', 'url' => '/organizationProviders/{organizationProviderId}/organizations/{parentOrganizationId}/subOrganizations', 'verb' => 'GET'],
|
||||
|
|
16
src/api.js
16
src/api.js
|
@ -118,14 +118,22 @@ export default {
|
|||
},
|
||||
|
||||
/**
|
||||
* @param {number|string} resourceMemberId Resource member id
|
||||
* @param {number} resourceMemberId Resource member id
|
||||
* @param {{
|
||||
* permissionLevel: ResourceMemberPermissionLevel
|
||||
* }} createResourceMemberDto CreateResourceMemberDto
|
||||
* }} updateResourceMemberDto UpdateResourceMemberDto
|
||||
* @return {Promise<ResourceMember>}
|
||||
*/
|
||||
updateResourceMember(resourceId, createResourceMemberDto) {
|
||||
return axios.post(`/resources/${resourceId}/members`, { ...createResourceMemberDto }).then((res) => res.data);
|
||||
updateResourceMember(resourceMemberId, updateResourceMemberDto) {
|
||||
return axios.put(`/resources/members/${resourceMemberId}`, { ...updateResourceMemberDto }).then((res) => res.data);
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {number} resourceMemberId Resource member id
|
||||
* @return {Promise<ResourceMember>}
|
||||
*/
|
||||
deleteResourceMember(resourceMemberId) {
|
||||
return axios.delete(`/resources/members/${resourceMemberId}`, {}).then((res) => res.data);
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,162 +0,0 @@
|
|||
<script setup>
|
||||
import NcEmptyContent from "@nextcloud/vue/dist/Components/NcEmptyContent.js"
|
||||
import NcLoadingIcon from "@nextcloud/vue/dist/Components/NcLoadingIcon.js"
|
||||
import NcActions from "@nextcloud/vue/dist/Components/NcActions.js"
|
||||
import NcActionButton from "@nextcloud/vue/dist/Components/NcActionButton.js"
|
||||
import NcButton from "@nextcloud/vue/dist/Components/NcButton.js"
|
||||
import { showError } from "@nextcloud/dialogs"
|
||||
//import MemberListNewItem from "./MemberListNewItem.vue"
|
||||
import MemberListItem from "./MemberListItem.vue"
|
||||
import Plus from "vue-material-design-icons/Plus.vue"
|
||||
import Close from "vue-material-design-icons/Close.vue"
|
||||
import HelpCircle from "vue-material-design-icons/HelpCircle.vue"
|
||||
import api from "../../api.js"
|
||||
import { ref } from 'vue';
|
||||
|
||||
const props = defineProps({
|
||||
members: {
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
|
||||
const loading = ref(false);
|
||||
const error = ref(undefined);
|
||||
const newItemComponent = ref(null);
|
||||
const addMenuOpen = ref(false);
|
||||
|
||||
const setNewItemComponent = (name) => {
|
||||
this.newItemComponent.value = name
|
||||
this.addMenuOpen.value = false
|
||||
};
|
||||
|
||||
const deleteMember = async (memberId) => {
|
||||
this.loading.value = true
|
||||
try {
|
||||
api.deleteGroupMember(this.groupId, memberId)
|
||||
//this.members.value = this.members.filter((m) => m.id !== memberId)
|
||||
} catch (err) {
|
||||
showError(err.message)
|
||||
} finally {
|
||||
this.loading.value = false
|
||||
}
|
||||
};
|
||||
|
||||
const updateMember = async (memberId, changes) => {
|
||||
this.loading.value = true
|
||||
try {
|
||||
const member = await api.updateGroupMember(this.groupId, memberId, changes)
|
||||
this.members = this.members.map((m) => m.id === member.id ? member : m)
|
||||
} catch (err) {
|
||||
showError(err.message)
|
||||
} finally {
|
||||
this.loading.value = false
|
||||
}
|
||||
};
|
||||
|
||||
const addMember = async ({ mappingId, mappingType }) => {
|
||||
this.loading.value = true
|
||||
try {
|
||||
const _member = await api.addGroupMember(this.groupId, {
|
||||
mappingType,
|
||||
mappingId,
|
||||
type: "member",
|
||||
})
|
||||
this.members.push(_member)
|
||||
this.setNewItemComponent(null)
|
||||
} catch (err) {
|
||||
showError(err.message)
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div class="title">
|
||||
<h3>Mitglieder</h3>
|
||||
<!--<NcActions :disabled="!!newItemComponent" type="secondary">
|
||||
<template #icon>
|
||||
<Plus :size="20" />
|
||||
</template>
|
||||
<NcActionButton icon="icon-group" close-after-click @click="setNewItemComponent('new_item')">
|
||||
Benutzer/Gruppe hinzufügen
|
||||
</NcActionButton>
|
||||
<NcActionButton icon="icon-group" close-after-click @click="setNewItemComponent('new_role_item')">
|
||||
Organisation Rolle hinzufügen
|
||||
</NcActionButton>
|
||||
</NcActions>-->
|
||||
</div>
|
||||
<!--<div v-if="newItemComponent" class="new-item">
|
||||
<NcButton type="tertiary" @click="setNewItemComponent(null)">
|
||||
<template #icon>
|
||||
<Close />
|
||||
</template>
|
||||
</NcButton>
|
||||
<MemberListNewItem v-if="newItemComponent === 'new_item'" :group-id="groupId" @selected="addMember" />
|
||||
</div>-->
|
||||
<table>
|
||||
<thead style="display: contents;">
|
||||
<tr>
|
||||
<th />
|
||||
<th>Name</th>
|
||||
<th>
|
||||
<div style="display: flex; align-items: center;">
|
||||
<span>Typ</span>
|
||||
<HelpCircle v-tooltip="'Für Admins gelten die oben ausgewählten Ordneradministrator*innen Berechtigungen, für Mitglieder die Ordnermitglieder Berechtigungen. Admins haben auf diese Einstellungen Zugriff.'" style="margin-left: 5px;" :size="15" />
|
||||
</div>
|
||||
</th>
|
||||
<th>Aktion</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody style="display: contents">
|
||||
<tr v-if="loading">
|
||||
<td colspan="4" style="grid-column-start: 1; grid-column-end: 5">
|
||||
<NcLoadingIcon :size="50" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-if="!loading && !members.length">
|
||||
<td colspan="4" style="grid-column-start: 1; grid-column-end: 5">
|
||||
<NcEmptyContent title="Keine Gruppenmitglieder" />
|
||||
</td>
|
||||
</tr>
|
||||
<MemberListItem v-for="member in members"
|
||||
:key="member.id"
|
||||
:member="member"
|
||||
@update="updateMember"
|
||||
@delete="deleteMember" />
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
table {
|
||||
width: 100%;
|
||||
margin-bottom: 14px;
|
||||
display: grid;
|
||||
grid-template-columns: max-content minmax(30px, auto) max-content max-content;
|
||||
}
|
||||
table tr {
|
||||
display: contents;
|
||||
}
|
||||
table td, table th {
|
||||
padding: 8px;
|
||||
}
|
||||
.title {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
margin-top: 24px;
|
||||
}
|
||||
h3 {
|
||||
font-weight: bold;
|
||||
margin-right: 24px;
|
||||
}
|
||||
.new-item {
|
||||
display: flex;
|
||||
}
|
||||
</style>
|
|
@ -13,23 +13,23 @@ const props = defineProps({
|
|||
},
|
||||
});
|
||||
|
||||
const friendlyNameParts = computed(() => props.member.principal.split(" / "));
|
||||
const friendlyNameParts = computed(() => [props.member.principal.id] /*.split(" / ")*/);
|
||||
|
||||
const emit = defineEmits(["update", "delete"]);
|
||||
|
||||
const typeOptions = [
|
||||
const permissionLevelOptions = [
|
||||
{ label: "Mitglied", value: 1 },
|
||||
{ label: "Manager", value: 2 },
|
||||
];
|
||||
|
||||
const onTypeSelected = (e) => {
|
||||
const onPermissionLevelSelected = (e) => {
|
||||
emit("update", props.member.id, {
|
||||
type: e.target.value,
|
||||
})
|
||||
permissionLevel: parseInt(e.target.value, 10),
|
||||
});
|
||||
};
|
||||
|
||||
const onDeleteClicked = (e) => {
|
||||
emit("delete", props.member.id)
|
||||
emit("delete", props.member.id);
|
||||
};
|
||||
</script>
|
||||
|
||||
|
@ -52,8 +52,8 @@ const onDeleteClicked = (e) => {
|
|||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<select :value="props.member.permissionLevel" @input="onTypeSelected">
|
||||
<option v-for="{ label, value} in typeOptions" :key="value" :value="value">
|
||||
<select :value="props.member.permissionLevel" @input="onPermissionLevelSelected">
|
||||
<option v-for="{ label, value} in permissionLevelOptions" :key="value" :value="value">
|
||||
{{ label }}
|
||||
</option>
|
||||
</select>
|
||||
|
|
144
src/components/MemberList/MemberListNewRole.vue
Normal file
144
src/components/MemberList/MemberListNewRole.vue
Normal file
|
@ -0,0 +1,144 @@
|
|||
<template>
|
||||
<div class="input-row">
|
||||
<div v-for="(level, levelIndex) in levels"
|
||||
:key="'level-' + levelIndex"
|
||||
style="display: contents;"
|
||||
@input="event => onSelection(levelIndex, event.target.value)">
|
||||
<select>
|
||||
<option value="" selected />
|
||||
<option v-for="(item, itemIndex) in level" :key="'option-' + itemIndex + '-' + item.prefix" :value="item.type + '_' + item.id">
|
||||
{{ item.friendlyName }}
|
||||
</option>
|
||||
</select>
|
||||
<ChevronRight v-if="levelIndex !== levels.length - 1" :size="20" />
|
||||
</div>
|
||||
<NcButton :disabled="!validSelection"
|
||||
@click="onSave">
|
||||
<template #icon>
|
||||
<Plus />
|
||||
</template>
|
||||
Hinzufügen
|
||||
</NcButton>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import NcButton from "@nextcloud/vue/dist/Components/NcButton.js"
|
||||
import Plus from "vue-material-design-icons/Plus.vue"
|
||||
import ChevronRight from "vue-material-design-icons/ChevronRight.vue"
|
||||
import api from "../../api.js"
|
||||
|
||||
export default {
|
||||
components: {
|
||||
NcButton,
|
||||
Plus,
|
||||
ChevronRight,
|
||||
},
|
||||
props: {
|
||||
organizationProvider: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
selections: [],
|
||||
levels: [],
|
||||
selectedRole: null,
|
||||
options: [],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
validSelection() {
|
||||
// valid, if not null, undefined or empty
|
||||
return !!this.selectedRole
|
||||
},
|
||||
},
|
||||
async mounted() {
|
||||
// load first selection level
|
||||
this.options = await this.loadSubOptions();
|
||||
await this.recalculateLevels();
|
||||
},
|
||||
methods: {
|
||||
async loadSubOptions(parent) {
|
||||
const self = this.loadSubOptions;
|
||||
|
||||
let subOrganizations = await api.getSubOrganizations(this.organizationProvider, parent);
|
||||
|
||||
let roles = [];
|
||||
if(parent) {
|
||||
roles = await api.getRoles(this.organizationProvider, parent);
|
||||
}
|
||||
|
||||
|
||||
return [
|
||||
...subOrganizations.map((subOrganization) => {
|
||||
return {
|
||||
type: "organization",
|
||||
id: subOrganization.id,
|
||||
friendlyName: subOrganization.friendlyName,
|
||||
subOptions: () => new Promise((resolve, reject) => {
|
||||
self(subOrganization.id).then((result) => {
|
||||
resolve(result);
|
||||
}).catch((err) => {
|
||||
reject(err);
|
||||
});
|
||||
}),
|
||||
};
|
||||
}),
|
||||
...roles.map((role) => {
|
||||
return {
|
||||
type: "role",
|
||||
id: role.id,
|
||||
friendlyName: role.friendlyName,
|
||||
};
|
||||
}),
|
||||
];
|
||||
},
|
||||
async recalculateLevels() {
|
||||
const levels = [this.options]
|
||||
let selectedRole = null
|
||||
|
||||
let parent = this.options
|
||||
for (let index = 0; index < this.selections.length; index++) {
|
||||
const selection = this.selections[index]
|
||||
|
||||
const option = parent.find(option => option.type + '_' + option.id === selection);
|
||||
|
||||
if (option.type === "organization") {
|
||||
const subOptions = await option.subOptions()
|
||||
levels[index + 1] = subOptions
|
||||
parent = subOptions
|
||||
} else {
|
||||
// reached leaf
|
||||
selectedRole = option.id
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
this.selectedRole = selectedRole
|
||||
this.levels = levels
|
||||
},
|
||||
async onSelection(level, value) {
|
||||
// truncate to levels before new selection
|
||||
const newSelections = this.selections.filter((_, index) => index < level);
|
||||
|
||||
newSelections[level] = value;
|
||||
this.selections = newSelections;
|
||||
|
||||
this.recalculateLevels();
|
||||
},
|
||||
onSave() {
|
||||
this.$emit("add-member", this.organizationProvider + ":" + this.selectedRole);
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.input-row {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
</style>
|
155
src/components/MemberList/ResourceMembersList.vue
Normal file
155
src/components/MemberList/ResourceMembersList.vue
Normal file
|
@ -0,0 +1,155 @@
|
|||
<script setup>
|
||||
import NcEmptyContent from "@nextcloud/vue/dist/Components/NcEmptyContent.js";
|
||||
import NcLoadingIcon from "@nextcloud/vue/dist/Components/NcLoadingIcon.js";
|
||||
import NcActions from "@nextcloud/vue/dist/Components/NcActions.js";
|
||||
import NcActionButton from "@nextcloud/vue/dist/Components/NcActionButton.js";
|
||||
import NcButton from "@nextcloud/vue/dist/Components/NcButton.js";
|
||||
import { showError } from "@nextcloud/dialogs";
|
||||
import MemberListNewRole from "./MemberListNewRole.vue";
|
||||
import MemberListItem from "./MemberListItem.vue";
|
||||
import Plus from "vue-material-design-icons/Plus.vue";
|
||||
import Close from "vue-material-design-icons/Close.vue";
|
||||
import HelpCircle from "vue-material-design-icons/HelpCircle.vue";
|
||||
import api from "../../api.js";
|
||||
import { ref } from 'vue';
|
||||
|
||||
const props = defineProps({
|
||||
resourceId: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
members: {
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
organizationProviders: {
|
||||
type: Array,
|
||||
required: false,
|
||||
default: [],
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(["add-member", "update-member", "delete-member"]);
|
||||
|
||||
const loading = ref(false);
|
||||
|
||||
const newMemberType = ref(null);
|
||||
const newMemberAdditionalParameters = ref({});
|
||||
const addMenuOpen = ref(false);
|
||||
|
||||
const setNewMemberType = (name, additionalParameters = {}) => {
|
||||
newMemberType.value = name;
|
||||
newMemberAdditionalParameters.value = additionalParameters;
|
||||
addMenuOpen.value = false;
|
||||
};
|
||||
|
||||
const addMember = (principalType, principalId) => {
|
||||
emit("add-member", principalType, principalId);
|
||||
newMemberType.value = null;
|
||||
};
|
||||
|
||||
const updateMember = (memberId, updateResourceMemberDto) => {
|
||||
emit("update-member", memberId, updateResourceMemberDto);
|
||||
};
|
||||
|
||||
const deleteMember = (memberId) => {
|
||||
emit("delete-member", memberId);
|
||||
};
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div class="title">
|
||||
<h3>Mitglieder</h3>
|
||||
<NcActions :disabled="!!newMemberType" type="secondary">
|
||||
<template #icon>
|
||||
<Plus :size="20" />
|
||||
</template>
|
||||
<NcActionButton icon="icon-user" close-after-click @click="setNewMemberType(api.PrincipalTypes.USER)">
|
||||
Benutzer hinzufügen
|
||||
</NcActionButton>
|
||||
<NcActionButton icon="icon-group" close-after-click @click="setNewMemberType(api.PrincipalTypes.GROUP)">
|
||||
Gruppe hinzufügen
|
||||
</NcActionButton>
|
||||
<NcActionButton v-for="organizationProvider of organizationProviders"
|
||||
:key="organizationProvider"
|
||||
icon="icon-group"
|
||||
close-after-click
|
||||
@click="setNewMemberType(api.PrincipalTypes.ROLE, { organizationProvider })">
|
||||
{{ organizationProvider }} Organisation Rolle hinzufügen
|
||||
</NcActionButton>
|
||||
</NcActions>
|
||||
</div>
|
||||
<div v-if="newMemberType" class="new-item">
|
||||
<NcButton type="tertiary" @click="setNewMemberType(null)">
|
||||
<template #icon>
|
||||
<Close />
|
||||
</template>
|
||||
</NcButton>
|
||||
<!--<MemberListNewUser v-if="newMemberType === api.PrincipalTypes.USER" :resource-id="props.resourceId" @add-member="(principalId) => addMember(api.PrincipalTypes.USER, principalId)" />-->
|
||||
<!--<MemberListNewGroup v-if="newMemberType === api.PrincipalTypes.GROUP" :resource-id="props.resourceId" @add-member="(principalId) => addMember(api.PrincipalTypes.GROUP, principalId)" />-->
|
||||
<MemberListNewRole v-if="newMemberType === api.PrincipalTypes.ROLE" :resource-id="props.resourceId" :organization-provider="newMemberAdditionalParameters?.organizationProvider" @add-member="(principalId) => addMember(api.PrincipalTypes.ROLE, principalId)" />
|
||||
</div>
|
||||
<table>
|
||||
<thead style="display: contents;">
|
||||
<tr>
|
||||
<th />
|
||||
<th>Name</th>
|
||||
<th>
|
||||
<div style="display: flex; align-items: center;">
|
||||
<span>Typ</span>
|
||||
<HelpCircle v-tooltip="'Für Manager gelten die oben ausgewählten Ordnermanager Berechtigungen, für Mitglieder die Ordnermitglieder Berechtigungen. Manager haben auf diese Einstellungen Zugriff.'" style="margin-left: 5px;" :size="15" />
|
||||
</div>
|
||||
</th>
|
||||
<th>Aktion</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody style="display: contents">
|
||||
<tr v-if="loading">
|
||||
<td colspan="4" style="grid-column-start: 1; grid-column-end: 5">
|
||||
<NcLoadingIcon :size="50" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-if="!loading && !members.length">
|
||||
<td colspan="4" style="grid-column-start: 1; grid-column-end: 5">
|
||||
<NcEmptyContent title="Keine Mitglieder" />
|
||||
</td>
|
||||
</tr>
|
||||
<MemberListItem v-for="member in members"
|
||||
:key="member.id"
|
||||
:member="member"
|
||||
@update="updateMember"
|
||||
@delete="deleteMember" />
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
table {
|
||||
width: 100%;
|
||||
margin-bottom: 14px;
|
||||
display: grid;
|
||||
grid-template-columns: max-content minmax(30px, auto) max-content max-content;
|
||||
}
|
||||
table tr {
|
||||
display: contents;
|
||||
}
|
||||
table td, table th {
|
||||
padding: 8px;
|
||||
}
|
||||
.title {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
margin-top: 24px;
|
||||
}
|
||||
h3 {
|
||||
font-weight: bold;
|
||||
margin-right: 24px;
|
||||
}
|
||||
.new-item {
|
||||
display: flex;
|
||||
}
|
||||
</style>
|
|
@ -1 +0,0 @@
|
|||
export { default } from "./MemberList.vue"
|
|
@ -6,7 +6,7 @@ import { NcLoadingIcon, NcCheckboxRadioSwitch, NcButton, NcTextField } from '@ne
|
|||
import BackupRestore from "vue-material-design-icons/BackupRestore.vue";
|
||||
import Delete from "vue-material-design-icons/Delete.vue";
|
||||
|
||||
import MemberList from "../components/MemberList/index.js";
|
||||
import ResourceMembersList from "../components/MemberList/ResourceMembersList.vue";
|
||||
import Permissions from "../components/Permissions/index.js";
|
||||
import ConfirmDeleteDialog from "../components/ConfirmDeleteDialog.vue";
|
||||
import ModalView from '../ModalView.vue';
|
||||
|
@ -31,7 +31,11 @@ const resourceNameValid = computed(() => {
|
|||
});
|
||||
|
||||
const saveName = async () => {
|
||||
resource.value = await api.updateResource(resource.value.id, { name: currentResourceName.value });
|
||||
resource.value = await api.updateResource(resource.value.id, { name: currentResourceName.value }, "model+members");
|
||||
};
|
||||
|
||||
const saveInheritManagers = async (inheritManagers) => {
|
||||
resource.value = await api.updateResource(resource.value.id, { inheritManagers }, "model+members");
|
||||
};
|
||||
|
||||
watch(() => props.resourceId, async (newResourceId) => {
|
||||
|
@ -43,28 +47,54 @@ watch(() => props.resourceId, async (newResourceId) => {
|
|||
|
||||
const saveActive = async (active) => {
|
||||
resourceActiveLoading.value = true;
|
||||
resource.value = await api.updateResource(resource.value.id, { active });
|
||||
resource.value = await api.updateResource(resource.value.id, { active }, "model+members");
|
||||
resourceActiveLoading.value = false;
|
||||
};
|
||||
|
||||
const savePermission = async ({ field, value }) => {
|
||||
resource.value = await api.updateResource(resource.value.id, {
|
||||
[field]: value,
|
||||
});
|
||||
}, "model+members");
|
||||
};
|
||||
|
||||
const switchToSnapshotRestoreView = () => {
|
||||
|
||||
};
|
||||
|
||||
const addMember = async (principalType, principalId) => {
|
||||
resource.value.members.push(await api.createResourceMember(resource.value.id, {
|
||||
permissionLevel: api.ResourceMemberPermissionLevels.MEMBER,
|
||||
principalType,
|
||||
principalId,
|
||||
}));
|
||||
};
|
||||
|
||||
const updateMember = async (memberId, updateResourceMemberDto) => {
|
||||
const member = await api.updateResourceMember(memberId, updateResourceMemberDto);
|
||||
resource.value.members = resource.value.members.map((m) => m.id === member.id ? member : m);
|
||||
};
|
||||
|
||||
const deleteMember = async (memberId) => {
|
||||
await api.deleteResourceMember(memberId);
|
||||
resource.value.members = resource.value.members.filter((m) => m.id !== memberId);
|
||||
};
|
||||
|
||||
const snapshotIntegrationActive = loadState('organization_folders', 'snapshot_integration_active', false);
|
||||
|
||||
const organizationProviders = ref([]);
|
||||
|
||||
api.getOrganizationProviders().then((providers) => {
|
||||
organizationProviders.value = providers;
|
||||
});
|
||||
|
||||
const validResourceMemberPrincipalTypes = api.PrincipalTypes;
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ModalView :has-back-button="true" :has-next-step-button="false" :has-last-step-button="false" :title="'Resource Settings'" :loading="loading" v-slot="">
|
||||
<h3>Eigenschaften</h3>
|
||||
<div class="name-input-container">
|
||||
<div class="resource-general-settings">
|
||||
<NcTextField :value.sync="currentResourceName"
|
||||
:error="!resourceNameValid"
|
||||
:label-visible="!resourceNameValid"
|
||||
|
@ -77,10 +107,16 @@ const snapshotIntegrationActive = loadState('organization_folders', 'snapshot_in
|
|||
@trailing-button-click="saveName"
|
||||
@blur="() => currentResourceName = currentResourceName.trim()"
|
||||
@keyup.enter="saveName" />
|
||||
<NcCheckboxRadioSwitch :checked="resource.inheritManagers" @update:checked="saveInheritManagers">Manager aus oberer Ebene vererben</NcCheckboxRadioSwitch>
|
||||
</div>
|
||||
<h3>Berechtigungen</h3>
|
||||
<Permissions :resource="resource" @permissionUpdated="savePermission" />
|
||||
<MemberList :members="resource?.members" />
|
||||
<ResourceMembersList :resource-id="resource.id"
|
||||
:members="resource?.members"
|
||||
:organizationProviders="organizationProviders"
|
||||
@add-member="addMember"
|
||||
@update-member="updateMember"
|
||||
@delete-member="deleteMember"/>
|
||||
<h3>Einstellungen</h3>
|
||||
<div class="settings-group">
|
||||
<NcButton v-if="snapshotIntegrationActive" @click="switchToSnapshotRestoreView">
|
||||
|
|
Loading…
Reference in a new issue