app/views/server/universities/_sso_mapping.html.erb
<%
kind = object.class.name.underscore.gsub('/', '_')
if kind == 'university'
mapping_keys = ['email', 'first_name', 'last_name', 'role', 'mobile_phone', 'language', 'picture_url']
else
mapping_keys = ['email', 'first_name', 'last_name', 'mobile_phone', 'language', 'picture_url']
end
%>
<%# Include vue.js before call Vue.createApp %>
<%= javascript_include_tag 'vue' %>
<div id="app" v-cloak>
<div class="spinner-border text-primary" role="status">
<span class="sr-only"><%= t('loading') %></span>
</div>
<div class="app-form">
<draggable :list="fields" handle=".dragHandle" >
<div v-for="(field, index) in fields">
<div class="card">
<div class="card-header d-flex justify-content-between">
<div>
<i class="<%= Icon::SORT %> dragHandle"></i>
<a data-bs-toggle="collapse" :href="'#sso_mapping_collapse_' + index ">
{{index + 1}}. {{ field.sso_key }} -> {{ keys[field.internal_key]}}
</a>
</div>
<a
v-on:click="fields.splice(fields.indexOf(field), 1)"
title="Remove field">
<i class="<%= Icon::DELETE %>"></i>
</a>
</div>
<div class="card-body collapse pt-0" :id="'sso_mapping_collapse_' + index ">
<hr class="mt-0">
<div class="form-group">
<label for="" class="form-control-label"><%= t('university.sso_key') %> <abbr title="required">*</abbr></label>
<input
v-model="field.sso_key"
type="text" class="form-control">
</div>
<div class="form-group">
<label for="" class="form-control-label"><%= t('university.internal_key') %> <abbr title="required">*</abbr></label>
<select v-model="field.internal_key" id="" class="form-select" required>
<option v-for="(label, key) in keys" :value="key">{{ label }}</option>
</select>
</div>
<% if kind == 'university' %>
<div v-if="field.internal_key === 'role'">
<hr class="mt-4">
<% User.roles.keys.each do |role| %>
<div class="form-group">
<label for="" class="form-label"><%= t("activerecord.attributes.user.roles.#{role}") %></label>
<input v-model="field.roles.<%= role %>" type="text" class="form-control">
</div>
<% end %>
</div>
<% end %>
</div>
</div>
</div>
</draggable>
<a v-on:click="fields.push({sso_key: 'key', internal_key: 'email', roles: {}})" class="btn btn-primary btn-sm">
<%= t('add_field') %>
</a>
</div>
<textarea name="<%= kind %>[sso_mapping]" id="<%= kind %>_sso_mapping" rows="20" cols="200" class="d-none">
{{ JSON.stringify(fields) }}
</textarea>
</div>
<script nonce="<%= request.content_security_policy_nonce %>">
var app = Vue.createApp({
components: {
draggable: VueDraggableNext.VueDraggableNext,
},
data() {
return {
fields: <%= object.sso_mapping.blank? ? '[]' : object.sso_mapping.to_json.html_safe %>,
keys: <%= mapping_keys.map { |key| [key, User.human_attribute_name(key)] }.to_h.to_json.html_safe %>
}
}
});
window.addEventListener('load', function(){
setTimeout(function() {
app.mount('#app');
}, 1000);
});
</script>