<commit_before><% environment.context_class.instance_eval { include ImagesHelper } %>

var Sharing = {
  addPermission: function (permission, preserveAccessType) {
    // Update if already existing, otherwise add a new row
    for (var i = 0; i < Sharing.permissionsTable.permissions.length; i++) {
      var p = Sharing.permissionsTable.permissions[i];
      if (p.contributor_type == permission.contributor_type && p.contributor_id == permission.contributor_id) {
        if (preserveAccessType)
          permission.access_type = p.access_type;
        Sharing.permissionsTable.permissions.splice(i, 1, permission);
        return false;
      }
    }

    // This ensures that if a project permission is added, and that project is associated with the resource, it gains
    //  the "isMandatory" flag.
    if (permission.contributor_type === 'Project') {
      for (var j = 0; j < Sharing.projectsSelector.selected.length; j++) {
        if (Sharing.projectsSelector.selected[j].id === permission.contributor_id) {
          permission.isMandatory = true;
          break;
        }
      }
    }

    Sharing.permissionsTable.permissions.push(permission);
  },

  // Add a permission when a new project is associated with the resource via the dropdown menu
  addPermissionForProject: function (project) {
      Sharing.addPermission({
        contributor_type: 'Project',
        contributor_id: project.id,
        title: project.title,
        access_type: Sharing.associatedProjectAccessType,
        isMandatory: true }, true);
  },

  removePermissionForProject: function (project) {
    for (var i = 0; i < Sharing.permissionsTable.permissions.length; i++) {
      if (Sharing.permissionsTable.permissions[i].contributor_id === project.id)
        break;
    }
    if (confirm('Do you want to want to remove any permissions for ' + project.title + '?')) {
      Sharing.permissionsTable.permissions.splice(i, 1);
    } else {
      Sharing.permissionsTable.permissions[i].isMandatory = false;
    }
  },

  requestInstitutionsUrl: '<%= Rails.application.routes.url_helpers.request_institutions_projects_path %>',
  requestAllInstitutionsUrl: '<%= Rails.application.routes.url_helpers.request_all_institutions_path %>',

  accessTypes: {
    noAccess: <%= Policy::NO_ACCESS %>,
    visible: <%= Policy::VISIBLE %>,
    accessible: <%= Policy::ACCESSIBLE %>,
    editing: <%= Policy::EDITING %>,
    managing: <%= Policy::MANAGING %>
  },

  associatedProjectAccessType: <%= Seek::Config.default_associated_projects_access_type %>,
  allVisitorsAccessType: <%= Seek::Config.default_all_visitors_access_type %>,
  maxPublicAccessType: <%= Policy.max_public_access_type %>,

  permissionsChanged: function () {
    if (originalPolicy.access_type !== Sharing.permissionsTable.publicPermission.access_type)
      return true;
    if (originalPolicy.permissions.length !== Sharing.permissionsTable.permissions.length)
      return true;
    for (var i = 0; i < Sharing.permissionsTable.permissions.length; i++) {
      for (var j = 0; j < originalPolicy.permissions.length; j++) {
          var p1 = Sharing.permissionsTable.permissions[i];
          var p2 = originalPolicy.permissions[j];
          if (p1.contributor_type == p2.contributor_type &&
              p1.contributor_id == p2.contributor_id &&
              p1.access_type !== p2.access_type)
              return true;
      }
    }

    return false;
  },

  applyPolicy: function (policy) {
    Sharing.permissionsTable.permissions = policy.permissions;
    Sharing.permissionsTable.publicPermission.access_type = policy.access_type;
  }
};

Vue.component('permissions-table', {
  props: ['publicPermission', 'permissions'],
  template:
  '<table class="permissions-table" id="permissions-table">' +
  '<thead>' +
  '<tr>' +
  '<th class="name-column"></th>' +
  '<th class="permission-column" v-for="accessType in accessTypes" :class="accessType.classes">{{ accessType.title }}</th>' +
  '<th class="actions-column"></th>' +
  '</tr>' +
  '</thead>' +
  '<tbody>' +
  '<tr is="permission-row" class="public-permission-row" :permission="publicPermission" :access-types="accessTypes" :public-access-type="publicPermission.access_type" field-prefix-orig="policy_attributes"></tr>' +
  '<tr is="permission-row" v-for="(permission, index) in sortedPermissions" :index="index" :permission="permission" :access-types="accessTypes" :public-access-type="publicPermission.access_type" v-on:delete-permission="deletePermission(index)"></tr>' +
  '</tbody>'+
  '</table>',
  data: function () {
    return {
      accessTypes: [
        { title: 'No Access', value: Sharing.accessTypes.noAccess, classes: 'no-access' },
        { title: 'View', value: Sharing.accessTypes.visible },
        { title: 'Download', value: Sharing.accessTypes.accessible },
        { title: 'Edit', value: Sharing.accessTypes.editing },
        { title: 'Manage', value: Sharing.accessTypes.managing }
      ]
    };
  },
  computed: {
    sortedPermissions: function () {
      return this.permissions.sort(function (a, b) {
        return (b.isMandatory || false) - (a.isMandatory || false);
      });
    }
  },
  methods: {
    deletePermission: function (index) {
      this.permissions.splice(index, 1);
    }
  }
});

Vue.component('permission-row', {
  props: ['index', 'permission', 'accessTypes', 'publicAccessType', 'fieldPrefixOrig'],
  template:
  '<tr class="permission-row" :class="{ mandatory: permission.isMandatory, hidden: permission.contributor_type === \'FavouriteGroup\' }">' +
  '<td class="name-cell" :title="permission.title"><span class="type-icon-wrapper"><img :src="typeIcon" class="type-icon" :title="permission.contributor_type || \'All visitors\'"/></span> {{ permission.title }}' +
  '<input v-if="permission.contributor_type" type="hidden" :name="fieldPrefix+\'[contributor_type]\'" v-model="permission.contributor_type"/>' +
  '<input v-if="permission.contributor_id" type="hidden" :name="fieldPrefix+\'[contributor_id]\'" v-model="permission.contributor_id"/>' +
  '</td>' +
  '<td is="privilege-cell" v-for="accessType in accessTypes" :fieldPrefix="fieldPrefix" :permission="permission" :access-type="accessType" :public-access-type="publicAccessType"></td>' +
  '<td class="actions-cell">'+
  '<a v-if="!permission.isMandatory" @click="$emit(\'delete-permission\')" class="clickable remove-button" title="Remove this permission">' +
  '<span class="glyphicon glyphicon-remove" aria-hidden="true"></span>' +
  '</a>' +
  '</td>' +
  '</tr>',
  computed: {
    fieldPrefix: function () {
      return (this.fieldPrefixOrig ? this.fieldPrefixOrig : 'policy_attributes[permissions_attributes][' + this.index + ']');
    },
    typeIcon: function () {
      switch(this.permission.contributor_type) {
        case 'Person':
          return '<%= asset_path(icon_filename_for_key('person')) %>';
        case 'Project':
          return '<%= asset_path(icon_filename_for_key('project')) %>';
        case 'Institution':
          return '<%= asset_path(icon_filename_for_key('institution')) %>';
        case 'WorkGroup':
          return '<%= asset_path(icon_filename_for_key('work_group')) %>';
      }

      return '<%= asset_path icon_filename_for_key('world') %>';
    }
  }
});

Vue.component('privilege-cell', {
  props: ['fieldPrefix', 'permission', 'accessType', 'publicAccessType'],
  template:
  '<td class="privilege-cell" :class="classes" @click="toggleValue">' +
  '<input v-if="!disabled" autocomplete="off" type="radio" :name="fieldPrefix+\'[access_type]\'" v-model="permission.access_type" :value="accessType.value"/>' +
  '</td>',
  computed: {
    disabled: function () {
      //return (this.permission.isPublic ? (this.accessType.value > Sharing.maxPublicAccessType) : (this.accessType.value < this.publicAccessType));
      return (this.permission.isPublic ? (this.accessType.value > Sharing.maxPublicAccessType) : false);
    },
    enabled: function () {
      return this.permission.access_type === this.accessType.value ||
          (this.accessType.value !== Sharing.accessTypes.noAccess && this.permission.access_type > this.accessType.value);
    },
    classes: function () {
      return { 'enabled': !this.disabled && this.enabled,
        'disabled': this.disabled,
        'no-access': this.accessType.value === Sharing.accessTypes.noAccess };
    }
  },
  methods: {
    toggleValue: function () {
      if (!this.disabled) {
        // If the existing setting is clicked, decrease the access type
        if (this.permission.access_type === this.accessType.value &&
            this.accessType.value !== Sharing.accessTypes.noAccess) {
          this.permission.access_type = this.accessType.value - 1;
        } else {
          this.permission.access_type = this.accessType.value;
        }
      }
    }
  }
});
<commit_msg>Ensure default policies aren't modified<commit_after><% environment.context_class.instance_eval { include ImagesHelper } %>

var Sharing = {
  addPermission: function (permission, preserveAccessType) {
    // Update if already existing, otherwise add a new row
    for (var i = 0; i < Sharing.permissionsTable.permissions.length; i++) {
      var p = Sharing.permissionsTable.permissions[i];
      if (p.contributor_type == permission.contributor_type && p.contributor_id == permission.contributor_id) {
        if (preserveAccessType)
          permission.access_type = p.access_type;
        Sharing.permissionsTable.permissions.splice(i, 1, permission);
        return false;
      }
    }

    // This ensures that if a project permission is added, and that project is associated with the resource, it gains
    //  the "isMandatory" flag.
    if (permission.contributor_type === 'Project') {
      for (var j = 0; j < Sharing.projectsSelector.selected.length; j++) {
        if (Sharing.projectsSelector.selected[j].id === permission.contributor_id) {
          permission.isMandatory = true;
          break;
        }
      }
    }

    Sharing.permissionsTable.permissions.push(permission);
  },

  // Add a permission when a new project is associated with the resource via the dropdown menu
  addPermissionForProject: function (project) {
      Sharing.addPermission({
        contributor_type: 'Project',
        contributor_id: project.id,
        title: project.title,
        access_type: Sharing.associatedProjectAccessType,
        isMandatory: true }, true);
  },

  removePermissionForProject: function (project) {
    for (var i = 0; i < Sharing.permissionsTable.permissions.length; i++) {
      if (Sharing.permissionsTable.permissions[i].contributor_id === project.id)
        break;
    }
    if (confirm('Do you want to want to remove any permissions for ' + project.title + '?')) {
      Sharing.permissionsTable.permissions.splice(i, 1);
    } else {
      Sharing.permissionsTable.permissions[i].isMandatory = false;
    }
  },

  requestInstitutionsUrl: '<%= Rails.application.routes.url_helpers.request_institutions_projects_path %>',
  requestAllInstitutionsUrl: '<%= Rails.application.routes.url_helpers.request_all_institutions_path %>',

  accessTypes: {
    noAccess: <%= Policy::NO_ACCESS %>,
    visible: <%= Policy::VISIBLE %>,
    accessible: <%= Policy::ACCESSIBLE %>,
    editing: <%= Policy::EDITING %>,
    managing: <%= Policy::MANAGING %>
  },

  associatedProjectAccessType: <%= Seek::Config.default_associated_projects_access_type %>,
  allVisitorsAccessType: <%= Seek::Config.default_all_visitors_access_type %>,
  maxPublicAccessType: <%= Policy.max_public_access_type %>,

  permissionsChanged: function () {
    if (originalPolicy.access_type !== Sharing.permissionsTable.publicPermission.access_type)
      return true;
    if (originalPolicy.permissions.length !== Sharing.permissionsTable.permissions.length)
      return true;
    for (var i = 0; i < Sharing.permissionsTable.permissions.length; i++) {
      for (var j = 0; j < originalPolicy.permissions.length; j++) {
          var p1 = Sharing.permissionsTable.permissions[i];
          var p2 = originalPolicy.permissions[j];
          if (p1.contributor_type == p2.contributor_type &&
              p1.contributor_id == p2.contributor_id &&
              p1.access_type !== p2.access_type)
              return true;
      }
    }

    return false;
  },

  applyPolicy: function (policy) {
    Sharing.permissionsTable.permissions = policy.permissions.slice(); // Copy the permissions rather than just reference
    Sharing.permissionsTable.publicPermission.access_type = policy.access_type;
  }
};

Vue.component('permissions-table', {
  props: ['publicPermission', 'permissions'],
  template:
  '<table class="permissions-table" id="permissions-table">' +
  '<thead>' +
  '<tr>' +
  '<th class="name-column"></th>' +
  '<th class="permission-column" v-for="accessType in accessTypes" :class="accessType.classes">{{ accessType.title }}</th>' +
  '<th class="actions-column"></th>' +
  '</tr>' +
  '</thead>' +
  '<tbody>' +
  '<tr is="permission-row" class="public-permission-row" :permission="publicPermission" :access-types="accessTypes" :public-access-type="publicPermission.access_type" field-prefix-orig="policy_attributes"></tr>' +
  '<tr is="permission-row" v-for="(permission, index) in sortedPermissions" :index="index" :permission="permission" :access-types="accessTypes" :public-access-type="publicPermission.access_type" v-on:delete-permission="deletePermission(index)"></tr>' +
  '</tbody>'+
  '</table>',
  data: function () {
    return {
      accessTypes: [
        { title: 'No Access', value: Sharing.accessTypes.noAccess, classes: 'no-access' },
        { title: 'View', value: Sharing.accessTypes.visible },
        { title: 'Download', value: Sharing.accessTypes.accessible },
        { title: 'Edit', value: Sharing.accessTypes.editing },
        { title: 'Manage', value: Sharing.accessTypes.managing }
      ]
    };
  },
  computed: {
    sortedPermissions: function () {
      return this.permissions.sort(function (a, b) {
        return (b.isMandatory || false) - (a.isMandatory || false);
      });
    }
  },
  methods: {
    deletePermission: function (index) {
      this.permissions.splice(index, 1);
    }
  }
});

Vue.component('permission-row', {
  props: ['index', 'permission', 'accessTypes', 'publicAccessType', 'fieldPrefixOrig'],
  template:
  '<tr class="permission-row" :class="{ mandatory: permission.isMandatory, hidden: permission.contributor_type === \'FavouriteGroup\' }">' +
  '<td class="name-cell" :title="permission.title"><span class="type-icon-wrapper"><img :src="typeIcon" class="type-icon" :title="permission.contributor_type || \'All visitors\'"/></span> {{ permission.title }}' +
  '<input v-if="permission.contributor_type" type="hidden" :name="fieldPrefix+\'[contributor_type]\'" v-model="permission.contributor_type"/>' +
  '<input v-if="permission.contributor_id" type="hidden" :name="fieldPrefix+\'[contributor_id]\'" v-model="permission.contributor_id"/>' +
  '</td>' +
  '<td is="privilege-cell" v-for="accessType in accessTypes" :fieldPrefix="fieldPrefix" :permission="permission" :access-type="accessType" :public-access-type="publicAccessType"></td>' +
  '<td class="actions-cell">'+
  '<a v-if="!permission.isMandatory" @click="$emit(\'delete-permission\')" class="clickable remove-button" title="Remove this permission">' +
  '<span class="glyphicon glyphicon-remove" aria-hidden="true"></span>' +
  '</a>' +
  '</td>' +
  '</tr>',
  computed: {
    fieldPrefix: function () {
      return (this.fieldPrefixOrig ? this.fieldPrefixOrig : 'policy_attributes[permissions_attributes][' + this.index + ']');
    },
    typeIcon: function () {
      switch(this.permission.contributor_type) {
        case 'Person':
          return '<%= asset_path(icon_filename_for_key('person')) %>';
        case 'Project':
          return '<%= asset_path(icon_filename_for_key('project')) %>';
        case 'Institution':
          return '<%= asset_path(icon_filename_for_key('institution')) %>';
        case 'WorkGroup':
          return '<%= asset_path(icon_filename_for_key('work_group')) %>';
      }

      return '<%= asset_path icon_filename_for_key('world') %>';
    }
  }
});

Vue.component('privilege-cell', {
  props: ['fieldPrefix', 'permission', 'accessType', 'publicAccessType'],
  template:
  '<td class="privilege-cell" :class="classes" @click="toggleValue">' +
  '<input v-if="!disabled" autocomplete="off" type="radio" :name="fieldPrefix+\'[access_type]\'" v-model="permission.access_type" :value="accessType.value"/>' +
  '</td>',
  computed: {
    disabled: function () {
      //return (this.permission.isPublic ? (this.accessType.value > Sharing.maxPublicAccessType) : (this.accessType.value < this.publicAccessType));
      return (this.permission.isPublic ? (this.accessType.value > Sharing.maxPublicAccessType) : false);
    },
    enabled: function () {
      return this.permission.access_type === this.accessType.value ||
          (this.accessType.value !== Sharing.accessTypes.noAccess && this.permission.access_type > this.accessType.value);
    },
    classes: function () {
      return { 'enabled': !this.disabled && this.enabled,
        'disabled': this.disabled,
        'no-access': this.accessType.value === Sharing.accessTypes.noAccess };
    }
  },
  methods: {
    toggleValue: function () {
      if (!this.disabled) {
        // If the existing setting is clicked, decrease the access type
        if (this.permission.access_type === this.accessType.value &&
            this.accessType.value !== Sharing.accessTypes.noAccess) {
          this.permission.access_type = this.accessType.value - 1;
        } else {
          this.permission.access_type = this.accessType.value;
        }
      }
    }
  }
});

{'fraction_non_alphanumeric': 0.15288869306603514, 'fraction_numerical': 0.0018725560389932258, 'mean_word_length': 3.367003367003367, 'pattern_counts': {'":': 0, '<': 123, '<?xml version=': 0, '>': 117, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3936601', 'n_tokens_mistral': 5599, 'n_tokens_neox': 5392, 'n_words': 965}