Skip to content

Commit

Permalink
feat: new realms UI (#583)
Browse files Browse the repository at this point in the history
* feat: realms table added

* feat: realm dialog added (wip)

* feat: realm forms added
  • Loading branch information
ymarcon authored Jan 10, 2025
1 parent c9d875c commit 719aea6
Show file tree
Hide file tree
Showing 20 changed files with 1,417 additions and 204 deletions.
383 changes: 199 additions & 184 deletions agate-ui/src/auto-imports.d.ts

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion agate-ui/src/components/ApplicationDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@
<div class="row q-col-gutter-md">
<q-select
v-model="realmGroup.realm"
:label="t('realm')"
:label="t('realm.realm')"
:options="realmOptions"
emit-value
map-options
Expand Down
2 changes: 0 additions & 2 deletions agate-ui/src/components/ApplicationsTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
@click="onShowEdit(props.row)"
/>
<q-btn
v-if="!props.row.hasDatasource"
rounded
dense
flat
Expand Down Expand Up @@ -105,7 +104,6 @@ const columns = computed(() => [
]);
onMounted(() => {
applicationStore.init();
refresh();
});
Expand Down
1 change: 0 additions & 1 deletion agate-ui/src/components/GroupsTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
@click="onShowEdit(props.row)"
/>
<q-btn
v-if="!props.row.hasDatasource"
rounded
dense
flat
Expand Down
199 changes: 199 additions & 0 deletions agate-ui/src/components/RealmDialog.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
<template>
<q-dialog v-model="showDialog" persistent @hide="onHide">
<q-card class="dialog-md">
<q-card-section>
<div class="text-h6">{{ t(editMode ? 'realm.edit' : 'realm.add') }}</div>
</q-card-section>

<q-separator />

<q-card-section>
<q-form>
<q-input
v-model="selected.name"
:label="t('name') + ' *'"
:hint="t('name_hint')"
:disable="editMode"
dense
lazy-rules
:rules="[
(val) => !!val || t('name_required'),
(val) => (val?.trim().length ?? 0) >= 3 || t('name_min_length', { min: 3 }),
]"
class="q-mb-md"
/>
<div class="row q-col-gutter-md q-mb-md">
<div class="col-12 col-sm-3">
<q-toggle
:label="t(`realm.status.${selected.status}`)"
color="positive"
false-value="INACTIVE"
true-value="ACTIVE"
v-model="selected.status"
/>
</div>
<div class="col-12 col-sm-9">
<q-select
v-model="selected.type"
:label="t('type') + ' *'"
:options="typeOptions"
dense
emit-value
map-options
lazy-rules
@update:model-value="onTypeChange"
/>
</div>
</div>
<div class="row q-col-gutter-md q-mb-md">
<div class="col-12 col-sm-3">
<q-checkbox
v-model="selected.forSignup"
:label="t('realm.for_signup')"
@update:model-value="selected.groups = []"
/>
</div>
<div class="col-12 col-sm-9">
<q-select
v-model="selected.groups"
:label="t('groups')"
:hint="t('realm.groups_hint')"
:disable="!selected.forSignup"
:options="groupOptions"
dense
emit-value
map-options
multiple
use-chips
lazy-rules
/>
</div>
</div>
<q-input
v-model="selected.publicUrl"
:label="t('realm.public_url')"
:hint="t('realm.public_url_hint')"
dense
class="q-mb-md"
/>
<q-input
v-model="selected.domain"
:label="t('realm.sso_domain')"
:hint="t('realm.sso_domain_hint')"
dense
class="q-mb-md"
/>

<q-card bordered flat>
<q-card-section>
<oidc-form v-if="selected.type === 'agate-oidc-realm'" v-model="selected.content" />
<ldap-form v-if="selected.type === 'agate-ldap-realm'" v-model="selected.content" />
<ad-form v-if="selected.type === 'agate-ad-realm'" v-model="selected.content" />
<jdbc-form v-if="selected.type === 'agate-jdbc-realm'" v-model="selected.content" />
<user-info-mappings-form
v-if="selected.type === 'agate-oidc-realm'"
v-model="selected.userInfoMappings"
/>
</q-card-section>
</q-card>
</q-form>
</q-card-section>

<q-separator />

<q-card-actions align="right" class="bg-grey-3">
<q-btn flat :label="t('cancel')" color="secondary" @click="onCancel" v-close-popup />
<q-btn flat :label="t('save')" :disable="!isValid" color="primary" @click="onSave" />
</q-card-actions>
</q-card>
</q-dialog>
</template>

<script setup lang="ts">
import OidcForm from 'src/components/realms/OidcForm.vue';
import LdapForm from 'src/components/realms/LdapForm.vue';
import AdForm from 'src/components/realms/AdForm.vue';
import JdbcForm from 'src/components/realms/JdbcForm.vue';
import UserInfoMappingsForm from 'src/components/realms/UserInfoMappingsForm.vue';
import type { RealmConfigDto, RealmConfigSummaryDto } from 'src/models/Agate';
import { notifyError, notifySuccess } from 'src/utils/notify';
const { t } = useI18n();
const groupStore = useGroupStore();
const realmStore = useRealmStore();
interface DialogProps {
modelValue: boolean;
realmSummary: RealmConfigSummaryDto | undefined;
duplicate: boolean;
}
const props = defineProps<DialogProps>();
const emit = defineEmits(['update:modelValue', 'saved', 'cancel']);
const showDialog = ref(props.modelValue);
const selected = ref<RealmConfigDto>({} as RealmConfigDto);
const editMode = ref(false);
const typeOptions = computed(() =>
['agate-oidc-realm', 'agate-ad-realm', 'agate-ldap-realm', 'agate-jdbc-realm'].map((type) => ({
label: t(`realm.type.${type}`),
value: type,
})),
);
const groupOptions = computed(() => groupStore.groups?.map((group) => ({ label: group.name, value: group.id })) ?? []);
const isValid = computed(() => selected.value.name && selected.value.name.trim().length >= 3);
onMounted(() => {
groupStore.init();
});
watch(
() => props.modelValue,
(value) => {
showDialog.value = value;
if (props.realmSummary) {
realmStore.getConfig(props.realmSummary.name).then((config) => {
selected.value = config;
if (props.duplicate) {
config.name = '';
delete config.id;
}
});
} else {
selected.value = { type: typeOptions.value[0]?.value, status: 'INACTIVE', forSignup: false } as RealmConfigDto;
}
editMode.value = props.realmSummary !== undefined && !props.duplicate;
},
);
function onHide() {
emit('update:modelValue', false);
}
function onCancel() {
emit('cancel');
}
function onTypeChange() {
selected.value.content = '';
if (selected.value.type !== 'agate-oidc-realm') {
selected.value.userInfoMappings = [];
}
}
function onSave() {
realmStore
.save(selected.value)
.then(() => {
notifySuccess(t('realm.saved'));
emit('saved');
})
.catch(() => {
notifyError(t('realm.save_failed'));
})
.finally(() => {
emit('update:modelValue', false);
});
}
</script>
Loading

0 comments on commit 719aea6

Please sign in to comment.