Permissions.svelte 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. <script lang="ts">
  2. import { getContext, onMount } from 'svelte';
  3. const i18n = getContext('i18n');
  4. import Switch from '$lib/components/common/Switch.svelte';
  5. import Tooltip from '$lib/components/common/Tooltip.svelte';
  6. // Default values for permissions
  7. const defaultPermissions = {
  8. workspace: {
  9. models: false,
  10. knowledge: false,
  11. prompts: false,
  12. tools: false
  13. },
  14. chat: {
  15. controls: true,
  16. delete: true,
  17. edit: true,
  18. temporary: true,
  19. file_upload: true
  20. },
  21. features: {
  22. web_search: true,
  23. image_generation: true,
  24. code_interpreter: true
  25. }
  26. };
  27. export let permissions = {};
  28. // Reactive statement to ensure all fields are present in `permissions`
  29. $: {
  30. permissions = fillMissingProperties(permissions, defaultPermissions);
  31. }
  32. function fillMissingProperties(obj: any, defaults: any) {
  33. return {
  34. ...defaults,
  35. ...obj,
  36. workspace: { ...defaults.workspace, ...obj.workspace },
  37. chat: { ...defaults.chat, ...obj.chat },
  38. features: { ...defaults.features, ...obj.features }
  39. };
  40. }
  41. onMount(() => {
  42. permissions = fillMissingProperties(permissions, defaultPermissions);
  43. });
  44. </script>
  45. <div>
  46. <!-- <div>
  47. <div class=" mb-2 text-sm font-medium">{$i18n.t('Model Permissions')}</div>
  48. <div class="mb-2">
  49. <div class="flex justify-between items-center text-xs pr-2">
  50. <div class=" text-xs font-medium">{$i18n.t('Model Filtering')}</div>
  51. <Switch bind:state={permissions.model.filter} />
  52. </div>
  53. </div>
  54. {#if permissions.model.filter}
  55. <div class="mb-2">
  56. <div class=" space-y-1.5">
  57. <div class="flex flex-col w-full">
  58. <div class="mb-1 flex justify-between">
  59. <div class="text-xs text-gray-500">{$i18n.t('Model IDs')}</div>
  60. </div>
  61. {#if model_ids.length > 0}
  62. <div class="flex flex-col">
  63. {#each model_ids as modelId, modelIdx}
  64. <div class=" flex gap-2 w-full justify-between items-center">
  65. <div class=" text-sm flex-1 rounded-lg">
  66. {modelId}
  67. </div>
  68. <div class="shrink-0">
  69. <button
  70. type="button"
  71. on:click={() => {
  72. model_ids = model_ids.filter((_, idx) => idx !== modelIdx);
  73. }}
  74. >
  75. <Minus strokeWidth="2" className="size-3.5" />
  76. </button>
  77. </div>
  78. </div>
  79. {/each}
  80. </div>
  81. {:else}
  82. <div class="text-gray-500 text-xs text-center py-2 px-10">
  83. {$i18n.t('No model IDs')}
  84. </div>
  85. {/if}
  86. </div>
  87. </div>
  88. <hr class=" border-gray-100 dark:border-gray-700/10 mt-2.5 mb-1 w-full" />
  89. <div class="flex items-center">
  90. <select
  91. class="w-full py-1 text-sm rounded-lg bg-transparent {selectedModelId
  92. ? ''
  93. : 'text-gray-500'} placeholder:text-gray-300 dark:placeholder:text-gray-700 outline-hidden"
  94. bind:value={selectedModelId}
  95. >
  96. <option value="">{$i18n.t('Select a model')}</option>
  97. {#each $models.filter((m) => m?.owned_by !== 'arena') as model}
  98. <option value={model.id} class="bg-gray-50 dark:bg-gray-700">{model.name}</option>
  99. {/each}
  100. </select>
  101. <div>
  102. <button
  103. type="button"
  104. on:click={() => {
  105. if (selectedModelId && !permissions.model.model_ids.includes(selectedModelId)) {
  106. permissions.model.model_ids = [...permissions.model.model_ids, selectedModelId];
  107. selectedModelId = '';
  108. }
  109. }}
  110. >
  111. <Plus className="size-3.5" strokeWidth="2" />
  112. </button>
  113. </div>
  114. </div>
  115. </div>
  116. {/if}
  117. <div class=" space-y-1 mb-3">
  118. <div class="">
  119. <div class="flex justify-between items-center text-xs">
  120. <div class=" text-xs font-medium">{$i18n.t('Default Model')}</div>
  121. </div>
  122. </div>
  123. <div class="flex-1 mr-2">
  124. <select
  125. class="w-full bg-transparent outline-hidden py-0.5 text-sm"
  126. bind:value={permissions.model.default_id}
  127. placeholder="Select a model"
  128. >
  129. <option value="" disabled selected>{$i18n.t('Select a model')}</option>
  130. {#each permissions.model.filter ? $models.filter( (model) => filterModelIds.includes(model.id) ) : $models.filter((model) => model.id) as model}
  131. <option value={model.id} class="bg-gray-100 dark:bg-gray-700">{model.name}</option>
  132. {/each}
  133. </select>
  134. </div>
  135. </div>
  136. </div>
  137. <hr class=" border-gray-100 dark:border-gray-850 my-2" /> -->
  138. <div>
  139. <div class=" mb-2 text-sm font-medium">{$i18n.t('Workspace Permissions')}</div>
  140. <div class=" flex w-full justify-between my-2 pr-2">
  141. <div class=" self-center text-xs font-medium">
  142. {$i18n.t('Models Access')}
  143. </div>
  144. <Switch bind:state={permissions.workspace.models} />
  145. </div>
  146. <div class=" flex w-full justify-between my-2 pr-2">
  147. <div class=" self-center text-xs font-medium">
  148. {$i18n.t('Knowledge Access')}
  149. </div>
  150. <Switch bind:state={permissions.workspace.knowledge} />
  151. </div>
  152. <div class=" flex w-full justify-between my-2 pr-2">
  153. <div class=" self-center text-xs font-medium">
  154. {$i18n.t('Prompts Access')}
  155. </div>
  156. <Switch bind:state={permissions.workspace.prompts} />
  157. </div>
  158. <div class=" ">
  159. <Tooltip
  160. className=" flex w-full justify-between my-2 pr-2"
  161. content={$i18n.t(
  162. 'Warning: Enabling this will allow users to upload arbitrary code on the server.'
  163. )}
  164. placement="top-start"
  165. >
  166. <div class=" self-center text-xs font-medium">
  167. {$i18n.t('Tools Access')}
  168. </div>
  169. <Switch bind:state={permissions.workspace.tools} />
  170. </Tooltip>
  171. </div>
  172. </div>
  173. <hr class=" border-gray-100 dark:border-gray-850 my-2" />
  174. <div>
  175. <div class=" mb-2 text-sm font-medium">{$i18n.t('Chat Permissions')}</div>
  176. <div class=" flex w-full justify-between my-2 pr-2">
  177. <div class=" self-center text-xs font-medium">
  178. {$i18n.t('Allow Chat Controls')}
  179. </div>
  180. <Switch bind:state={permissions.chat.controls} />
  181. </div>
  182. <div class=" flex w-full justify-between my-2 pr-2">
  183. <div class=" self-center text-xs font-medium">
  184. {$i18n.t('Allow File Upload')}
  185. </div>
  186. <Switch bind:state={permissions.chat.file_upload} />
  187. </div>
  188. <div class=" flex w-full justify-between my-2 pr-2">
  189. <div class=" self-center text-xs font-medium">
  190. {$i18n.t('Allow Chat Delete')}
  191. </div>
  192. <Switch bind:state={permissions.chat.delete} />
  193. </div>
  194. <div class=" flex w-full justify-between my-2 pr-2">
  195. <div class=" self-center text-xs font-medium">
  196. {$i18n.t('Allow Chat Edit')}
  197. </div>
  198. <Switch bind:state={permissions.chat.edit} />
  199. </div>
  200. <div class=" flex w-full justify-between my-2 pr-2">
  201. <div class=" self-center text-xs font-medium">
  202. {$i18n.t('Allow Temporary Chat')}
  203. </div>
  204. <Switch bind:state={permissions.chat.temporary} />
  205. </div>
  206. </div>
  207. <hr class=" border-gray-100 dark:border-gray-850 my-2" />
  208. <div>
  209. <div class=" mb-2 text-sm font-medium">{$i18n.t('Features Permissions')}</div>
  210. <div class=" flex w-full justify-between my-2 pr-2">
  211. <div class=" self-center text-xs font-medium">
  212. {$i18n.t('Web Search')}
  213. </div>
  214. <Switch bind:state={permissions.features.web_search} />
  215. </div>
  216. <div class=" flex w-full justify-between my-2 pr-2">
  217. <div class=" self-center text-xs font-medium">
  218. {$i18n.t('Image Generation')}
  219. </div>
  220. <Switch bind:state={permissions.features.image_generation} />
  221. </div>
  222. <div class=" flex w-full justify-between my-2 pr-2">
  223. <div class=" self-center text-xs font-medium">
  224. {$i18n.t('Code Interpreter')}
  225. </div>
  226. <Switch bind:state={permissions.features.code_interpreter} />
  227. </div>
  228. </div>
  229. </div>