Compare commits

...

370 Commits

Author SHA1 Message Date
twwu
2a25ca2b2c feat: enhance online drive connection UI and add localization for connection status in dataset pipeline 2025-06-26 14:24:50 +08:00
twwu
3a9c79b09a feat: refactor data source handling and integrate OnlineDrive component in TestRunPanel 2025-06-26 13:46:12 +08:00
twwu
025b55ef3b feat: update tooltip text for test run mode in English and Chinese translations for clarity 2025-06-26 10:17:48 +08:00
twwu
cf7574bd10 feat: add FooterTips component and integrate it into TestRunPanel; extend DatasourceType enum with onlineDrive 2025-06-26 10:16:37 +08:00
twwu
c7cec120a6 feat: update variable validation regex for consistency in ExternalDataToolModal and schema 2025-06-25 17:07:31 +08:00
twwu
7d7fd18e65 Merge branch 'feat/rag-pipeline' of https://github.com/langgenius/dify into feat/rag-pipeline 2025-06-25 16:16:41 +08:00
twwu
c6ae9628af feat: refactor input variable handling and configurations in pipeline processing components 2025-06-25 16:15:59 +08:00
Joel
4631575c12 feat: can support choose current node var 2025-06-25 16:06:08 +08:00
zxhlyh
a4f4fea0a5 fix: note node delete 2025-06-25 16:01:45 +08:00
twwu
261b7cabc8 feat: enhance OnlineDocumentPreview with datasourceNodeId and implement preview functionality 2025-06-25 11:36:56 +08:00
twwu
ccd346d1da feat: add handling for RAG pipeline variables in node interactions 2025-06-25 10:40:48 +08:00
twwu
a866cbc6d7 feat: implement usePipeline hook for managing pipeline variables and refactor input field handling 2025-06-25 10:11:26 +08:00
zxhlyh
8f4a0d4a22 variable picker 2025-06-24 17:27:06 +08:00
twwu
1c51bef3cb fix: standardize capitalization in translation keys and remove unused group property in FieldListContainer 2025-06-24 14:25:58 +08:00
zxhlyh
c31754e6cd fix: create pipeline from customized 2025-06-24 11:12:39 +08:00
twwu
2414dbb5f8 feat: clear selected IDs on document deletion action in DocumentList component 2025-06-23 16:38:19 +08:00
twwu
916a8c76e7 fix: rename currentDocuments to currentDocument for consistency in online documents handling 2025-06-23 16:31:09 +08:00
twwu
896906ae77 feat: refactor layout structure in PipelineSettings component for improved responsiveness 2025-06-23 15:57:02 +08:00
twwu
dd792210f6 Merge branch 'feat/rag-pipeline' of https://github.com/langgenius/dify into feat/rag-pipeline 2025-06-23 15:38:34 +08:00
twwu
6ba4a4c165 feat: enhance website crawl functionality with state management and result handling 2025-06-23 15:38:24 +08:00
zxhlyh
48f53f3b9b workflow dependency 2025-06-23 15:02:57 +08:00
twwu
b9f59e3a75 Merge branch 'main' into feat/rag-pipeline 2025-06-23 13:59:05 +08:00
twwu
3899211c41 Merge branch 'feat/rag-pipeline' of https://github.com/langgenius/dify into feat/rag-pipeline 2025-06-19 15:58:01 +08:00
twwu
335e1e3602 feat: enhance pipeline settings with execution log and processing capabilities 2025-06-19 15:57:49 +08:00
zxhlyh
95ba55af4d fix: import dsl sync rag variables 2025-06-19 15:04:26 +08:00
twwu
55516c4e57 fix: add type checks for workspace roles in DatasetsLayout component 2025-06-19 10:56:03 +08:00
twwu
5d25199f42 refactor: update layout for creation title and content in StepThree component 2025-06-19 09:36:04 +08:00
twwu
387826674c Merge branch 'main' into feat/rag-pipeline 2025-06-19 09:34:09 +08:00
twwu
a103324f25 refactor: enhance UI components with new icons and improved styling in billing and dataset processes 2025-06-18 18:03:43 +08:00
twwu
f85e6a0dea feat: implement SSE for data source node processing and completion events, replacing previous run methods 2025-06-18 15:06:50 +08:00
twwu
4b3a54633f refactor: streamline dataset detail fetching and improve dataset list handling across components 2025-06-18 15:05:21 +08:00
zxhlyh
379c92bd82 Merge branch 'main' into feat/rag-pipeline 2025-06-18 13:47:06 +08:00
twwu
176b844cd5 refactor: consolidate DialogWrapper component usage and improve prop handling across input fields 2025-06-17 18:20:30 +08:00
zxhlyh
3164f90327 merge main 2025-06-17 17:44:08 +08:00
twwu
90ac52482c test: add unit tests for ActionButton component with various states and sizes 2025-06-17 16:48:52 +08:00
twwu
796797d12b feat: centralize variable type mapping by introducing VAR_TYPE_MAP in pipeline model 2025-06-17 16:28:50 +08:00
twwu
7ac0f0c08c feat: enhance processing components by adding runDisabled state and fetching indicators 2025-06-17 16:13:49 +08:00
twwu
5cc6a2bf33 refactor: update toast notification handling and improve context usage in DocumentDetail 2025-06-17 14:41:06 +08:00
twwu
33cd32382f feat: add indexing status batch and process rule hooks; refactor Notion page preview types 2025-06-17 11:29:56 +08:00
twwu
ce0bd421ae Merge branch 'main' into feat/rag-pipeline 2025-06-17 10:13:31 +08:00
twwu
f9d04c6975 Merge branch 'feat/rag-pipeline' of https://github.com/langgenius/dify into feat/rag-pipeline 2025-06-16 18:26:01 +08:00
twwu
ecb07a5d0d feat: enhance field list functionality by adding chosen and selected properties to SortableItem 2025-06-16 18:25:30 +08:00
zxhlyh
a165ba2059 merge main 2025-06-16 15:43:57 +08:00
zxhlyh
12fd2903d8 fix 2025-06-16 15:41:27 +08:00
twwu
0a2c569b3b fix: replace useGetDocLanguage with useDocLink for consistent documentation linking 2025-06-16 14:58:52 +08:00
twwu
9ab0d5fe60 Merge branch 'main' into feat/rag-pipeline 2025-06-16 14:25:58 +08:00
zxhlyh
1633626d23 Merge branch 'main' into feat/rag-pipeline 2025-06-16 11:44:42 +08:00
zxhlyh
abb2ed66e7 merge main 2025-06-16 10:15:24 +08:00
zxhlyh
5ae78f79b0 datasource dark theme 2025-06-16 10:00:14 +08:00
twwu
6622ce6ad8 fix: update formData construction in convertToInputFieldFormData for improved handling of optional fields
fix: adjust z-index value in DialogWrapper for proper stacking context
2025-06-13 18:32:36 +08:00
twwu
55906c8375 fix: remove unused billing plan logic from CreateFromDSLModal component 2025-06-13 18:01:01 +08:00
twwu
58842898e1 Merge branch 'feat/rag-pipeline' of https://github.com/langgenius/dify into feat/rag-pipeline 2025-06-13 16:42:27 +08:00
zxhlyh
26aff400e4 node default configs 2025-06-13 16:38:54 +08:00
twwu
4b11d29ede fix: update VAR_TYPE_MAP and initialData handling in useConfigurations for improved variable processing 2025-06-13 15:57:16 +08:00
twwu
5c228bca4f feat: replace TypeIcon with AppIcon in SelectDataSet component for improved icon display 2025-06-13 15:02:31 +08:00
twwu
b0107f4128 fix: update z-index values for DialogWrapper components to ensure proper stacking context 2025-06-13 14:44:32 +08:00
zxhlyh
55bff10f0d fix 2025-06-13 14:43:02 +08:00
Joel
45c9b77e82 fix: match var reg 2025-06-13 14:42:35 +08:00
twwu
80f656f79a fix: adjust layout and visibility conditions in CreateFormPipeline and ChunkPreview components 2025-06-13 11:38:26 +08:00
Joel
c891eb28fc fix: in prompt editor show vars error 2025-06-13 11:12:11 +08:00
twwu
b9fa3f54e9 refactor: refactor component imports and enhance layout for better responsiveness in dataset previews 2025-06-13 10:54:31 +08:00
twwu
4d2f904d72 feat: enhance WorkflowPreview and TemplateCard components with additional styling and className prop 2025-06-13 10:14:45 +08:00
twwu
26b7911177 Merge branch 'main' into feat/rag-pipeline 2025-06-13 09:49:03 +08:00
twwu
d994e6b6c7 feat: replace data source icons with AppIcon component in Item and DatasetItem 2025-06-12 18:11:00 +08:00
twwu
aba48bde0b feat: update SettingsModal to integrate keyword number handling and refactor index method logic 2025-06-12 18:06:00 +08:00
twwu
3e5d9884cb test: add unit tests for AppIcon component with various rendering scenarios 2025-06-12 17:33:28 +08:00
twwu
406d70e4a3 feat: integrate resetDatasetList hook into CreateOptions and TemplateCard components 2025-06-12 16:59:33 +08:00
zxhlyh
b367f48de6 add datasource category 2025-06-12 16:24:21 +08:00
twwu
6f17200dec refactor: update dataset handling to use runtime_mode instead of pipeline_id 2025-06-12 15:57:07 +08:00
twwu
b1f250862f Merge branch 'main' into feat/rag-pipeline 2025-06-12 15:18:19 +08:00
twwu
141d6b1abf feat: implement document settings and pipeline settings components with localization support 2025-06-12 15:13:15 +08:00
zxhlyh
a7eb534761 add datasource category 2025-06-12 15:05:36 +08:00
twwu
808f792f55 fix: update isPending condition and add indexing technique checks for segment detail and new segment modal 2025-06-12 11:11:03 +08:00
twwu
5c41922b8a fix: update file extension for downloaded DSL files and refine mutation keys for template operations 2025-06-11 18:11:38 +08:00
twwu
e52c905aa5 refactor: improve layout-main component structure and readability 2025-06-11 17:46:50 +08:00
twwu
7b9a3c1084 fix: update translation keys for document availability messages in English and Chinese 2025-06-11 17:42:45 +08:00
twwu
b7f9d7e94a Merge branch 'feat/rag-pipeline' of https://github.com/langgenius/dify into feat/rag-pipeline 2025-06-11 17:17:15 +08:00
twwu
92e6c52c0e refactor: update handleUseTemplate to use callback for dataset creation and improve error handling; change HTTP method for dependency check 2025-06-11 17:17:09 +08:00
zxhlyh
7dea7f77ac Merge branch 'main' into feat/rag-pipeline 2025-06-11 17:12:38 +08:00
zxhlyh
4d9b15e519 fix 2025-06-11 17:11:57 +08:00
twwu
f995436eec feat: implement chunk structure card and related hooks for dataset creation; update translations and refactor pipeline template fetching 2025-06-11 16:38:42 +08:00
twwu
45c76c1d68 refactor: rename icon property to icon_info in UpdateTemplateInfoRequest and related components 2025-06-11 13:39:07 +08:00
zxhlyh
6ecdac6344 pipeline preview 2025-06-11 11:51:19 +08:00
twwu
5c58b11b22 refactor: standardize pipeline template properties and improve related components 2025-06-11 11:25:08 +08:00
twwu
caa275fdbd refactor: remove unused websiteCrawlJobId state and related props from useWebsiteCrawl and CreateFormPipeline components; update loading and file preview components for consistent width 2025-06-11 10:50:03 +08:00
zxhlyh
5dbda7f4c5 merge main 2025-06-11 10:41:50 +08:00
zxhlyh
0564651f6f publish as customized pipeline 2025-06-11 10:40:49 +08:00
twwu
eff8108f1c refactor: update dataset model and improve batch action component 2025-06-11 10:24:07 +08:00
zxhlyh
0aeeee49f7 fix: draft sync 2025-06-10 17:39:20 +08:00
twwu
65ac022245 Merge branch 'feat/rag-pipeline' of https://github.com/langgenius/dify into feat/rag-pipeline 2025-06-10 16:06:58 +08:00
twwu
6e6090d5a9 test(SegmentedControl): add test cases 2025-06-10 16:06:42 +08:00
zxhlyh
978118f770 fix: datasource 2025-06-10 15:40:15 +08:00
zxhlyh
f4789d750d publish as pipeline 2025-06-10 15:19:47 +08:00
zxhlyh
5e71f7c825 publish as pipeline 2025-06-10 15:10:13 +08:00
twwu
d3eedaf0ec feat(i18n): add new translation entries for local file, website crawl, and online document 2025-06-10 14:22:09 +08:00
twwu
c91456de1b fix(ChunkStructure): add disabled prop to OptionCard component 2025-06-10 10:43:40 +08:00
zxhlyh
9e19ed4e67 knowledge base node checklisst 2025-06-10 10:16:13 +08:00
zxhlyh
5b4d04b348 Merge branch 'main' into feat/rag-pipeline 2025-06-10 09:38:06 +08:00
twwu
9b9640b3db refactor: remove job ID handling from website crawl components and update related hooks 2025-06-06 18:52:32 +08:00
twwu
3e2f12b065 refactor: update website crawl handling and improve parameter naming in pipeline processing 2025-06-06 17:00:34 +08:00
twwu
547bd3cc1b refactor: rename cancel editor handler and improve variable name validation in field list 2025-06-06 15:54:55 +08:00
twwu
83ca59e0f1 Merge branch 'feat/rag-pipeline' of https://github.com/langgenius/dify into feat/rag-pipeline 2025-06-06 15:35:50 +08:00
twwu
d725aa8791 Merge branch 'feat/rag-pipeline' of https://github.com/langgenius/dify into feat/rag-pipeline 2025-06-06 15:35:31 +08:00
zxhlyh
cc8ee0ff69 dsl 2025-06-06 15:35:19 +08:00
twwu
4a249c40b1 feat: enhance input field configurations with blur listeners and update translations for display name 2025-06-06 15:35:19 +08:00
zxhlyh
f9d0a7bdc8 Merge branch 'main' into feat/rag-pipeline 2025-06-06 15:01:27 +08:00
zxhlyh
e961722597 dsl 2025-06-06 15:00:37 +08:00
zxhlyh
3db864561e confirm publish 2025-06-06 14:22:15 +08:00
twwu
5193fa2118 fix: update condition for handling datasource selection in DataSourceOptions 2025-06-06 11:43:00 +08:00
zxhlyh
8e4165defe datasource 2025-06-06 10:55:13 +08:00
twwu
cf2ef93ad5 Merge branch 'main' into feat/rag-pipeline 2025-06-06 10:10:53 +08:00
twwu
cbf0864edc refactor: refactor online documents handling and update related components 2025-06-06 10:08:19 +08:00
twwu
bce2bdd0de Merge branch 'feat/rag-pipeline' of https://github.com/langgenius/dify into feat/rag-pipeline 2025-06-05 18:28:58 +08:00
twwu
82e7c8a2f9 refactor: update datasource handling and improve documentation properties in pipeline components 2025-06-05 18:28:48 +08:00
Joel
2acdb0a4ea fix: var type error in cal var type in data source type 2025-06-05 17:40:49 +08:00
twwu
350ea6be6e fix: correct spacing and formatting in variable utility functions 2025-06-05 17:32:03 +08:00
zxhlyh
f0413f359a datasource 2025-06-05 16:51:19 +08:00
Joel
90ca98ff3a fix: in node show rag var 2025-06-05 16:41:04 +08:00
Joel
d4a1d045f8 fix: to new var format 2025-06-05 16:36:41 +08:00
twwu
91fefa0e37 refactor: improve layout and event handling in Header and FieldItem components 2025-06-05 15:44:18 +08:00
zxhlyh
468bfdfed9 datasource 2025-06-05 15:07:29 +08:00
twwu
fdc4c36b77 refactor: replace useStore with useDatasetDetailContextWithSelector for pipeline ID retrieval 2025-06-05 14:05:27 +08:00
twwu
6286f368f1 refactor: replace ImagePlus icon with RiImageCircleAiLine and improve tab button styling 2025-06-05 11:21:17 +08:00
twwu
c83370f701 refactor: simplify workflow draft synchronization in InputFieldDialog 2025-06-05 11:07:28 +08:00
twwu
7506867fb9 Merge branch 'main' into feat/rag-pipeline 2025-06-05 10:29:18 +08:00
twwu
842136959b feat: update data source handling and improve processing parameters integration 2025-06-05 10:24:25 +08:00
twwu
4c2cc98ebc Merge branch 'feat/rag-pipeline' of https://github.com/langgenius/dify into feat/rag-pipeline 2025-06-04 18:37:25 +08:00
twwu
44b9f49ab1 feat: enhance field item interaction and add preprocessing parameters hooks 2025-06-04 18:37:19 +08:00
zxhlyh
a7fa5044e3 datasource 2025-06-04 18:09:31 +08:00
Joel
0bf0c7dbe8 feat: var type to inner 2025-06-04 17:34:22 +08:00
twwu
c9a4c66b07 fix: update input type from 'number-input' to 'number' for consistency 2025-06-04 16:58:08 +08:00
twwu
9934eac15c refactor: refactor data source handling and add form for document processing 2025-06-04 16:50:27 +08:00
Joel
c155afac29 chore: rename rag var spell errro 2025-06-04 16:43:24 +08:00
Joel
7080c9f279 fix: show rag vars names 2025-06-04 16:29:36 +08:00
zxhlyh
dfe091789c datasource 2025-06-04 15:48:29 +08:00
zxhlyh
4c9bf78363 knowledge base node checklist 2025-06-04 15:18:03 +08:00
twwu
3afd5e73c9 feat: enhance input field dialog with preview functionality and global inputs 2025-06-04 15:16:02 +08:00
Joel
cab491795a chore: some special to some fns 2025-06-04 14:54:11 +08:00
twwu
e290ddc3e5 Merge branch 'feat/rag-pipeline' of https://github.com/langgenius/dify into feat/rag-pipeline 2025-06-04 14:50:16 +08:00
twwu
db154e33b7 Merge branch 'main' into feat/rag-pipeline 2025-06-04 14:48:10 +08:00
zxhlyh
225402280e datasource auth 2025-06-04 11:39:31 +08:00
twwu
0a9f50e85f Merge branch 'main' into feat/rag-pipeline 2025-06-03 18:44:53 +08:00
twwu
ed1d71f4d0 Merge branch 'feat/rag-pipeline' of https://github.com/langgenius/dify into feat/rag-pipeline 2025-06-03 18:33:07 +08:00
twwu
7039ec33b9 refactor: update retrieval search method from invertedIndex to keywordSearch 2025-06-03 18:33:01 +08:00
Joel
025dc7c781 feat: can show rag vars 2025-06-03 18:32:52 +08:00
twwu
bad451d5ec Merge branch 'feat/rag-pipeline' of https://github.com/langgenius/dify into feat/rag-pipeline 2025-06-03 17:42:53 +08:00
twwu
87c15062e6 feat: enhance document processing with embedding and rule detail components 2025-06-03 17:42:40 +08:00
zxhlyh
163bae3aaf input rag variable 2025-06-03 16:07:58 +08:00
zxhlyh
b9c6496fea datasource default value & publish sync draft 2025-06-03 14:42:17 +08:00
twwu
5fb771218c fix: update types and improve data handling in pipeline components 2025-06-03 10:14:48 +08:00
twwu
898495b5c4 Merge branch 'feat/rag-pipeline' of https://github.com/langgenius/dify into feat/rag-pipeline 2025-05-30 15:54:46 +08:00
twwu
08624878cf fix: update ChunkStructureEnum values for consistency with model naming 2025-05-30 15:53:32 +08:00
zxhlyh
6fe473f0fa knowledge base node 2025-05-30 15:45:58 +08:00
Jyong
e1d658b482 Update build-push.yml 2025-05-30 15:26:51 +08:00
twwu
1274aaed5d fix: add dataset mutation context to Popup component 2025-05-30 15:17:19 +08:00
twwu
9be036e0ca Merge branch 'main' into feat/rag-pipeline 2025-05-30 15:10:16 +08:00
zxhlyh
558a280fc8 datasource type 2025-05-29 18:21:29 +08:00
twwu
2158c03231 fix: update button disabled state to reflect publishedAt status in Popup component 2025-05-29 17:53:08 +08:00
twwu
a61f1f8eb0 refactor: replace anchor tag with Link component for navigation in Actions 2025-05-29 17:42:00 +08:00
twwu
9f724c19db refactor: refactor navigation components to use Link for improved routing 2025-05-29 17:33:04 +08:00
twwu
4ae936b263 refactor: refactor navigation handling in dataset components to use button elements 2025-05-29 15:48:54 +08:00
twwu
80875a109a feat: add logic to handle navigation based on pipeline status in DatasetCard 2025-05-29 15:22:29 +08:00
zxhlyh
121e54f3e3 plugins page 2025-05-29 15:18:27 +08:00
zxhlyh
1c2c4b62f8 run & tracing 2025-05-29 14:31:35 +08:00
twwu
9176790adf feat: enhance dataset detail layout with button disable logic based on pipeline status 2025-05-29 14:06:12 +08:00
zxhlyh
6ff6525d1d test run 2025-05-29 11:30:42 +08:00
zxhlyh
71ce505631 data source panel 2025-05-29 11:03:22 +08:00
twwu
11dfe3713f refactor: enhance document upload flow with step indicators and file preview handling 2025-05-29 10:18:11 +08:00
zxhlyh
c4169f8aa0 Merge branch 'main' into feat/rag-pipeline 2025-05-29 09:39:36 +08:00
twwu
3005419573 feat: implement document upload steps and enhance test run panel with new hooks and components 2025-05-28 18:34:26 +08:00
twwu
cc7ad5ac97 feat: add input field variables change sync 2025-05-28 16:38:49 +08:00
zxhlyh
769b5e185a workflow init config staletime 2025-05-28 15:36:10 +08:00
twwu
9e763c9e87 feat: enhance file uploader and test run panel with batch upload limits and tooltips 2025-05-28 14:51:10 +08:00
zxhlyh
b9214ca76b knowledge base default data 2025-05-28 13:57:24 +08:00
twwu
29d2f2339b refactor: enhance document preview functionality and refactor form handling 2025-05-28 13:44:37 +08:00
zxhlyh
5ac1e3584d Merge branch 'main' into feat/rag-pipeline 2025-05-28 11:01:56 +08:00
twwu
dd0cf6fadc refactor: streamline data source type handling and improve FieldList props 2025-05-28 10:07:12 +08:00
zxhlyh
b320ebe2ba datasource variables 2025-05-27 18:44:29 +08:00
twwu
377093b776 fix: conditionally render FieldListContainer based on inputFields length 2025-05-27 18:19:10 +08:00
twwu
70119a054a fix: add is_preview flag to datasource submission and improve dataset card rendering logic 2025-05-27 17:54:39 +08:00
zxhlyh
69d1e3ec7d input field in datasource 2025-05-27 17:42:30 +08:00
twwu
365157c37d refactor: enhance action button logic to include workflow running state 2025-05-27 15:43:10 +08:00
zxhlyh
4bc0a1bd37 knowledge base node init 2025-05-27 15:28:35 +08:00
twwu
d6640f2adf refactor: streamline input field data conversion and enhance datasource component 2025-05-27 15:25:35 +08:00
twwu
987f845e79 Merge branch 'feat/rag-pipeline' of https://github.com/langgenius/dify into feat/rag-pipeline 2025-05-27 14:42:12 +08:00
zxhlyh
84daf49047 node meta data 2025-05-27 14:40:56 +08:00
twwu
31e183ef0d refactor: enhance datasource handling by adding fileExtensions support 2025-05-27 14:39:52 +08:00
twwu
754a1d1197 refactor: add DatasourceIcon component and update related hooks and options 2025-05-27 14:17:55 +08:00
twwu
049a6de4b3 refactor: update data source handling and replace icon implementation 2025-05-27 13:52:43 +08:00
zxhlyh
6bd28cadc4 datasource icon 2025-05-27 13:42:13 +08:00
zxhlyh
3b9a0b1d25 datasource icon 2025-05-27 11:27:25 +08:00
twwu
db963a638c Merge branch 'main' into feat/rag-pipeline 2025-05-27 11:03:49 +08:00
twwu
dcb4c9e84a refactor: refactor datasource type handling 2025-05-27 11:01:38 +08:00
twwu
d333645e09 Merge branch 'feat/rag-pipeline' of https://github.com/langgenius/dify into feat/rag-pipeline 2025-05-26 17:48:59 +08:00
twwu
2812c774c6 fix(i18n): Update economy index method description to include keyword count 2025-05-26 17:48:54 +08:00
zxhlyh
e2f3f0ae4c datasource 2025-05-26 17:47:03 +08:00
zxhlyh
e6c6fa8ed8 tool icon 2025-05-26 17:28:16 +08:00
zxhlyh
cef77a3717 datasource icon 2025-05-26 16:41:50 +08:00
zxhlyh
28726b6cf3 block selector 2025-05-26 16:33:08 +08:00
zxhlyh
dc2b63b832 Merge branch 'main' into feat/rag-pipeline 2025-05-26 15:58:15 +08:00
zxhlyh
0478fc9649 datasource node variable 2025-05-26 15:57:34 +08:00
zxhlyh
b5f88c77a3 datasource list 2025-05-26 14:13:59 +08:00
twwu
324c0d7b4c refactor: improve layout and styling in TestRunPanel and FilePreview components 2025-05-26 14:06:04 +08:00
twwu
13e3f17493 refactor: standardize terminology by renaming 'data-source' to 'datasource' across components and translations 2025-05-26 10:50:39 +08:00
twwu
841bd35ebb Merge branch 'feat/rag-pipeline' of https://github.com/langgenius/dify into feat/rag-pipeline 2025-05-26 09:49:15 +08:00
twwu
ccefd41606 refactor: rename InputType to InputTypeEnum and update related usages for consistency 2025-05-26 09:48:17 +08:00
zxhlyh
e7370766bd datasource 2025-05-23 18:19:28 +08:00
twwu
db4958be05 fix: fix modal handling in InputFieldEditor 2025-05-23 17:52:00 +08:00
twwu
ac049d938e Merge branch 'feat/rag-pipeline' of https://github.com/langgenius/dify into feat/rag-pipeline 2025-05-23 16:57:46 +08:00
twwu
3af61f4b5d refactor: update input type mappings and enums for consistency across components 2025-05-23 16:57:27 +08:00
zxhlyh
e19adbbbc5 datasource 2025-05-23 16:27:49 +08:00
twwu
c9bf99a1e2 refactor: update input variable types and initial data handling in pipeline components 2025-05-23 15:10:20 +08:00
zxhlyh
720ce79901 checklist & datasource icon 2025-05-23 14:26:06 +08:00
twwu
693107a6c8 Merge branch 'feat/rag-pipeline' of https://github.com/langgenius/dify into feat/rag-pipeline 2025-05-23 13:54:59 +08:00
twwu
583db24ee7 refactor: update CustomActions type to use structured props across form components 2025-05-23 13:54:49 +08:00
zxhlyh
7d92574e02 datasource panel 2025-05-23 11:51:17 +08:00
twwu
5aaa06c8b0 refactor: integrate routing for document creation in Popup component 2025-05-23 11:19:57 +08:00
twwu
52b773770b refactor: update datasource handling in InputFieldDialog and Datasource components 2025-05-23 11:07:48 +08:00
zxhlyh
23adc7d8a8 datasource 2025-05-23 10:47:31 +08:00
twwu
e3708bfa85 refactor: enhance ChunkPreview with form handling and preview functionality 2025-05-23 10:29:59 +08:00
twwu
7d65e9980c Merge branch 'main' into feat/rag-pipeline 2025-05-23 09:35:08 +08:00
twwu
21c24977d8 refactor: enhance document processing UI and functionality with new components and translations 2025-05-22 23:05:58 +08:00
zxhlyh
fe435c23c3 i18n 2025-05-22 17:44:07 +08:00
twwu
ead1209f98 Merge branch 'feat/rag-pipeline' of https://github.com/langgenius/dify into feat/rag-pipeline 2025-05-22 17:41:18 +08:00
twwu
3994bb1771 refactor: refactor document processing components and update translations 2025-05-22 17:39:39 +08:00
zxhlyh
327690e4a7 merge main 2025-05-22 16:45:13 +08:00
zxhlyh
c2a7e0e986 version panel 2025-05-22 16:43:30 +08:00
twwu
faf6b9ea03 refactor: refactor preview components 2025-05-22 14:49:40 +08:00
twwu
69a60101fe Merge branch 'feat/rag-pipeline' of https://github.com/langgenius/dify into feat/rag-pipeline 2025-05-21 16:37:08 +08:00
twwu
b18519b824 refactor: add create-from-pipeline page and associated components for document processing 2025-05-21 16:37:02 +08:00
zxhlyh
0d01025254 parallel check 2025-05-21 16:34:41 +08:00
zxhlyh
eef1542cb3 use available nodes 2025-05-21 15:51:05 +08:00
twwu
9aef4b6d6b refactor: Notion component and add NotionPageSelector for improved page selection 2025-05-21 14:02:37 +08:00
zxhlyh
7dba83754f Merge branch 'main' into feat/rag-pipeline 2025-05-21 13:42:28 +08:00
zxhlyh
e2585bc778 Merge branch 'main' into feat/rag-pipeline 2025-05-21 11:27:50 +08:00
twwu
cc6e2558ef Merge branch 'feat/rag-pipeline' of https://github.com/langgenius/dify into feat/rag-pipeline 2025-05-21 10:53:29 +08:00
twwu
20343facad refactor: website data source components and hooks 2025-05-21 10:53:18 +08:00
zxhlyh
eff123a11c checklist 2025-05-20 16:52:45 +08:00
twwu
cf73faf174 feat: add FileUploaderField and TextAreaField components; enhance BaseField to support file inputs 2025-05-20 15:09:30 +08:00
zxhlyh
55f4177b01 merge main 2025-05-20 14:03:54 +08:00
twwu
14a9052d60 refactor: update variable naming for consistency and improve data source handling in pipeline components 2025-05-20 11:42:22 +08:00
twwu
314a2f9be8 Merge branch 'feat/rag-pipeline' of https://github.com/langgenius/dify into feat/rag-pipeline 2025-05-19 18:21:29 +08:00
twwu
8eee344fbb fix: correct hover state logic and refactor environment variable handling in FieldItem and usePipelineInit 2025-05-19 18:21:17 +08:00
zxhlyh
0e0a266142 merge main 2025-05-19 18:11:45 +08:00
zxhlyh
7bce35913d i18n 2025-05-19 18:09:12 +08:00
twwu
7898dbd5bf Merge branch 'feat/rag-pipeline' of https://github.com/langgenius/dify into feat/rag-pipeline 2025-05-19 16:26:24 +08:00
twwu
bd1073ff1a refactor: update input variable types to use PipelineInputVarType and simplify form data handling 2025-05-19 16:26:13 +08:00
zxhlyh
1bbd572593 option card 2025-05-19 15:59:04 +08:00
zxhlyh
5199297f61 run and history 2025-05-19 14:23:40 +08:00
twwu
8d4ced227e fix: update click handler logic in OptionCard 2025-05-16 17:54:41 +08:00
zxhlyh
f481075f8f pipeline sync draft 2025-05-16 17:48:01 +08:00
zxhlyh
836cf6453e pipeline sync draft 2025-05-16 17:48:01 +08:00
twwu
4b7274f9a5 fix: update link in Form component and correct endpoint for related apps query 2025-05-16 16:49:43 +08:00
twwu
7de5585da6 refactor: replace SWR with custom hooks for dataset detail and related apps; update context usage in components 2025-05-16 16:32:25 +08:00
twwu
87dc80f6fa fix: add cursor pointer and hover effect to MemberItem; adjust padding in PermissionItem 2025-05-16 15:52:28 +08:00
twwu
a008c04331 refactor: standardize naming for load more handlers and navigation items across components 2025-05-16 15:43:28 +08:00
twwu
56b66b8a57 Merge branch 'feat/rag-pipeline' of https://github.com/langgenius/dify into feat/rag-pipeline 2025-05-16 15:15:00 +08:00
twwu
35a7add4e9 refactor: refactor pipeline-related components and services to use template terminology 2025-05-16 15:14:50 +08:00
zxhlyh
f1fe143962 add i18n 2025-05-16 14:53:39 +08:00
twwu
019ef74bf2 refactor: replace Container with List, update DatasetCard z-index, and implement useDatasetList for data fetching 2025-05-16 10:50:31 +08:00
zxhlyh
2670557258 merge main 2025-05-16 10:09:24 +08:00
zxhlyh
f5c297708b Merge branch 'main' into feat/rag-pipeline 2025-05-15 14:52:54 +08:00
zxhlyh
bf8324f7f7 tag filter 2025-05-15 14:52:00 +08:00
zxhlyh
b730d153ea Merge branch 'main' into feat/rag-pipeline 2025-05-15 10:27:47 +08:00
zxhlyh
11977596c9 merge main 2025-05-15 10:14:40 +08:00
twwu
612dca8b7d feat: add WorkflowPreview component to Details and define graph structure in PipelineTemplateByIdResponse 2025-05-14 18:20:29 +08:00
zxhlyh
53018289d4 workflow preview 2025-05-14 18:02:58 +08:00
twwu
958ff44707 refactor: simplify import DSL confirmation request structure 2025-05-14 16:27:59 +08:00
twwu
d910770b3c feat: add dataset_id to DSL import responses and update routing logic in CreateFromDSLModal 2025-05-14 16:00:17 +08:00
twwu
5a8f10520f feat: refactor template card actions and details to standardize prop names; add create modal for dataset creation 2025-05-14 15:53:17 +08:00
twwu
df928772c0 Merge branch 'feat/rag-pipeline' of https://github.com/langgenius/dify into feat/rag-pipeline 2025-05-14 14:49:10 +08:00
twwu
b713218cab feat: add DSL modal header and tab components; enhance pipeline import functionality 2025-05-14 14:49:01 +08:00
zxhlyh
9ea2123e7f component add readonly 2025-05-14 11:14:49 +08:00
twwu
de0cb06f8c feat: implement create dataset pipeline forms and modals 2025-05-14 10:48:54 +08:00
twwu
cfb6d59513 Merge branch 'main' into feat/rag-pipeline 2025-05-13 18:38:26 +08:00
twwu
4c30d1c1eb feat: Enhance InputFieldDialog and workflow hooks to handle ragPipelineVariables 2025-05-13 16:33:38 +08:00
twwu
5bb02c79cc Merge branch 'feat/rag-pipeline' of https://github.com/langgenius/dify into feat/rag-pipeline 2025-05-13 16:18:07 +08:00
twwu
0a891e5392 feat: Update retrieval method configuration to use new OptionCard component and improve layout 2025-05-13 16:17:59 +08:00
zxhlyh
f6978ce6b1 fix: pipeline init 2025-05-13 16:02:36 +08:00
twwu
4d68aadc1c Refactor: Replace IndexMethodRadio with IndexMethod component, add keyword number functionality, and update related translations 2025-05-13 15:35:21 +08:00
twwu
cef6463847 feat: Enhance dataset settings with chunk structure and icon selection 2025-05-13 11:07:31 +08:00
zxhlyh
39b8331f81 merge main 2025-05-09 18:20:56 +08:00
twwu
212d4c5899 Merge branch 'feat/rag-pipeline' of https://github.com/langgenius/dify into feat/rag-pipeline 2025-05-09 16:35:14 +08:00
twwu
97ec855df4 feat: enhance input field management with internationalization support and improved state handling 2025-05-09 16:35:09 +08:00
zxhlyh
d83b9b70e3 fix: import 2025-05-09 16:25:34 +08:00
zxhlyh
b51c18c2cf pipeline init 2025-05-09 15:53:31 +08:00
twwu
7e31da7882 refactor: update data source handling and improve internationalization support in test run panel 2025-05-09 12:56:57 +08:00
twwu
d9ed61287d Merge branch 'feat/rag-pipeline' of https://github.com/langgenius/dify into feat/rag-pipeline 2025-05-08 18:29:58 +08:00
twwu
6024dbe98d refactor: simplify type definitions in form components and update related configurations 2025-05-08 18:29:49 +08:00
zxhlyh
13ce6317f1 pipeline header 2025-05-08 18:27:44 +08:00
twwu
0099f2296d Merge branch 'feat/rag-pipeline' of https://github.com/langgenius/dify into feat/rag-pipeline 2025-05-08 16:26:37 +08:00
twwu
2d93bc6725 refactor: update DatasetInfo component layout and styling for better responsiveness 2025-05-08 16:26:30 +08:00
zxhlyh
cb52f9ecc5 pipeline header 2025-05-08 15:32:19 +08:00
twwu
1fbeb3a21a refactor: enhance dataset components with new icons and improve layout structure 2025-05-08 13:48:14 +08:00
twwu
38f1a42ce8 refactor: remove unused icon components and update imports in dataset components 2025-05-08 11:15:27 +08:00
twwu
3d11af2dd6 refactor: update imports for knowledge and pipeline components 2025-05-08 10:44:26 +08:00
twwu
d1fd5db7f8 Merge branch 'feat/rag-pipeline' of https://github.com/langgenius/dify into feat/rag-pipeline 2025-05-08 09:52:53 +08:00
twwu
c240cf3bb1 refactor: dataset creation to support pipeline datasets, update related types and hooks 2025-05-08 09:42:02 +08:00
zxhlyh
bbbcd68258 portal element 2025-05-07 18:14:26 +08:00
twwu
7ce9710229 feat: add pipeline template details and import functionality, enhance dataset pipeline management 2025-05-07 18:09:38 +08:00
zxhlyh
3f7f21ce70 show test run panel 2025-05-07 17:31:06 +08:00
zxhlyh
fa8ab4ea04 rag pipeline 2025-05-07 16:30:24 +08:00
zxhlyh
3f52f491d7 feat: knowledge base node 2025-05-07 15:08:37 +08:00
twwu
e86a3fc672 feat: Enhance dataset pipeline creation and management with new export and delete functionalities, improved internationalization, and refactor for better clarity 2025-05-07 14:29:01 +08:00
twwu
6f77f67427 Merge branch 'feat/rag-pipeline' of https://github.com/langgenius/dify into feat/rag-pipeline 2025-05-07 11:30:20 +08:00
twwu
4025cd0b46 feat: Refactor dataset pipeline creation components and add internationalization support 2025-05-07 11:30:13 +08:00
zxhlyh
3bbb22750c merge main 2025-05-06 18:28:44 +08:00
zxhlyh
d196872059 merge main 2025-05-06 17:31:48 +08:00
zxhlyh
a478d95950 feat: knowledge base node 2025-05-06 17:25:18 +08:00
twwu
12c060b795 feat: enhance dataset icon handling by making icon background and URL optional 2025-05-06 16:58:37 +08:00
twwu
c480c3d881 feat: enhance dataset detail layout with new icon structure and additional document count display 2025-05-06 16:37:21 +08:00
twwu
b4bccf5fef feat: Add External Knowledge Base and Pipeline icons, update DatasetCard component 2025-05-06 11:58:53 +08:00
twwu
14ad34af71 feat: enhance dataset creation UI with new pipeline list and edit functionality 2025-05-03 17:16:00 +08:00
twwu
7ed398267f Merge branch 'feat/rag-pipeline' of https://github.com/langgenius/dify into feat/rag-pipeline 2025-05-03 13:43:43 +08:00
twwu
fc9556e057 feat: add dataset creation components and functionality 2025-05-03 13:43:37 +08:00
zxhlyh
acf6872a50 fix: variable selector 2025-04-30 16:55:00 +08:00
twwu
e689f21a60 Merge branch 'feat/rag-pipeline' of https://github.com/langgenius/dify into feat/rag-pipeline 2025-04-30 14:16:25 +08:00
twwu
a7f9259e27 feat: new Dataset list 2025-04-30 14:16:13 +08:00
zxhlyh
a46b4e3616 Merge branch 'main' into feat/rag-pipeline 2025-04-29 16:27:49 +08:00
zxhlyh
e7e12c1d2e fix: node selector 2025-04-29 16:26:53 +08:00
zxhlyh
66176c4d71 fix: node default 2025-04-29 16:14:20 +08:00
twwu
2613a380b6 fix: Correct link path for creating datasets and optimize Link component with memoization 2025-04-29 15:47:29 +08:00
twwu
9392ce259f feat: Refactor dataset components and update translations for new dataset creation options 2025-04-29 15:44:32 +08:00
twwu
d1287f08b4 Merge branch 'feat/rag-pipeline' of https://github.com/langgenius/dify into feat/rag-pipeline 2025-04-29 10:44:37 +08:00
twwu
7ee8472a5f feat: Add SegmentedControl component with styling and option handling 2025-04-29 10:44:03 +08:00
zxhlyh
cdb615deeb knowledge base node 2025-04-28 18:37:18 +08:00
zxhlyh
abbba1d004 knowledge base node 2025-04-28 18:37:17 +08:00
twwu
53f2882077 feat: Implement document processing component with configuration and action handling 2025-04-28 15:55:24 +08:00
twwu
8f07e088f5 feat: Add JinaReader and WaterCrawl components with configurations and schema handling 2025-04-28 14:33:01 +08:00
twwu
f71b0eccb2 Refactor: dataset creation components and implement Firecrawl functionality 2025-04-28 13:33:16 +08:00
twwu
5b89d36ea1 feat: Update Zod schema generation for file types and upload methods to use new constants 2025-04-27 20:44:05 +08:00
twwu
7c3af74b0d feat: Update useConfigurations and useHiddenConfigurations to use InputVarType constants for type values 2025-04-27 20:34:25 +08:00
twwu
d1d83f8a2a feat: Enhance form components with hidden fields and popup properties for improved configuration 2025-04-27 20:17:50 +08:00
twwu
839fe12087 feat: Update OptionsField to use correct Options type and enhance Zod schema generation for options and select input types 2025-04-27 18:45:22 +08:00
twwu
fd8ee9f53e Refactor input field form components and schema 2025-04-27 15:29:11 +08:00
twwu
8367ae85de feat: Replace BaseVarType with BaseFieldType for consistent field type usage across components 2025-04-27 10:16:16 +08:00
twwu
d1f0e6e5c2 feat: Implement Zod schema generation for form validation and update form component usage 2025-04-27 09:56:48 +08:00
twwu
7deb44f864 feat: Add additional field components to form hook for enhanced functionality 2025-04-26 22:43:51 +08:00
twwu
d12e9b81e3 feat: Introduce new form field components and enhance existing ones with label options 2025-04-26 21:50:21 +08:00
twwu
b1fbaaed95 refactor: Simplify type checks for form field rendering and correct comment grammar 2025-04-25 18:39:05 +08:00
twwu
3f8b0b937c Merge branch 'feat/rag-pipeline' of https://github.com/langgenius/dify into feat/rag-pipeline 2025-04-25 18:13:57 +08:00
twwu
734c62998f feat: Implement dynamic form field rendering and replace SubmitButton with Actions component 2025-04-25 18:13:52 +08:00
zxhlyh
4792ca1813 knowledge base node 2025-04-25 17:24:47 +08:00
zxhlyh
076924bbd6 rag pipeline main 2025-04-25 11:32:17 +08:00
zxhlyh
97cf6b2d65 refactor workflow 2025-04-25 11:04:14 +08:00
twwu
f317ef2fe2 feat: Refactor NotionConnector integration and add Header component for improved UI in NotionPageSelector 2025-04-24 21:26:54 +08:00
zxhlyh
f7de55364f chore: refactor workflow 2025-04-24 16:29:58 +08:00
twwu
de30e9278c feat: Refactor Notion and LocalFile components to remove unused VectorSpaceFull prop and improve step indicator logic 2025-04-24 15:47:22 +08:00
twwu
44b9ce0951 feat: Implement Notion connector and related components for data source selection in the RAG pipeline 2025-04-24 15:32:04 +08:00
twwu
d768094376 feat: Refactor file upload configuration and validation logic 2025-04-24 13:46:50 +08:00
twwu
93f83086c1 feat: add CustomSelectField component and integrate with input field form 2025-04-23 22:16:19 +08:00
zxhlyh
8d9c252811 block selector & data source node 2025-04-22 16:46:33 +08:00
twwu
efb27eb443 feat: enhance FieldList component with sorting and dynamic input field management 2025-04-22 12:56:22 +08:00
twwu
5b8c43052e feat: implement input field dialog and related components for rag pipeline 2025-04-22 11:29:03 +08:00
twwu
e04ae927b6 Merge branch 'main' into feat/rag-pipeline 2025-04-22 10:14:28 +08:00
twwu
ac68d62d1c Merge branch 'main' into feat/rag-pipeline 2025-04-21 18:07:15 +08:00
zxhlyh
caa17b8fe9 rag pipeline store 2025-04-21 17:52:34 +08:00
twwu
cd1562ee24 Merge branch 'feat/rag-pipeline' of https://github.com/langgenius/dify into feat/rag-pipeline 2025-04-21 16:58:28 +08:00
twwu
47af1a9c42 feat: add InputField component and integrate into RagPipeline panel 2025-04-21 16:58:22 +08:00
zxhlyh
0cd6a427af add publisher 2025-04-21 14:41:41 +08:00
twwu
51165408ed feat: implement input field form with file upload settings and validation 2025-04-21 09:53:35 +08:00
zxhlyh
a2dc38f90a feat: add rag pipeline store slice 2025-04-18 15:51:40 +08:00
zxhlyh
a36436b585 feat: add rag pipeline store slice 2025-04-18 15:46:54 +08:00
zxhlyh
2d87823fc6 init rag pipeline 2025-04-18 14:56:34 +08:00
zxhlyh
d238da9826 Merge branch 'main' into feat/rag-pipeline 2025-04-18 14:00:58 +08:00
twwu
6eef5990c9 feat: enhance form components with additional props for validation and tooltips; add OptionsField component 2025-04-18 11:32:23 +08:00
twwu
0345eb4659 feat: add new form components including CheckboxField, NumberInputField, SelectField, TextField, and SubmitButton with updated input sizes 2025-04-17 13:33:33 +08:00
twwu
71f78e0d33 feat: replace existing page content with DemoForm component for improved layout 2025-04-16 14:16:56 +08:00
twwu
942648e9e9 feat: implement form components including CheckboxField, SelectField, TextField, and SubmitButton with validation 2025-04-16 14:16:32 +08:00
twwu
d841581679 feat: add IndeterminateIcon component and update Checkbox to support indeterminate state
refactor: remove mixed state handling and update related styles
fix: update useCallback dependencies for better performance
2025-04-15 17:30:18 +08:00
767 changed files with 28969 additions and 4447 deletions

View File

@@ -6,6 +6,7 @@ on:
- "main"
- "deploy/dev"
- "deploy/enterprise"
- "feat/rag-pipeline"
tags:
- "*"

View File

@@ -43,10 +43,10 @@ const AppDetailLayout: FC<IAppDetailLayoutProps> = (props) => {
const media = useBreakpoints()
const isMobile = media === MediaType.mobile
const { isCurrentWorkspaceEditor, isLoadingCurrentWorkspace } = useAppContext()
const { appDetail, setAppDetail, setAppSiderbarExpand } = useStore(useShallow(state => ({
const { appDetail, setAppDetail, setAppSidebarExpand } = useStore(useShallow(state => ({
appDetail: state.appDetail,
setAppDetail: state.setAppDetail,
setAppSiderbarExpand: state.setAppSiderbarExpand,
setAppSidebarExpand: state.setAppSidebarExpand,
})))
const [isLoadingAppDetail, setIsLoadingAppDetail] = useState(false)
const [appDetailRes, setAppDetailRes] = useState<App | null>(null)
@@ -57,8 +57,8 @@ const AppDetailLayout: FC<IAppDetailLayoutProps> = (props) => {
selectedIcon: NavIcon
}>>([])
const getNavigations = useCallback((appId: string, isCurrentWorkspaceEditor: boolean, mode: string) => {
const navs = [
const getNavigationConfig = useCallback((appId: string, isCurrentWorkspaceEditor: boolean, mode: string) => {
const navConfig = [
...(isCurrentWorkspaceEditor
? [{
name: t('common.appMenus.promptEng'),
@@ -92,8 +92,8 @@ const AppDetailLayout: FC<IAppDetailLayoutProps> = (props) => {
selectedIcon: RiDashboard2Fill,
},
]
return navs
}, [])
return navConfig
}, [t])
useDocumentTitle(appDetail?.name || t('common.menus.appDetail'))
@@ -101,10 +101,10 @@ const AppDetailLayout: FC<IAppDetailLayoutProps> = (props) => {
if (appDetail) {
const localeMode = localStorage.getItem('app-detail-collapse-or-expand') || 'expand'
const mode = isMobile ? 'collapse' : 'expand'
setAppSiderbarExpand(isMobile ? mode : localeMode)
setAppSidebarExpand(isMobile ? mode : localeMode)
// TODO: consider screen size and mode
// if ((appDetail.mode === 'advanced-chat' || appDetail.mode === 'workflow') && (pathname).endsWith('workflow'))
// setAppSiderbarExpand('collapse')
// setAppSidebarExpand('collapse')
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [appDetail, isMobile])
@@ -141,7 +141,7 @@ const AppDetailLayout: FC<IAppDetailLayoutProps> = (props) => {
}
else {
setAppDetail({ ...res, enable_sso: false })
setNavigation(getNavigations(appId, isCurrentWorkspaceEditor, res.mode))
setNavigation(getNavigationConfig(appId, isCurrentWorkspaceEditor, res.mode))
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [appDetailRes, isCurrentWorkspaceEditor, isLoadingAppDetail, isLoadingCurrentWorkspace])
@@ -161,7 +161,9 @@ const AppDetailLayout: FC<IAppDetailLayoutProps> = (props) => {
return (
<div className={cn(s.app, 'relative flex', 'overflow-hidden')}>
{appDetail && (
<AppSideBar title={appDetail.name} icon={appDetail.icon} icon_background={appDetail.icon_background as string} desc={appDetail.mode} navigation={navigation} />
<AppSideBar
navigation={navigation}
/>
)}
<div className="grow overflow-hidden bg-components-panel-bg">
{children}

View File

@@ -0,0 +1,10 @@
import React from 'react'
import CreateFromPipeline from '@/app/components/datasets/documents/create-from-pipeline'
const CreateFromPipelinePage = async () => {
return (
<CreateFromPipeline />
)
}
export default CreateFromPipelinePage

View File

@@ -2,10 +2,10 @@
import type { FC } from 'react'
import React, { useEffect, useMemo } from 'react'
import { usePathname } from 'next/navigation'
import useSWR from 'swr'
import { useTranslation } from 'react-i18next'
import { useBoolean } from 'ahooks'
import type { RemixiconComponentType } from '@remixicon/react'
import {
RiAttachmentLine,
RiEqualizer2Fill,
RiEqualizer2Line,
RiFileTextFill,
@@ -13,12 +13,8 @@ import {
RiFocus2Fill,
RiFocus2Line,
} from '@remixicon/react'
import {
PaperClipIcon,
} from '@heroicons/react/24/outline'
import { RiApps2AddLine, RiBookOpenLine, RiInformation2Line } from '@remixicon/react'
import { RiInformation2Line } from '@remixicon/react'
import classNames from '@/utils/classnames'
import { fetchDatasetDetail, fetchDatasetRelatedApps } from '@/service/datasets'
import type { RelatedAppResponse } from '@/models/datasets'
import AppSideBar from '@/app/components/app-sidebar'
import Loading from '@/app/components/base/loading'
@@ -30,6 +26,10 @@ import { useDocLink } from '@/context/i18n'
import { useAppContext } from '@/context/app-context'
import Tooltip from '@/app/components/base/tooltip'
import LinkedAppsPanel from '@/app/components/base/linked-apps-panel'
import { PipelineFill, PipelineLine } from '@/app/components/base/icons/src/vender/pipeline'
import { Divider } from '@/app/components/base/icons/src/vender/knowledge'
import NoLinkedAppsPanel from '@/app/components/datasets/no-linked-apps-panel'
import { useDatasetDetail, useDatasetRelatedApps } from '@/service/knowledge/use-dataset'
import useDocumentTitle from '@/hooks/use-document-title'
export type IAppDetailLayoutProps = {
@@ -38,81 +38,72 @@ export type IAppDetailLayoutProps = {
}
type IExtraInfoProps = {
isMobile: boolean
relatedApps?: RelatedAppResponse
documentCount?: number
expand: boolean
}
const ExtraInfo = ({ isMobile, relatedApps, expand }: IExtraInfoProps) => {
const [isShowTips, { toggle: toggleTips, set: setShowTips }] = useBoolean(!isMobile)
const ExtraInfo = React.memo(({
relatedApps,
documentCount,
expand,
}: IExtraInfoProps) => {
const { t } = useTranslation()
const docLink = useDocLink()
const hasRelatedApps = relatedApps?.data && relatedApps?.data?.length > 0
const relatedAppsTotal = relatedApps?.data?.length || 0
useEffect(() => {
setShowTips(!isMobile)
}, [isMobile, setShowTips])
return <div>
{hasRelatedApps && (
<>
{!isMobile && (
<Tooltip
position='right'
noDecoration
needsDelay
popupContent={
<LinkedAppsPanel
relatedApps={relatedApps.data}
isMobile={isMobile}
/>
}
>
<div className='system-xs-medium-uppercase inline-flex cursor-pointer items-center space-x-1 text-text-secondary'>
<span>{relatedAppsTotal || '--'} {t('common.datasetMenus.relatedApp')}</span>
<RiInformation2Line className='h-4 w-4' />
return (
<>
{!expand && (
<div className='flex items-center gap-x-0.5'>
<div className='flex grow flex-col px-2 pb-1.5 pt-1'>
<div className='system-md-semibold-uppercase text-text-secondary'>
{documentCount ?? '--'}
</div>
</Tooltip>
)}
{isMobile && <div className={classNames('uppercase text-xs text-text-tertiary font-medium pb-2 pt-4', 'flex items-center justify-center !px-0 gap-1')}>
{relatedAppsTotal || '--'}
<PaperClipIcon className='h-4 w-4 text-text-secondary' />
</div>}
</>
)}
{!hasRelatedApps && !expand && (
<Tooltip
position='right'
noDecoration
needsDelay
popupContent={
<div className='w-[240px] rounded-xl border-[0.5px] border-components-panel-border bg-components-panel-bg-blur p-4'>
<div className='inline-flex rounded-lg border-[0.5px] border-components-panel-border-subtle bg-background-default-subtle p-2'>
<RiApps2AddLine className='h-4 w-4 text-text-tertiary' />
<div className='system-2xs-medium-uppercase text-text-tertiary'>
{t('common.datasetMenus.documents')}
</div>
<div className='my-2 text-xs text-text-tertiary'>{t('common.datasetMenus.emptyTip')}</div>
<a
className='mt-2 inline-flex cursor-pointer items-center text-xs text-text-accent'
href={docLink('/guides/knowledge-base/integrate-knowledge-within-application')}
target='_blank' rel='noopener noreferrer'
>
<RiBookOpenLine className='mr-1 text-text-accent' />
{t('common.datasetMenus.viewDoc')}
</a>
</div>
}
>
<div className='system-xs-medium-uppercase inline-flex cursor-pointer items-center space-x-1 text-text-secondary'>
<span>{t('common.datasetMenus.noRelatedApp')}</span>
<RiInformation2Line className='h-4 w-4' />
<div className='py-2 pl-0.5 pr-1.5'>
<Divider className='text-test-divider-regular h-full w-fit' />
</div>
<div className='flex grow flex-col px-2 pb-1.5 pt-1'>
<div className='system-md-semibold-uppercase text-text-secondary'>
{relatedAppsTotal ?? '--'}
</div>
<Tooltip
position='bottom-start'
noDecoration
needsDelay
popupContent={
hasRelatedApps ? (
<LinkedAppsPanel
relatedApps={relatedApps.data}
isMobile={expand}
/>
) : <NoLinkedAppsPanel />
}
>
<div className='system-2xs-medium-uppercase flex cursor-pointer items-center gap-x-0.5 text-text-tertiary'>
<span>{t('common.datasetMenus.relatedApp')}</span>
<RiInformation2Line className='size-3' />
</div>
</Tooltip>
</div>
</div>
</Tooltip>
)}
</div>
}
)}
{expand && (
<div className={classNames('uppercase text-xs text-text-tertiary font-medium pb-2 pt-4', 'flex items-center justify-center !px-0 gap-1')}>
{relatedAppsTotal ?? '--'}
<RiAttachmentLine className='size-4 text-text-secondary' />
</div>
)}
</>
)
})
const DatasetDetailLayout: FC<IAppDetailLayoutProps> = (props) => {
const {
@@ -120,70 +111,98 @@ const DatasetDetailLayout: FC<IAppDetailLayoutProps> = (props) => {
params: { datasetId },
} = props
const pathname = usePathname()
const hideSideBar = /documents\/create$/.test(pathname)
const hideSideBar = pathname.endsWith('documents/create') || pathname.endsWith('documents/create-from-pipeline')
const { t } = useTranslation()
const { isCurrentWorkspaceDatasetOperator } = useAppContext()
const media = useBreakpoints()
const isMobile = media === MediaType.mobile
const { data: datasetRes, error, mutate: mutateDatasetRes } = useSWR({
url: 'fetchDatasetDetail',
datasetId,
}, apiParams => fetchDatasetDetail(apiParams.datasetId))
const { data: datasetRes, error, refetch: mutateDatasetRes } = useDatasetDetail(datasetId)
const { data: relatedApps } = useSWR({
action: 'fetchDatasetRelatedApps',
datasetId,
}, apiParams => fetchDatasetRelatedApps(apiParams.datasetId))
const { data: relatedApps } = useDatasetRelatedApps(datasetId)
const isButtonDisabledWithPipeline = useMemo(() => {
if (!datasetRes)
return true
if (datasetRes.provider === 'external')
return false
if (datasetRes.runtime_mode === 'general')
return false
return !datasetRes.is_published
}, [datasetRes])
const navigation = useMemo(() => {
const baseNavigation = [
{ name: t('common.datasetMenus.hitTesting'), href: `/datasets/${datasetId}/hitTesting`, icon: RiFocus2Line, selectedIcon: RiFocus2Fill },
{ name: t('common.datasetMenus.settings'), href: `/datasets/${datasetId}/settings`, icon: RiEqualizer2Line, selectedIcon: RiEqualizer2Fill },
{
name: t('common.datasetMenus.hitTesting'),
href: `/datasets/${datasetId}/hitTesting`,
icon: RiFocus2Line,
selectedIcon: RiFocus2Fill,
disabled: isButtonDisabledWithPipeline,
},
{
name: t('common.datasetMenus.settings'),
href: `/datasets/${datasetId}/settings`,
icon: RiEqualizer2Line,
selectedIcon: RiEqualizer2Fill,
disabled: false,
},
]
if (datasetRes?.provider !== 'external') {
if (datasetRes?.runtime_mode === 'rag_pipeline') {
baseNavigation.unshift({
name: t('common.datasetMenus.pipeline'),
href: `/datasets/${datasetId}/pipeline`,
icon: PipelineLine as RemixiconComponentType,
selectedIcon: PipelineFill as RemixiconComponentType,
disabled: false,
})
}
baseNavigation.unshift({
name: t('common.datasetMenus.documents'),
href: `/datasets/${datasetId}/documents`,
icon: RiFileTextLine,
selectedIcon: RiFileTextFill,
disabled: isButtonDisabledWithPipeline,
})
}
return baseNavigation
}, [datasetRes?.provider, datasetId, t])
}, [t, datasetId, isButtonDisabledWithPipeline, datasetRes?.provider, datasetRes?.runtime_mode])
useDocumentTitle(datasetRes?.name || t('common.menus.datasets'))
const setAppSiderbarExpand = useStore(state => state.setAppSiderbarExpand)
const setAppSidebarExpand = useStore(state => state.setAppSidebarExpand)
useEffect(() => {
const localeMode = localStorage.getItem('app-detail-collapse-or-expand') || 'expand'
const mode = isMobile ? 'collapse' : 'expand'
setAppSiderbarExpand(isMobile ? mode : localeMode)
}, [isMobile, setAppSiderbarExpand])
setAppSidebarExpand(isMobile ? mode : localeMode)
}, [isMobile, setAppSidebarExpand])
if (!datasetRes && !error)
return <Loading type='app' />
return (
<div className='flex grow overflow-hidden'>
{!hideSideBar && <AppSideBar
title={datasetRes?.name || '--'}
icon={datasetRes?.icon || 'https://static.dify.ai/images/dataset-default-icon.png'}
icon_background={datasetRes?.icon_background || '#F5F5F5'}
desc={datasetRes?.description || '--'}
isExternal={datasetRes?.provider === 'external'}
navigation={navigation}
extraInfo={!isCurrentWorkspaceDatasetOperator ? mode => <ExtraInfo isMobile={mode === 'collapse'} relatedApps={relatedApps} expand={mode === 'collapse'} /> : undefined}
iconType={datasetRes?.data_source_type === DataSourceType.NOTION ? 'notion' : 'dataset'}
/>}
<DatasetDetailContext.Provider value={{
indexingTechnique: datasetRes?.indexing_technique,
dataset: datasetRes,
mutateDatasetRes: () => mutateDatasetRes(),
mutateDatasetRes,
}}>
{!hideSideBar && (
<AppSideBar
navigation={navigation}
extraInfo={
!isCurrentWorkspaceDatasetOperator
? mode => <ExtraInfo relatedApps={relatedApps} expand={mode === 'collapse'} documentCount={datasetRes?.document_count} />
: undefined
}
iconType={datasetRes?.data_source_type === DataSourceType.NOTION ? 'notion' : 'dataset'}
/>
)}
<div className="grow overflow-hidden bg-background-default-subtle">{children}</div>
</DatasetDetailContext.Provider>
</div>

View File

@@ -0,0 +1,11 @@
'use client'
import RagPipeline from '@/app/components/rag-pipeline'
const PipelinePage = () => {
return (
<div className='h-full w-full overflow-x-auto'>
<RagPipeline />
</div>
)
}
export default PipelinePage

View File

@@ -8,8 +8,8 @@ const Settings = async () => {
return (
<div className='h-full overflow-y-auto'>
<div className='px-6 py-3'>
<div className='system-xl-semibold mb-1 text-text-primary'>{t('title')}</div>
<div className='flex flex-col gap-y-0.5 px-6 pb-2 pt-3'>
<div className='system-xl-semibold text-text-primary'>{t('title')}</div>
<div className='system-sm-regular text-text-tertiary'>{t('desc')}</div>
</div>
<Form />

View File

@@ -1,96 +0,0 @@
'use client'
import { useCallback, useEffect, useRef } from 'react'
import useSWRInfinite from 'swr/infinite'
import { debounce } from 'lodash-es'
import NewDatasetCard from './NewDatasetCard'
import DatasetCard from './DatasetCard'
import type { DataSetListResponse, FetchDatasetsParams } from '@/models/datasets'
import { fetchDatasets } from '@/service/datasets'
import { useAppContext } from '@/context/app-context'
import { useTranslation } from 'react-i18next'
const getKey = (
pageIndex: number,
previousPageData: DataSetListResponse,
tags: string[],
keyword: string,
includeAll: boolean,
) => {
if (!pageIndex || previousPageData.has_more) {
const params: FetchDatasetsParams = {
url: 'datasets',
params: {
page: pageIndex + 1,
limit: 30,
include_all: includeAll,
},
}
if (tags.length)
params.params.tag_ids = tags
if (keyword)
params.params.keyword = keyword
return params
}
return null
}
type Props = {
containerRef: React.RefObject<HTMLDivElement>
tags: string[]
keywords: string
includeAll: boolean
}
const Datasets = ({
containerRef,
tags,
keywords,
includeAll,
}: Props) => {
const { t } = useTranslation()
const { isCurrentWorkspaceEditor } = useAppContext()
const { data, isLoading, setSize, mutate } = useSWRInfinite(
(pageIndex: number, previousPageData: DataSetListResponse) => getKey(pageIndex, previousPageData, tags, keywords, includeAll),
fetchDatasets,
{ revalidateFirstPage: false, revalidateAll: true },
)
const loadingStateRef = useRef(false)
const anchorRef = useRef<HTMLAnchorElement>(null)
useEffect(() => {
loadingStateRef.current = isLoading
}, [isLoading, t])
const onScroll = useCallback(
debounce(() => {
if (!loadingStateRef.current && containerRef.current && anchorRef.current) {
const { scrollTop, clientHeight } = containerRef.current
const anchorOffset = anchorRef.current.offsetTop
if (anchorOffset - scrollTop - clientHeight < 100)
setSize(size => size + 1)
}
}, 50),
[setSize],
)
useEffect(() => {
const currentContainer = containerRef.current
currentContainer?.addEventListener('scroll', onScroll)
return () => {
currentContainer?.removeEventListener('scroll', onScroll)
onScroll.cancel()
}
}, [containerRef, onScroll])
return (
<nav className='grid shrink-0 grow grid-cols-1 content-start gap-4 px-12 pt-2 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4'>
{isCurrentWorkspaceEditor && <NewDatasetCard ref={anchorRef} />}
{data?.map(({ data: datasets }) => datasets.map(dataset => (
<DatasetCard key={dataset.id} dataset={dataset} onSuccess={mutate} />),
))}
</nav>
)
}
export default Datasets

View File

@@ -1,42 +0,0 @@
'use client'
import { useTranslation } from 'react-i18next'
import { basePath } from '@/utils/var'
import {
RiAddLine,
RiArrowRightLine,
} from '@remixicon/react'
import Link from 'next/link'
type CreateAppCardProps = {
ref?: React.Ref<HTMLAnchorElement>
}
const CreateAppCard = ({ ref }: CreateAppCardProps) => {
const { t } = useTranslation()
return (
<div className='bg-background-default-dimm flex min-h-[160px] flex-col rounded-xl border-[0.5px]
border-components-panel-border transition-all duration-200 ease-in-out'
>
<Link ref={ref} className='group flex grow cursor-pointer items-start p-4' href={`${basePath}/datasets/create`}>
<div className='flex items-center gap-3'>
<div className='flex h-10 w-10 items-center justify-center rounded-lg border border-dashed border-divider-regular bg-background-default-lighter
p-2 group-hover:border-solid group-hover:border-effects-highlight group-hover:bg-background-default-dodge'
>
<RiAddLine className='h-4 w-4 text-text-tertiary group-hover:text-text-accent' />
</div>
<div className='system-md-semibold text-text-secondary group-hover:text-text-accent'>{t('dataset.createDataset')}</div>
</div>
</Link>
<div className='system-xs-regular p-4 pt-0 text-text-tertiary'>{t('dataset.createDatasetIntro')}</div>
<Link className='group flex cursor-pointer items-center gap-1 rounded-b-xl border-t-[0.5px] border-divider-subtle p-4' href={`${basePath}/datasets/connect`}>
<div className='system-xs-medium text-text-tertiary group-hover:text-text-accent'>{t('dataset.connectDataset')}</div>
<RiArrowRightLine className='h-3.5 w-3.5 text-text-tertiary group-hover:text-text-accent' />
</Link>
</div>
)
}
CreateAppCard.displayName = 'CreateAppCard'
export default CreateAppCard

View File

@@ -0,0 +1,10 @@
import React from 'react'
import CreateFromPipeline from '@/app/components/datasets/create-from-pipeline'
const DatasetCreation = async () => {
return (
<CreateFromPipeline />
)
}
export default DatasetCreation

View File

@@ -1,12 +1,7 @@
'use client'
import { useTranslation } from 'react-i18next'
import Container from './Container'
import useDocumentTitle from '@/hooks/use-document-title'
import List from '../../components/datasets/list'
const AppList = () => {
const { t } = useTranslation()
useDocumentTitle(t('common.menus.datasets'))
return <Container />
const DatasetList = async () => {
return <List />
}
export default AppList
export default DatasetList

View File

@@ -1,11 +0,0 @@
import { create } from 'zustand'
type DatasetStore = {
showExternalApiPanel: boolean
setShowExternalApiPanel: (show: boolean) => void
}
export const useDatasetStore = create<DatasetStore>(set => ({
showExternalApiPanel: false,
setShowExternalApiPanel: show => set({ showExternalApiPanel: show }),
}))

View File

@@ -3,40 +3,89 @@ import type { FC } from 'react'
import React from 'react'
import { useTranslation } from 'react-i18next'
import AppIcon from '../base/app-icon'
const DatasetSvg = <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fillRule="evenodd" clipRule="evenodd" d="M0.833497 5.13481C0.833483 4.69553 0.83347 4.31654 0.858973 4.0044C0.88589 3.67495 0.94532 3.34727 1.10598 3.03195C1.34567 2.56155 1.72812 2.17909 2.19852 1.93941C2.51384 1.77875 2.84152 1.71932 3.17097 1.6924C3.48312 1.6669 3.86209 1.66691 4.30137 1.66693L7.62238 1.66684C8.11701 1.66618 8.55199 1.66561 8.95195 1.80356C9.30227 1.92439 9.62134 2.12159 9.88607 2.38088C10.1883 2.67692 10.3823 3.06624 10.603 3.50894L11.3484 5.00008H14.3679C15.0387 5.00007 15.5924 5.00006 16.0434 5.03691C16.5118 5.07518 16.9424 5.15732 17.3468 5.36339C17.974 5.68297 18.4839 6.19291 18.8035 6.82011C19.0096 7.22456 19.0917 7.65515 19.13 8.12356C19.1668 8.57455 19.1668 9.12818 19.1668 9.79898V13.5345C19.1668 14.2053 19.1668 14.7589 19.13 15.2099C19.0917 15.6784 19.0096 16.1089 18.8035 16.5134C18.4839 17.1406 17.974 17.6505 17.3468 17.9701C16.9424 18.1762 16.5118 18.2583 16.0434 18.2966C15.5924 18.3334 15.0387 18.3334 14.3679 18.3334H5.63243C4.96163 18.3334 4.40797 18.3334 3.95698 18.2966C3.48856 18.2583 3.05798 18.1762 2.65353 17.9701C2.02632 17.6505 1.51639 17.1406 1.19681 16.5134C0.990734 16.1089 0.908597 15.6784 0.870326 15.2099C0.833478 14.7589 0.833487 14.2053 0.833497 13.5345V5.13481ZM7.51874 3.33359C8.17742 3.33359 8.30798 3.34447 8.4085 3.37914C8.52527 3.41942 8.63163 3.48515 8.71987 3.57158C8.79584 3.64598 8.86396 3.7579 9.15852 4.34704L9.48505 5.00008L2.50023 5.00008C2.50059 4.61259 2.50314 4.34771 2.5201 4.14012C2.5386 3.91374 2.57 3.82981 2.59099 3.7886C2.67089 3.6318 2.79837 3.50432 2.95517 3.42442C2.99638 3.40343 3.08031 3.37203 3.30669 3.35353C3.54281 3.33424 3.85304 3.33359 4.3335 3.33359H7.51874Z" fill="#444CE7" />
</svg>
import Effect from '../base/effect'
import { useDatasetDetailContextWithSelector } from '@/context/dataset-detail'
import type { DataSet } from '@/models/datasets'
import { DOC_FORM_ICON_WITH_BG, DOC_FORM_TEXT } from '@/models/datasets'
import { useKnowledge } from '@/hooks/use-knowledge'
import Badge from '../base/badge'
import cn from '@/utils/classnames'
type Props = {
isExternal?: boolean
name: string
description: string
expand: boolean
extraInfo?: React.ReactNode
}
const DatasetInfo: FC<Props> = ({
name,
description,
isExternal,
expand,
extraInfo,
}) => {
const { t } = useTranslation()
const dataset = useDatasetDetailContextWithSelector(state => state.dataset) as DataSet
const iconInfo = dataset.icon_info || {
icon: '📙',
icon_type: 'emoji',
icon_background: '#FFF4ED',
icon_url: '',
}
const isExternalProvider = dataset.provider === 'external'
const { formatIndexingTechniqueAndMethod } = useKnowledge()
const chunkingModeIcon = dataset.doc_form ? DOC_FORM_ICON_WITH_BG[dataset.doc_form] : React.Fragment
const Icon = isExternalProvider ? DOC_FORM_ICON_WITH_BG.external : chunkingModeIcon
return (
<div className='pl-1 pt-1'>
<div className='mr-3 shrink-0'>
<AppIcon innerIcon={DatasetSvg} className='!border-[0.5px] !border-indigo-100 !bg-indigo-25' />
</div>
<div className={cn('relative flex flex-col', expand ? '' : 'p-1')}>
{expand && (
<div className='mt-2'>
<div className='system-md-semibold text-text-secondary'>
{name}
<>
<Effect className='-left-5 top-[-22px] opacity-15' />
<div className='flex flex-col gap-y-2 p-2'>
<div className='relative w-fit'>
<AppIcon
size='medium'
iconType={iconInfo.icon_type}
icon={iconInfo.icon}
background={iconInfo.icon_background}
imageUrl={iconInfo.icon_url}
/>
{(dataset.doc_form || isExternalProvider) && (
<div className='absolute -bottom-1 -right-1 z-10'>
<Icon className='size-4' />
</div>
)}
</div>
<>
<div className='flex flex-col gap-y-1'>
<div
className='system-md-semibold truncate text-text-secondary'
title={dataset.name}
>
{dataset.name}
</div>
<div className='system-2xs-medium-uppercase text-text-tertiary'>
{isExternalProvider && t('dataset.externalTag')}
{!isExternalProvider && dataset.doc_form && dataset.indexing_technique && (
<div className='flex items-center gap-x-1'>
<Badge>{t(`dataset.chunkingMode.${DOC_FORM_TEXT[dataset.doc_form]}`)}</Badge>
<Badge>{formatIndexingTechniqueAndMethod(dataset.indexing_technique, dataset.retrieval_model_dict?.search_method)}</Badge>
</div>
)}
</div>
</div>
<p className='system-xs-regular line-clamp-3 text-text-tertiary first-letter:capitalize'>
{dataset.description}
</p>
</>
</div>
<div className='system-2xs-medium-uppercase mt-1 text-text-tertiary'>{isExternal ? t('dataset.externalTag') : t('dataset.localDocs')}</div>
<div className='system-xs-regular my-3 text-text-tertiary first-letter:capitalize'>{description}</div>
</div>
</>
)}
{!expand && (
<AppIcon
size='medium'
iconType={iconInfo.icon_type}
icon={iconInfo.icon}
background={iconInfo.icon_background}
imageUrl={iconInfo.icon_url}
/>
)}
{extraInfo}
</div>

View File

@@ -3,7 +3,6 @@ import { useShallow } from 'zustand/react/shallow'
import { RiLayoutLeft2Line, RiLayoutRight2Line } from '@remixicon/react'
import NavLink from './navLink'
import type { NavIcon } from './navLink'
import AppBasic from './basic'
import AppInfo from './app-info'
import DatasetInfo from './dataset-info'
import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints'
@@ -12,39 +11,39 @@ import cn from '@/utils/classnames'
export type IAppDetailNavProps = {
iconType?: 'app' | 'dataset' | 'notion'
title: string
desc: string
isExternal?: boolean
icon: string
icon_background: string | null
navigation: Array<{
name: string
href: string
icon: NavIcon
selectedIcon: NavIcon
disabled?: boolean
}>
extraInfo?: (modeState: string) => React.ReactNode
}
const AppDetailNav = ({ title, desc, isExternal, icon, icon_background, navigation, extraInfo, iconType = 'app' }: IAppDetailNavProps) => {
const { appSidebarExpand, setAppSiderbarExpand } = useAppStore(useShallow(state => ({
const AppDetailNav = ({
navigation,
extraInfo,
iconType = 'app',
}: IAppDetailNavProps) => {
const { appSidebarExpand, setAppSidebarExpand } = useAppStore(useShallow(state => ({
appSidebarExpand: state.appSidebarExpand,
setAppSiderbarExpand: state.setAppSiderbarExpand,
setAppSidebarExpand: state.setAppSidebarExpand,
})))
const media = useBreakpoints()
const isMobile = media === MediaType.mobile
const expand = appSidebarExpand === 'expand'
const handleToggle = (state: string) => {
setAppSiderbarExpand(state === 'expand' ? 'collapse' : 'expand')
setAppSidebarExpand(state === 'expand' ? 'collapse' : 'expand')
}
useEffect(() => {
if (appSidebarExpand) {
localStorage.setItem('app-detail-collapse-or-expand', appSidebarExpand)
setAppSiderbarExpand(appSidebarExpand)
setAppSidebarExpand(appSidebarExpand)
}
}, [appSidebarExpand, setAppSiderbarExpand])
}, [appSidebarExpand, setAppSidebarExpand])
return (
<div
@@ -62,26 +61,12 @@ const AppDetailNav = ({ title, desc, isExternal, icon, icon_background, navigati
{iconType === 'app' && (
<AppInfo expand={expand} />
)}
{iconType === 'dataset' && (
{iconType !== 'app' && (
<DatasetInfo
name={title}
description={desc}
isExternal={isExternal}
expand={expand}
extraInfo={extraInfo && extraInfo(appSidebarExpand)}
/>
)}
{!['app', 'dataset'].includes(iconType) && (
<AppBasic
mode={appSidebarExpand}
iconType={iconType}
icon={icon}
icon_background={icon_background}
name={title}
type={desc}
isExternal={isExternal}
/>
)}
</div>
<div className='px-4'>
<div className={cn('mx-auto mt-1 h-[1px] bg-divider-subtle', !expand && 'w-6')} />
@@ -94,7 +79,14 @@ const AppDetailNav = ({ title, desc, isExternal, icon, icon_background, navigati
>
{navigation.map((item, index) => {
return (
<NavLink key={index} mode={appSidebarExpand} iconMap={{ selected: item.selectedIcon, normal: item.icon }} name={item.name} href={item.href} />
<NavLink
key={index}
mode={appSidebarExpand}
iconMap={{ selected: item.selectedIcon, normal: item.icon }}
name={item.name}
href={item.href}
disabled={!!item.disabled}
/>
)
})}
</nav>

View File

@@ -6,10 +6,10 @@ import classNames from '@/utils/classnames'
import type { RemixiconComponentType } from '@remixicon/react'
export type NavIcon = React.ComponentType<
React.PropsWithoutRef<React.ComponentProps<'svg'>> & {
title?: string | undefined
titleId?: string | undefined
}> | RemixiconComponentType
React.PropsWithoutRef<React.ComponentProps<'svg'>> & {
title?: string | undefined
titleId?: string | undefined
}> | RemixiconComponentType
export type NavLinkProps = {
name: string
@@ -19,6 +19,7 @@ export type NavLinkProps = {
normal: NavIcon
}
mode?: string
disabled?: boolean
}
export default function NavLink({
@@ -26,6 +27,7 @@ export default function NavLink({
href,
iconMap,
mode = 'expand',
disabled = false,
}: NavLinkProps) {
const segment = useSelectedLayoutSegment()
const formattedSegment = (() => {
@@ -39,13 +41,38 @@ export default function NavLink({
const isActive = href.toLowerCase().split('/')?.pop() === formattedSegment
const NavIcon = isActive ? iconMap.selected : iconMap.normal
if (disabled) {
return (
<button
key={name}
type='button'
disabled
className={classNames(
'opacity-30 text-components-menu-item-text hover:bg-state-base-hover group flex items-center h-9 rounded-md py-2 system-sm-medium cursor-not-allowed',
mode === 'expand' ? 'px-3' : 'px-2.5',
)}
title={mode === 'collapse' ? name : ''}
aria-disabled
>
<NavIcon
className={classNames(
'h-4 w-4 flex-shrink-0',
mode === 'expand' ? 'mr-2' : 'mr-0',
)}
aria-hidden="true"
/>
{mode === 'expand' && name}
</button>
)
}
return (
<Link
key={name}
href={href}
className={classNames(
isActive ? 'bg-state-accent-active text-text-accent font-semibold' : 'text-components-menu-item-text hover:bg-state-base-hover hover:text-components-menu-item-text-hover',
'group flex items-center h-9 rounded-md py-2 text-sm font-normal',
'group flex items-center h-9 rounded-md py-2 system-sm-medium',
mode === 'expand' ? 'px-3' : 'px-2.5',
)}
title={mode === 'collapse' ? name : ''}

View File

@@ -8,16 +8,13 @@ import {
import { useTranslation } from 'react-i18next'
import SettingsModal from '../settings-modal'
import type { DataSet } from '@/models/datasets'
import { DataSourceType } from '@/models/datasets'
import FileIcon from '@/app/components/base/file-icon'
import { Folder } from '@/app/components/base/icons/src/vender/solid/files'
import { Globe06 } from '@/app/components/base/icons/src/vender/solid/mapsAndTravel'
import ActionButton, { ActionButtonState } from '@/app/components/base/action-button'
import Drawer from '@/app/components/base/drawer'
import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints'
import Badge from '@/app/components/base/badge'
import { useKnowledge } from '@/hooks/use-knowledge'
import cn from '@/utils/classnames'
import AppIcon from '@/app/components/base/app-icon'
type ItemProps = {
className?: string
@@ -47,33 +44,26 @@ const Item: FC<ItemProps> = ({
const [isDeleting, setIsDeleting] = useState(false)
const iconInfo = config.icon_info || {
icon: '📙',
icon_type: 'emoji',
icon_background: '#FFF4ED',
icon_url: '',
}
return (
<div className={cn(
'group relative mb-1 flex h-10 w-full cursor-pointer items-center justify-between rounded-lg border-[0.5px] border-components-panel-border-subtle bg-components-panel-on-panel-item-bg px-2 last-of-type:mb-0 hover:bg-components-panel-on-panel-item-bg-hover',
isDeleting && 'border-state-destructive-border hover:bg-state-destructive-hover',
)}>
<div className='flex w-0 grow items-center space-x-1.5'>
{
config.data_source_type === DataSourceType.FILE && (
<div className='mr-2 flex h-6 w-6 shrink-0 items-center justify-center rounded-md border-[0.5px] border-[#E0EAFF] bg-[#F5F8FF]'>
<Folder className='h-4 w-4 text-[#444CE7]' />
</div>
)
}
{
config.data_source_type === DataSourceType.NOTION && (
<div className='mr-2 flex h-6 w-6 shrink-0 items-center justify-center rounded-md border-[0.5px] border-[#EAECF5]'>
<FileIcon type='notion' className='h-4 w-4' />
</div>
)
}
{
config.data_source_type === DataSourceType.WEB && (
<div className='mr-2 flex h-6 w-6 shrink-0 items-center justify-center rounded-md border-[0.5px] border-blue-100 bg-[#F5FAFF]'>
<Globe06 className='h-4 w-4 text-blue-600' />
</div>
)
}
<AppIcon
size='tiny'
iconType={iconInfo.icon_type}
icon={iconInfo.icon}
background={iconInfo.icon_type === 'image' ? undefined : iconInfo.icon_background}
imageUrl={iconInfo.icon_type === 'image' ? iconInfo.icon_url : undefined}
/>
<div className='system-sm-medium w-0 grow truncate text-text-secondary' title={config.name}>{config.name}</div>
</div>
<div className='ml-2 hidden shrink-0 items-center space-x-1 group-hover:flex'>

View File

@@ -21,10 +21,12 @@ type Value = {
type WeightedScoreProps = {
value: Value
onChange: (value: Value) => void
readonly?: boolean
}
const WeightedScore = ({
value,
onChange = noop,
readonly = false,
}: WeightedScoreProps) => {
const { t } = useTranslation()
@@ -37,8 +39,9 @@ const WeightedScore = ({
min={0}
step={0.1}
value={value.value[0]}
onChange={v => onChange({ value: [v, (10 - v * 10) / 10] })}
onChange={v => !readonly && onChange({ value: [v, (10 - v * 10) / 10] })}
trackClassName='weightedScoreSliderTrack'
disabled={readonly}
/>
<div className='mt-3 flex justify-between'>
<div className='system-xs-semibold-uppercase flex w-[90px] shrink-0 items-center text-util-colors-blue-light-blue-light-500'>

View File

@@ -5,7 +5,6 @@ import { useGetState, useInfiniteScroll } from 'ahooks'
import { useTranslation } from 'react-i18next'
import Link from 'next/link'
import produce from 'immer'
import TypeIcon from '../type-icon'
import Modal from '@/app/components/base/modal'
import type { DataSet } from '@/models/datasets'
import Button from '@/app/components/base/button'
@@ -15,6 +14,7 @@ import Badge from '@/app/components/base/badge'
import { useKnowledge } from '@/hooks/use-knowledge'
import cn from '@/utils/classnames'
import { basePath } from '@/utils/var'
import AppIcon from '@/app/components/base/app-icon'
export type ISelectDataSetProps = {
isShow: boolean
@@ -91,6 +91,7 @@ const SelectDataSet: FC<ISelectDataSetProps> = ({
const handleSelect = () => {
onSelect(selected)
}
return (
<Modal
isShow={isShow}
@@ -135,7 +136,13 @@ const SelectDataSet: FC<ISelectDataSetProps> = ({
>
<div className='mr-1 flex items-center overflow-hidden'>
<div className={cn('mr-2', !item.embedding_available && 'opacity-30')}>
<TypeIcon type="upload_file" size='md' />
<AppIcon
size='tiny'
iconType={item.icon_info.icon_type}
icon={item.icon_info.icon}
background={item.icon_info.icon_type === 'image' ? undefined : item.icon_info.icon_background}
imageUrl={item.icon_info.icon_type === 'image' ? item.icon_info.icon_url : undefined}
/>
</div>
<div className={cn('max-w-[200px] truncate text-[13px] font-medium text-text-secondary', !item.embedding_available && '!max-w-[120px] opacity-30')}>{item.name}</div>
{!item.embedding_available && (

View File

@@ -6,7 +6,7 @@ import { isEqual } from 'lodash-es'
import { RiCloseLine } from '@remixicon/react'
import { ApiConnectionMod } from '@/app/components/base/icons/src/vender/solid/development'
import cn from '@/utils/classnames'
import IndexMethodRadio from '@/app/components/datasets/settings/index-method-radio'
import IndexMethod from '@/app/components/datasets/settings/index-method'
import Divider from '@/app/components/base/divider'
import Button from '@/app/components/base/button'
import Input from '@/app/components/base/input'
@@ -31,6 +31,7 @@ import {
import { ModelTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
import { fetchMembers } from '@/service/common'
import type { Member } from '@/models/common'
import { IndexingType } from '@/app/components/datasets/create/step-two'
import { useDocLink } from '@/context/i18n'
type SettingsModalProps = {
@@ -55,8 +56,6 @@ const SettingsModal: FC<SettingsModalProps> = ({
const { data: embeddingsModelList } = useModelList(ModelTypeEnum.textEmbedding)
const {
modelList: rerankModelList,
defaultModel: rerankDefaultModel,
currentModel: isRerankDefaultModelValid,
} = useModelListAndDefaultModelAndCurrentProviderAndModel(ModelTypeEnum.rerank)
const { t } = useTranslation()
const docLink = useDocLink()
@@ -75,6 +74,7 @@ const SettingsModal: FC<SettingsModalProps> = ({
const [indexMethod, setIndexMethod] = useState(currentDataset.indexing_technique)
const [retrievalConfig, setRetrievalConfig] = useState(localeCurrentDataset?.retrieval_model_dict as RetrievalConfig)
const [keywordNumber, setKeywordNumber] = useState(currentDataset.keyword_number ?? 10)
const handleValueChange = (type: string, value: string) => {
setLocaleCurrentDataset({ ...localeCurrentDataset, [type]: value })
@@ -126,6 +126,7 @@ const SettingsModal: FC<SettingsModalProps> = ({
description,
permission,
indexing_technique: indexMethod,
keyword_number: keywordNumber,
retrieval_model: {
...retrievalConfig,
score_threshold: retrievalConfig.score_threshold_enabled ? retrievalConfig.score_threshold : 0,
@@ -247,17 +248,18 @@ const SettingsModal: FC<SettingsModalProps> = ({
<div className='system-sm-semibold text-text-secondary'>{t('datasetSettings.form.indexMethod')}</div>
</div>
<div className='grow'>
<IndexMethodRadio
disable={!localeCurrentDataset?.embedding_available}
<IndexMethod
disabled={!localeCurrentDataset?.embedding_available}
value={indexMethod}
onChange={v => setIndexMethod(v!)}
docForm={currentDataset.doc_form}
onChange={setIndexMethod}
currentValue={currentDataset.indexing_technique}
keywordNumber={keywordNumber}
onKeywordNumberChange={setKeywordNumber}
/>
</div>
</div>
)}
{indexMethod === 'high_quality' && (
{indexMethod === IndexingType.QUALIFIED && (
<div className={cn(rowClass)}>
<div className={labelClass}>
<div className='system-sm-semibold text-text-secondary'>{t('datasetSettings.form.embeddingModel')}</div>
@@ -336,7 +338,7 @@ const SettingsModal: FC<SettingsModalProps> = ({
</div>
</div>
<div>
{indexMethod === 'high_quality'
{indexMethod === IndexingType.QUALIFIED
? (
<RetrievalMethodConfig
value={retrievalConfig}

View File

@@ -89,9 +89,9 @@ type PublishConfig = {
const Configuration: FC = () => {
const { t } = useTranslation()
const { notify } = useContext(ToastContext)
const { appDetail, showAppConfigureFeaturesModal, setAppSiderbarExpand, setShowAppConfigureFeaturesModal } = useAppStore(useShallow(state => ({
const { appDetail, showAppConfigureFeaturesModal, setAppSidebarExpand, setShowAppConfigureFeaturesModal } = useAppStore(useShallow(state => ({
appDetail: state.appDetail,
setAppSiderbarExpand: state.setAppSiderbarExpand,
setAppSidebarExpand: state.setAppSidebarExpand,
showAppConfigureFeaturesModal: state.showAppConfigureFeaturesModal,
setShowAppConfigureFeaturesModal: state.setShowAppConfigureFeaturesModal,
})))
@@ -823,7 +823,7 @@ const Configuration: FC = () => {
{ id: `${Date.now()}-no-repeat`, model: '', provider: '', parameters: {} },
],
)
setAppSiderbarExpand('collapse')
setAppSidebarExpand('collapse')
}
if (isLoading) {

View File

@@ -153,7 +153,7 @@ const ExternalDataToolModal: FC<ExternalDataToolModalProps> = ({
return
}
if (localeData.variable && !/[a-zA-Z_]\w{0,29}/g.test(localeData.variable)) {
if (localeData.variable && !/^[a-zA-Z_]\w{0,29}$/.test(localeData.variable)) {
notify({ type: 'error', message: t('appDebug.varKeyError.notValid', { key: t('appDebug.feature.tools.modal.variableName.title') }) })
return
}

View File

@@ -15,7 +15,7 @@ type State = {
type Action = {
setAppDetail: (appDetail?: App & Partial<AppSSO>) => void
setAppSiderbarExpand: (state: string) => void
setAppSidebarExpand: (state: string) => void
setCurrentLogItem: (item?: IChatItem) => void
setCurrentLogModalActiveTab: (tab: string) => void
setShowPromptLogModal: (showPromptLogModal: boolean) => void
@@ -28,7 +28,7 @@ export const useStore = create<State & Action>(set => ({
appDetail: undefined,
setAppDetail: appDetail => set(() => ({ appDetail })),
appSidebarExpand: '',
setAppSiderbarExpand: appSidebarExpand => set(() => ({ appSidebarExpand })),
setAppSidebarExpand: appSidebarExpand => set(() => ({ appSidebarExpand })),
currentLogItem: undefined,
currentLogModalActiveTab: 'DETAIL',
setCurrentLogItem: currentLogItem => set(() => ({ currentLogItem })),

View File

@@ -3,6 +3,7 @@ import type { FC } from 'react'
import { useTranslation } from 'react-i18next'
import { RiCloseLine } from '@remixicon/react'
import Run from '@/app/components/workflow/run'
import { useStore } from '@/app/components/app/store'
type ILogDetail = {
runID: string
@@ -11,6 +12,7 @@ type ILogDetail = {
const DetailPanel: FC<ILogDetail> = ({ runID, onClose }) => {
const { t } = useTranslation()
const appDetail = useStore(state => state.appDetail)
return (
<div className='relative flex grow flex-col pt-3'>
@@ -18,7 +20,10 @@ const DetailPanel: FC<ILogDetail> = ({ runID, onClose }) => {
<RiCloseLine className='h-4 w-4 text-text-tertiary' />
</span>
<h1 className='system-xl-semibold shrink-0 px-4 py-1 text-text-primary'>{t('appLog.runDetail.workflowTitle')}</h1>
<Run runID={runID}/>
<Run
runDetailUrl={`/apps/${appDetail?.id}/workflow-runs/${runID}`}
tracingListUrl={`/apps/${appDetail?.id}/workflow-runs/${runID}/node-executions`}
/>
</div>
)
}

View File

@@ -0,0 +1,76 @@
import { render, screen } from '@testing-library/react'
import { ActionButton, ActionButtonState } from './index'
describe('ActionButton', () => {
test('renders button with default props', () => {
render(<ActionButton>Click me</ActionButton>)
const button = screen.getByRole('button', { name: 'Click me' })
expect(button).toBeInTheDocument()
expect(button.classList.contains('action-btn')).toBe(true)
expect(button.classList.contains('action-btn-m')).toBe(true)
})
test('renders button with xs size', () => {
render(<ActionButton size='xs'>Small Button</ActionButton>)
const button = screen.getByRole('button', { name: 'Small Button' })
expect(button.classList.contains('action-btn-xs')).toBe(true)
})
test('renders button with l size', () => {
render(<ActionButton size='l'>Large Button</ActionButton>)
const button = screen.getByRole('button', { name: 'Large Button' })
expect(button.classList.contains('action-btn-l')).toBe(true)
})
test('renders button with xl size', () => {
render(<ActionButton size='xl'>Extra Large Button</ActionButton>)
const button = screen.getByRole('button', { name: 'Extra Large Button' })
expect(button.classList.contains('action-btn-xl')).toBe(true)
})
test('applies correct state classes', () => {
const { rerender } = render(
<ActionButton state={ActionButtonState.Destructive}>Destructive</ActionButton>,
)
let button = screen.getByRole('button', { name: 'Destructive' })
expect(button.classList.contains('action-btn-destructive')).toBe(true)
rerender(<ActionButton state={ActionButtonState.Active}>Active</ActionButton>)
button = screen.getByRole('button', { name: 'Active' })
expect(button.classList.contains('action-btn-active')).toBe(true)
rerender(<ActionButton state={ActionButtonState.Disabled}>Disabled</ActionButton>)
button = screen.getByRole('button', { name: 'Disabled' })
expect(button.classList.contains('action-btn-disabled')).toBe(true)
rerender(<ActionButton state={ActionButtonState.Hover}>Hover</ActionButton>)
button = screen.getByRole('button', { name: 'Hover' })
expect(button.classList.contains('action-btn-hover')).toBe(true)
})
test('applies custom className', () => {
render(<ActionButton className='custom-class'>Custom Class</ActionButton>)
const button = screen.getByRole('button', { name: 'Custom Class' })
expect(button.classList.contains('custom-class')).toBe(true)
})
test('applies custom style', () => {
render(
<ActionButton styleCss={{ color: 'red', backgroundColor: 'blue' }}>
Custom Style
</ActionButton>,
)
const button = screen.getByRole('button', { name: 'Custom Style' })
expect(button).toHaveStyle({
color: 'red',
backgroundColor: 'blue',
})
})
test('forwards additional button props', () => {
render(<ActionButton disabled data-testid='test-button'>Disabled Button</ActionButton>)
const button = screen.getByRole('button', { name: 'Disabled Button' })
expect(button).toBeDisabled()
expect(button).toHaveAttribute('data-testid', 'test-button')
})
})

View File

@@ -5,7 +5,6 @@ import type { Area } from 'react-easy-crop'
import Modal from '../modal'
import Divider from '../divider'
import Button from '../button'
import { ImagePlus } from '../icons/src/vender/line/images'
import { useLocalFileUploader } from '../image-uploader/hooks'
import EmojiPickerInner from '../emoji-picker/Inner'
import type { OnImageInput } from './ImageInput'
@@ -16,6 +15,7 @@ import type { AppIconType, ImageFile } from '@/types/app'
import cn from '@/utils/classnames'
import { DISABLE_UPLOAD_IMAGE_AS_ICON } from '@/config'
import { noop } from 'lodash-es'
import { RiImageCircleAiLine } from '@remixicon/react'
export type AppIconEmojiSelection = {
type: 'emoji'
@@ -46,7 +46,7 @@ const AppIconPicker: FC<AppIconPickerProps> = ({
const tabs = [
{ key: 'emoji', label: t('app.iconPicker.emoji'), icon: <span className="text-lg">🤖</span> },
{ key: 'image', label: t('app.iconPicker.image'), icon: <ImagePlus /> },
{ key: 'image', label: t('app.iconPicker.image'), icon: <RiImageCircleAiLine className='size-4' /> },
]
const [activeTab, setActiveTab] = useState<AppIconType>('emoji')
@@ -119,10 +119,10 @@ const AppIconPicker: FC<AppIconPickerProps> = ({
{tabs.map(tab => (
<button
key={tab.key}
className={`
flex h-8 flex-1 shrink-0 items-center justify-center rounded-xl p-2 text-sm font-medium
${activeTab === tab.key && 'bg-components-main-nav-nav-button-bg-active shadow-md'}
`}
className={cn(
'system-sm-medium flex h-8 flex-1 shrink-0 items-center justify-center rounded-xl p-2 text-text-tertiary',
activeTab === tab.key && 'bg-components-main-nav-nav-button-bg-active text-text-accent shadow-md',
)}
onClick={() => setActiveTab(tab.key as AppIconType)}
>
{tab.icon} &nbsp; {tab.label}

View File

@@ -0,0 +1,159 @@
import { fireEvent, render, screen } from '@testing-library/react'
import '@testing-library/jest-dom'
import AppIcon from './index'
// Mock emoji-mart initialization
jest.mock('emoji-mart', () => ({
init: jest.fn(),
}))
// Mock emoji data
jest.mock('@emoji-mart/data', () => ({}))
// Mock the ahooks useHover hook
jest.mock('ahooks', () => ({
useHover: jest.fn(() => false),
}))
describe('AppIcon', () => {
beforeEach(() => {
// Mock custom element
if (!customElements.get('em-emoji')) {
customElements.define('em-emoji', class extends HTMLElement {
constructor() {
super()
}
// Mock basic functionality
connectedCallback() {
this.innerHTML = '🤖'
}
})
}
// Reset mocks
require('ahooks').useHover.mockReset().mockReturnValue(false)
})
it('renders default emoji when no icon or image is provided', () => {
render(<AppIcon />)
const emojiElement = document.querySelector('em-emoji')
expect(emojiElement).toBeInTheDocument()
expect(emojiElement?.getAttribute('id')).toBe('🤖')
})
it('renders with custom emoji when icon is provided', () => {
render(<AppIcon icon='smile' />)
const emojiElement = document.querySelector('em-emoji')
expect(emojiElement).toBeInTheDocument()
expect(emojiElement?.getAttribute('id')).toBe('smile')
})
it('renders image when iconType is image and imageUrl is provided', () => {
render(<AppIcon iconType='image' imageUrl='test-image.jpg' />)
const imgElement = screen.getByAltText('app icon')
expect(imgElement).toBeInTheDocument()
expect(imgElement).toHaveAttribute('src', 'test-image.jpg')
})
it('renders innerIcon when provided', () => {
render(<AppIcon innerIcon={<div data-testid='inner-icon'>Custom Icon</div>} />)
const innerIcon = screen.getByTestId('inner-icon')
expect(innerIcon).toBeInTheDocument()
})
it('applies size classes correctly', () => {
const { container: xsContainer } = render(<AppIcon size='xs' />)
expect(xsContainer.firstChild).toHaveClass('w-4 h-4 rounded-[4px]')
const { container: tinyContainer } = render(<AppIcon size='tiny' />)
expect(tinyContainer.firstChild).toHaveClass('w-6 h-6 rounded-md')
const { container: smallContainer } = render(<AppIcon size='small' />)
expect(smallContainer.firstChild).toHaveClass('w-8 h-8 rounded-lg')
const { container: mediumContainer } = render(<AppIcon size='medium' />)
expect(mediumContainer.firstChild).toHaveClass('w-9 h-9 rounded-[10px]')
const { container: largeContainer } = render(<AppIcon size='large' />)
expect(largeContainer.firstChild).toHaveClass('w-10 h-10 rounded-[10px]')
const { container: xlContainer } = render(<AppIcon size='xl' />)
expect(xlContainer.firstChild).toHaveClass('w-12 h-12 rounded-xl')
const { container: xxlContainer } = render(<AppIcon size='xxl' />)
expect(xxlContainer.firstChild).toHaveClass('w-14 h-14 rounded-2xl')
})
it('applies rounded class when rounded=true', () => {
const { container } = render(<AppIcon rounded />)
expect(container.firstChild).toHaveClass('rounded-full')
})
it('applies custom background color', () => {
const { container } = render(<AppIcon background='#FF5500' />)
expect(container.firstChild).toHaveStyle('background: #FF5500')
})
it('uses default background color when no background is provided for non-image icons', () => {
const { container } = render(<AppIcon />)
expect(container.firstChild).toHaveStyle('background: #FFEAD5')
})
it('does not apply background style for image icons', () => {
const { container } = render(<AppIcon iconType='image' imageUrl='test.jpg' background='#FF5500' />)
// Should not have the background style from the prop
expect(container.firstChild).not.toHaveStyle('background: #FF5500')
})
it('calls onClick handler when clicked', () => {
const handleClick = jest.fn()
const { container } = render(<AppIcon onClick={handleClick} />)
fireEvent.click(container.firstChild!)
expect(handleClick).toHaveBeenCalledTimes(1)
})
it('applies custom className', () => {
const { container } = render(<AppIcon className='custom-class' />)
expect(container.firstChild).toHaveClass('custom-class')
})
it('does not display edit icon when showEditIcon=false', () => {
render(<AppIcon />)
const editIcon = screen.queryByRole('svg')
expect(editIcon).not.toBeInTheDocument()
})
it('displays edit icon when showEditIcon=true and hovering', () => {
// Mock the useHover hook to return true for this test
require('ahooks').useHover.mockReturnValue(true)
render(<AppIcon showEditIcon />)
const editIcon = document.querySelector('svg')
expect(editIcon).toBeInTheDocument()
})
it('does not display edit icon when showEditIcon=true but not hovering', () => {
// useHover returns false by default from our mock setup
render(<AppIcon showEditIcon />)
const editIcon = document.querySelector('svg')
expect(editIcon).not.toBeInTheDocument()
})
it('handles conditional isValidImageIcon check correctly', () => {
// Case 1: Valid image icon
const { rerender } = render(
<AppIcon iconType='image' imageUrl='test.jpg' />,
)
expect(screen.getByAltText('app icon')).toBeInTheDocument()
// Case 2: Invalid - missing image URL
rerender(<AppIcon iconType='image' imageUrl={null} />)
expect(screen.queryByAltText('app icon')).not.toBeInTheDocument()
// Case 3: Invalid - wrong icon type
rerender(<AppIcon iconType='emoji' imageUrl='test.jpg' />)
expect(screen.queryByAltText('app icon')).not.toBeInTheDocument()
})
})

View File

@@ -1,11 +1,12 @@
'use client'
import type { FC } from 'react'
import React, { type FC, useRef } from 'react'
import { init } from 'emoji-mart'
import data from '@emoji-mart/data'
import { cva } from 'class-variance-authority'
import type { AppIconType } from '@/types/app'
import classNames from '@/utils/classnames'
import { useHover } from 'ahooks'
import { RiEditLine } from '@remixicon/react'
init({ data })
@@ -18,20 +19,21 @@ export type AppIconProps = {
imageUrl?: string | null
className?: string
innerIcon?: React.ReactNode
showEditIcon?: boolean
onClick?: () => void
}
const appIconVariants = cva(
'flex items-center justify-center relative text-lg rounded-lg grow-0 shrink-0 overflow-hidden leading-none',
'flex items-center justify-center relative grow-0 shrink-0 overflow-hidden leading-none border-[0.5px] border-divider-regular',
{
variants: {
size: {
xs: 'w-4 h-4 text-xs',
tiny: 'w-6 h-6 text-base',
small: 'w-8 h-8 text-xl',
medium: 'w-9 h-9 text-[22px]',
large: 'w-10 h-10 text-[24px]',
xl: 'w-12 h-12 text-[28px]',
xxl: 'w-14 h-14 text-[32px]',
xs: 'w-4 h-4 text-xs rounded-[4px]',
tiny: 'w-6 h-6 text-base rounded-md',
small: 'w-8 h-8 text-xl rounded-lg',
medium: 'w-9 h-9 text-[22px] rounded-[10px]',
large: 'w-10 h-10 text-[24px] rounded-[10px]',
xl: 'w-12 h-12 text-[28px] rounded-xl',
xxl: 'w-14 h-14 text-[32px] rounded-2xl',
},
rounded: {
true: 'rounded-full',
@@ -42,6 +44,46 @@ const appIconVariants = cva(
rounded: false,
},
})
const EditIconWrapperVariants = cva(
'absolute left-0 top-0 z-10 flex items-center justify-center bg-background-overlay-alt',
{
variants: {
size: {
xs: 'w-4 h-4 rounded-[4px]',
tiny: 'w-6 h-6 rounded-md',
small: 'w-8 h-8 rounded-lg',
medium: 'w-9 h-9 rounded-[10px]',
large: 'w-10 h-10 rounded-[10px]',
xl: 'w-12 h-12 rounded-xl',
xxl: 'w-14 h-14 rounded-2xl',
},
rounded: {
true: 'rounded-full',
},
},
defaultVariants: {
size: 'medium',
rounded: false,
},
})
const EditIconVariants = cva(
'text-text-primary-on-surface',
{
variants: {
size: {
xs: 'size-3',
tiny: 'size-3.5',
small: 'size-5',
medium: 'size-[22px]',
large: 'size-6',
xl: 'size-7',
xxl: 'size-8',
},
},
defaultVariants: {
size: 'medium',
},
})
const AppIcon: FC<AppIconProps> = ({
size = 'medium',
rounded = false,
@@ -52,20 +94,34 @@ const AppIcon: FC<AppIconProps> = ({
className,
innerIcon,
onClick,
showEditIcon = false,
}) => {
const isValidImageIcon = iconType === 'image' && imageUrl
const Icon = (icon && icon !== '') ? <em-emoji id={icon} /> : <em-emoji id='🤖' />
const wrapperRef = useRef<HTMLSpanElement>(null)
const isHovering = useHover(wrapperRef)
return <span
className={classNames(appIconVariants({ size, rounded }), className)}
style={{ background: isValidImageIcon ? undefined : (background || '#FFEAD5') }}
onClick={onClick}
>
{isValidImageIcon
? <img src={imageUrl} className="h-full w-full" alt="app icon" />
: (innerIcon || ((icon && icon !== '') ? <em-emoji id={icon} /> : <em-emoji id='🤖' />))
}
</span>
return (
<span
ref={wrapperRef}
className={classNames(appIconVariants({ size, rounded }), className)}
style={{ background: isValidImageIcon ? undefined : (background || '#FFEAD5') }}
onClick={onClick}
>
{
isValidImageIcon
? <img src={imageUrl} className='h-full w-full' alt='app icon' />
: (innerIcon || Icon)
}
{
showEditIcon && isHovering && (
<div className={EditIconWrapperVariants({ size, rounded })}>
<RiEditLine className={EditIconVariants({ size })} />
</div>
)
}
</span>
)
}
export default AppIcon
export default React.memo(AppIcon)

View File

@@ -10,8 +10,8 @@ type CornerLabelProps = {
const CornerLabel: React.FC<CornerLabelProps> = ({ label, className, labelClassName }) => {
return (
<div className={cn('group/corner-label inline-flex items-start', className)}>
<Corner className='h-5 w-[13px] text-background-section group-hover/corner-label:text-background-section-burn' />
<div className={cn('flex items-center gap-0.5 bg-background-section py-1 pr-2 group-hover/corner-label:bg-background-section-burn', labelClassName)}>
<Corner className='h-5 w-[13px] text-background-section-burn' />
<div className={cn('flex items-center gap-0.5 bg-background-section-burn py-1 pr-2', labelClassName)}>
<div className='system-2xs-medium-uppercase text-text-tertiary'>{label}</div>
</div>
</div>

View File

@@ -0,0 +1,18 @@
import React from 'react'
import cn from '@/utils/classnames'
type EffectProps = {
className?: string
}
const Effect = ({
className,
}: EffectProps) => {
return (
<div
className={cn('absolute size-[112px] rounded-full bg-util-colors-blue-brand-blue-brand-500 blur-[80px]', className)}
/>
)
}
export default React.memo(Effect)

View File

@@ -110,7 +110,7 @@ const FileUploaderInAttachment = ({
)
}
type FileUploaderInAttachmentWrapperProps = {
export type FileUploaderInAttachmentWrapperProps = {
value?: FileEntity[]
onChange: (files: FileEntity[]) => void
fileConfig: FileUpload

View File

@@ -0,0 +1,41 @@
import cn from '@/utils/classnames'
import { useFieldContext } from '../..'
import type { CustomSelectProps, Option } from '../../../select/custom'
import CustomSelect from '../../../select/custom'
import type { LabelProps } from '../label'
import Label from '../label'
type CustomSelectFieldProps<T extends Option> = {
label: string
labelOptions?: Omit<LabelProps, 'htmlFor' | 'label'>
options: T[]
className?: string
} & Omit<CustomSelectProps<T>, 'options' | 'value' | 'onChange'>
const CustomSelectField = <T extends Option>({
label,
labelOptions,
options,
className,
...selectProps
}: CustomSelectFieldProps<T>) => {
const field = useFieldContext<string>()
return (
<div className={cn('flex flex-col gap-y-0.5', className)}>
<Label
htmlFor={field.name}
label={label}
{...(labelOptions ?? {})}
/>
<CustomSelect<T>
value={field.state.value}
options={options}
onChange={value => field.handleChange(value)}
{...selectProps}
/>
</div>
)
}
export default CustomSelectField

View File

@@ -0,0 +1,83 @@
import cn from '@/utils/classnames'
import type { LabelProps } from '../label'
import { useFieldContext } from '../..'
import Label from '../label'
import { SupportUploadFileTypes } from '@/app/components/workflow/types'
import FileTypeItem from '@/app/components/workflow/nodes/_base/components/file-type-item'
import { useCallback } from 'react'
type FieldValue = {
allowedFileTypes: string[],
allowedFileExtensions: string[]
}
type FileTypesFieldProps = {
label: string
labelOptions?: Omit<LabelProps, 'htmlFor' | 'label'>
className?: string
}
const FileTypesField = ({
label,
labelOptions,
className,
}: FileTypesFieldProps) => {
const field = useFieldContext<FieldValue>()
const handleSupportFileTypeChange = useCallback((type: SupportUploadFileTypes) => {
let newAllowFileTypes = [...field.state.value.allowedFileTypes]
if (type === SupportUploadFileTypes.custom) {
if (!newAllowFileTypes.includes(SupportUploadFileTypes.custom))
newAllowFileTypes = [SupportUploadFileTypes.custom]
else
newAllowFileTypes = newAllowFileTypes.filter(v => v !== type)
}
else {
newAllowFileTypes = newAllowFileTypes.filter(v => v !== SupportUploadFileTypes.custom)
if (newAllowFileTypes.includes(type))
newAllowFileTypes = newAllowFileTypes.filter(v => v !== type)
else
newAllowFileTypes.push(type)
}
field.handleChange({
...field.state.value,
allowedFileTypes: newAllowFileTypes,
})
}, [field])
const handleCustomFileTypesChange = useCallback((customFileTypes: string[]) => {
field.handleChange({
...field.state.value,
allowedFileExtensions: customFileTypes,
})
}, [field])
return (
<div className={cn('flex flex-col gap-y-0.5', className)}>
<Label
htmlFor={field.name}
label={label}
{...(labelOptions ?? {})}
/>
{
[SupportUploadFileTypes.document, SupportUploadFileTypes.image, SupportUploadFileTypes.audio, SupportUploadFileTypes.video].map((type: SupportUploadFileTypes) => (
<FileTypeItem
key={type}
type={type as SupportUploadFileTypes.image | SupportUploadFileTypes.document | SupportUploadFileTypes.audio | SupportUploadFileTypes.video}
selected={field.state.value.allowedFileTypes.includes(type)}
onToggle={handleSupportFileTypeChange}
/>
))
}
<FileTypeItem
type={SupportUploadFileTypes.custom}
selected={field.state.value.allowedFileTypes.includes(SupportUploadFileTypes.custom)}
onToggle={handleSupportFileTypeChange}
customFileTypes={field.state.value.allowedFileExtensions}
onCustomFileTypesChange={handleCustomFileTypesChange}
/>
</div>
)
}
export default FileTypesField

View File

@@ -0,0 +1,40 @@
import React from 'react'
import { useFieldContext } from '../..'
import type { LabelProps } from '../label'
import Label from '../label'
import cn from '@/utils/classnames'
import type { FileUploaderInAttachmentWrapperProps } from '../../../file-uploader/file-uploader-in-attachment'
import FileUploaderInAttachmentWrapper from '../../../file-uploader/file-uploader-in-attachment'
import type { FileEntity } from '../../../file-uploader/types'
type FileUploaderFieldProps = {
label: string
labelOptions?: Omit<LabelProps, 'htmlFor' | 'label'>
className?: string
} & Omit<FileUploaderInAttachmentWrapperProps, 'value' | 'onChange'>
const FileUploaderField = ({
label,
labelOptions,
className,
...inputProps
}: FileUploaderFieldProps) => {
const field = useFieldContext<FileEntity[]>()
return (
<div className={cn('flex flex-col gap-y-0.5', className)}>
<Label
htmlFor={field.name}
label={label}
{...(labelOptions ?? {})}
/>
<FileUploaderInAttachmentWrapper
value={field.state.value}
onChange={value => field.handleChange(value)}
{...inputProps}
/>
</div>
)
}
export default FileUploaderField

View File

@@ -0,0 +1,52 @@
import { InputTypeEnum } from './types'
import { PipelineInputVarType } from '@/models/pipeline'
import { useTranslation } from 'react-i18next'
import {
RiAlignLeft,
RiCheckboxLine,
RiFileCopy2Line,
RiFileTextLine,
RiHashtag,
RiListCheck3,
RiTextSnippet,
} from '@remixicon/react'
const i18nFileTypeMap: Record<string, string> = {
'number': 'number',
'file': 'single-file',
'file-list': 'multi-files',
}
const INPUT_TYPE_ICON = {
[PipelineInputVarType.textInput]: RiTextSnippet,
[PipelineInputVarType.paragraph]: RiAlignLeft,
[PipelineInputVarType.number]: RiHashtag,
[PipelineInputVarType.select]: RiListCheck3,
[PipelineInputVarType.checkbox]: RiCheckboxLine,
[PipelineInputVarType.singleFile]: RiFileTextLine,
[PipelineInputVarType.multiFiles]: RiFileCopy2Line,
}
const DATA_TYPE = {
[PipelineInputVarType.textInput]: 'string',
[PipelineInputVarType.paragraph]: 'string',
[PipelineInputVarType.number]: 'number',
[PipelineInputVarType.select]: 'string',
[PipelineInputVarType.checkbox]: 'boolean',
[PipelineInputVarType.singleFile]: 'file',
[PipelineInputVarType.multiFiles]: 'array[file]',
}
export const useInputTypeOptions = (supportFile: boolean) => {
const { t } = useTranslation()
const options = supportFile ? InputTypeEnum.options : InputTypeEnum.exclude(['file', 'file-list']).options
return options.map((value) => {
return {
value,
label: t(`appDebug.variableConfig.${i18nFileTypeMap[value] || value}`),
Icon: INPUT_TYPE_ICON[value],
type: DATA_TYPE[value],
}
})
}

View File

@@ -0,0 +1,64 @@
import cn from '@/utils/classnames'
import { useFieldContext } from '../../..'
import type { CustomSelectProps } from '../../../../select/custom'
import CustomSelect from '../../../../select/custom'
import type { LabelProps } from '../../label'
import Label from '../../label'
import { useCallback } from 'react'
import Trigger from './trigger'
import type { FileTypeSelectOption, InputType } from './types'
import { useInputTypeOptions } from './hooks'
import Option from './option'
type InputTypeSelectFieldProps = {
label: string
labelOptions?: Omit<LabelProps, 'htmlFor' | 'label'>
supportFile: boolean
className?: string
} & Omit<CustomSelectProps<FileTypeSelectOption>, 'options' | 'value' | 'onChange' | 'CustomTrigger' | 'CustomOption'>
const InputTypeSelectField = ({
label,
labelOptions,
supportFile,
className,
...customSelectProps
}: InputTypeSelectFieldProps) => {
const field = useFieldContext<InputType>()
const inputTypeOptions = useInputTypeOptions(supportFile)
const renderTrigger = useCallback((option: FileTypeSelectOption | undefined, open: boolean) => {
return <Trigger option={option} open={open} />
}, [])
const renderOption = useCallback((option: FileTypeSelectOption) => {
return <Option option={option} />
}, [])
return (
<div className={cn('flex flex-col gap-y-0.5', className)}>
<Label
htmlFor={field.name}
label={label}
{...(labelOptions ?? {})}
/>
<CustomSelect<FileTypeSelectOption>
value={field.state.value}
options={inputTypeOptions}
onChange={value => field.handleChange(value as InputType)}
triggerProps={{
className: 'gap-x-0.5',
}}
popupProps={{
className: 'w-[368px]',
wrapperClassName: 'z-[9999999]',
itemClassName: 'gap-x-1',
}}
CustomTrigger={renderTrigger}
CustomOption={renderOption}
{...customSelectProps}
/>
</div>
)
}
export default InputTypeSelectField

View File

@@ -0,0 +1,21 @@
import React from 'react'
import type { FileTypeSelectOption } from './types'
import Badge from '@/app/components/base/badge'
type OptionProps = {
option: FileTypeSelectOption
}
const Option = ({
option,
}: OptionProps) => {
return (
<>
<option.Icon className='h-4 w-4 shrink-0 text-text-tertiary' />
<span className='grow px-1'>{option.label}</span>
<Badge text={option.type} uppercase={false} />
</>
)
}
export default React.memo(Option)

View File

@@ -0,0 +1,42 @@
import React from 'react'
import Badge from '@/app/components/base/badge'
import cn from '@/utils/classnames'
import { RiArrowDownSLine } from '@remixicon/react'
import { useTranslation } from 'react-i18next'
import type { FileTypeSelectOption } from './types'
type TriggerProps = {
option: FileTypeSelectOption | undefined
open: boolean
}
const Trigger = ({
option,
open,
}: TriggerProps) => {
const { t } = useTranslation()
return (
<>
{option ? (
<>
<option.Icon className='h-4 w-4 shrink-0 text-text-tertiary' />
<span className='grow p-1'>{option.label}</span>
<div className='pr-0.5'>
<Badge text={option.type} uppercase={false} />
</div>
</>
) : (
<span className='grow p-1'>{t('common.placeholder.select')}</span>
)}
<RiArrowDownSLine
className={cn(
'h-4 w-4 shrink-0 text-text-quaternary group-hover:text-text-secondary',
open && 'text-text-secondary',
)}
/>
</>
)
}
export default React.memo(Trigger)

View File

@@ -0,0 +1,21 @@
import type { RemixiconComponentType } from '@remixicon/react'
import { z } from 'zod'
export const InputTypeEnum = z.enum([
'text-input',
'paragraph',
'number',
'select',
'checkbox',
'file',
'file-list',
])
export type InputType = z.infer<typeof InputTypeEnum>
export type FileTypeSelectOption = {
value: InputType
label: string
Icon: RemixiconComponentType
type: string
}

View File

@@ -0,0 +1,39 @@
import {
memo,
} from 'react'
import PromptEditor from '@/app/components/base/prompt-editor'
import cn from '@/utils/classnames'
import Placeholder from './placeholder'
type MixedVariableTextInputProps = {
editable?: boolean
value?: string
onChange?: (text: string) => void
}
const MixedVariableTextInput = ({
editable = true,
value = '',
onChange,
}: MixedVariableTextInputProps) => {
return (
<PromptEditor
wrapperClassName={cn(
'rounded-lg border border-transparent bg-components-input-bg-normal px-2 py-1',
'hover:border-components-input-border-hover hover:bg-components-input-bg-hover',
'focus-within:border-components-input-border-active focus-within:bg-components-input-bg-active focus-within:shadow-xs',
)}
className='caret:text-text-accent'
editable={editable}
value={value}
workflowVariableBlock={{
show: true,
variables: [],
workflowNodesMap: {},
}}
placeholder={<Placeholder />}
onChange={onChange}
/>
)
}
export default memo(MixedVariableTextInput)

View File

@@ -0,0 +1,49 @@
import { useCallback } from 'react'
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'
import { FOCUS_COMMAND } from 'lexical'
import { $insertNodes } from 'lexical'
import { CustomTextNode } from '@/app/components/base/prompt-editor/plugins/custom-text/node'
import Badge from '@/app/components/base/badge'
const Placeholder = () => {
const [editor] = useLexicalComposerContext()
const handleInsert = useCallback((text: string) => {
editor.update(() => {
const textNode = new CustomTextNode(text)
$insertNodes([textNode])
})
editor.dispatchCommand(FOCUS_COMMAND, undefined as any)
}, [editor])
return (
<div
className='pointer-events-auto flex h-full w-full cursor-text items-center px-2'
onClick={(e) => {
e.stopPropagation()
handleInsert('')
}}
>
<div className='flex grow items-center'>
Type or press
<div className='system-kbd mx-0.5 flex h-4 w-4 items-center justify-center rounded bg-components-kbd-bg-gray text-text-placeholder'>/</div>
<div
className='system-sm-regular cursor-pointer text-components-input-text-placeholder underline decoration-dotted decoration-auto underline-offset-auto hover:text-text-tertiary'
onClick={((e) => {
e.stopPropagation()
handleInsert('/')
})}
>
insert variable
</div>
</div>
<Badge
className='shrink-0'
text='String'
uppercase={false}
/>
</div>
)
}
export default Placeholder

View File

@@ -1,5 +1,6 @@
import React from 'react'
import { useFieldContext } from '../..'
import type { LabelProps } from '../label'
import Label from '../label'
import cn from '@/utils/classnames'
import type { InputNumberProps } from '../../../input-number'
@@ -7,20 +8,14 @@ import { InputNumber } from '../../../input-number'
type TextFieldProps = {
label: string
isRequired?: boolean
showOptional?: boolean
tooltip?: string
labelOptions?: Omit<LabelProps, 'htmlFor' | 'label'>
className?: string
labelClassName?: string
} & Omit<InputNumberProps, 'id' | 'value' | 'onChange' | 'onBlur'>
const NumberInputField = ({
label,
isRequired,
showOptional,
tooltip,
labelOptions,
className,
labelClassName,
...inputProps
}: TextFieldProps) => {
const field = useFieldContext<number | undefined>()
@@ -30,10 +25,7 @@ const NumberInputField = ({
<Label
htmlFor={field.name}
label={label}
isRequired={isRequired}
showOptional={showOptional}
tooltip={tooltip}
className={labelClassName}
{...(labelOptions ?? {})}
/>
<InputNumber
id={field.name}

View File

@@ -0,0 +1,47 @@
import cn from '@/utils/classnames'
import type { LabelProps } from '../label'
import { useFieldContext } from '../..'
import Label from '../label'
import type { InputNumberWithSliderProps } from '@/app/components/workflow/nodes/_base/components/input-number-with-slider'
import InputNumberWithSlider from '@/app/components/workflow/nodes/_base/components/input-number-with-slider'
type NumberSliderFieldProps = {
label: string
labelOptions?: Omit<LabelProps, 'htmlFor' | 'label'>
description?: string
className?: string
} & Omit<InputNumberWithSliderProps, 'value' | 'onChange'>
const NumberSliderField = ({
label,
labelOptions,
description,
className,
...InputNumberWithSliderProps
}: NumberSliderFieldProps) => {
const field = useFieldContext<number>()
return (
<div className={cn('flex flex-col gap-y-0.5', className)}>
<div>
<Label
htmlFor={field.name}
label={label}
{...(labelOptions ?? {})}
/>
{description && (
<div className='body-xs-regular pb-0.5 text-text-tertiary'>
{description}
</div>
)}
</div>
<InputNumberWithSlider
value={field.state.value}
onChange={value => field.handleChange(value)}
{...InputNumberWithSliderProps}
/>
</div>
)
}
export default NumberSliderField

View File

@@ -1,27 +1,29 @@
import cn from '@/utils/classnames'
import { useFieldContext } from '../..'
import type { LabelProps } from '../label'
import Label from '../label'
import type { Options } from '@/app/components/app/configuration/config-var/config-select'
import ConfigSelect from '@/app/components/app/configuration/config-var/config-select'
type OptionsFieldProps = {
label: string;
labelOptions?: Omit<LabelProps, 'htmlFor' | 'label'>
className?: string;
labelClassName?: string;
}
const OptionsField = ({
label,
className,
labelClassName,
labelOptions,
}: OptionsFieldProps) => {
const field = useFieldContext<string[]>()
const field = useFieldContext<Options>()
return (
<div className={cn('flex flex-col gap-y-0.5', className)}>
<Label
htmlFor={field.name}
label={label}
className={labelClassName}
{...(labelOptions ?? {})}
/>
<ConfigSelect
options={field.state.value}

View File

@@ -1,31 +1,25 @@
import cn from '@/utils/classnames'
import { useFieldContext } from '../..'
import type { Option, PureSelectProps } from '../../../select/pure'
import PureSelect from '../../../select/pure'
import type { LabelProps } from '../label'
import Label from '../label'
type SelectOption = {
value: string
label: string
}
type SelectFieldProps = {
label: string
options: SelectOption[]
isRequired?: boolean
showOptional?: boolean
tooltip?: string
labelOptions?: Omit<LabelProps, 'htmlFor' | 'label'>
options: Option[]
onChange?: (value: string) => void
className?: string
labelClassName?: string
}
} & Omit<PureSelectProps, 'options' | 'value' | 'onChange'>
const SelectField = ({
label,
labelOptions,
options,
isRequired,
showOptional,
tooltip,
onChange,
className,
labelClassName,
...selectProps
}: SelectFieldProps) => {
const field = useFieldContext<string>()
@@ -34,15 +28,13 @@ const SelectField = ({
<Label
htmlFor={field.name}
label={label}
isRequired={isRequired}
showOptional={showOptional}
tooltip={tooltip}
className={labelClassName}
{...(labelOptions ?? {})}
/>
<PureSelect
value={field.state.value}
options={options}
onChange={value => field.handleChange(value)}
{...selectProps}
/>
</div>
)

View File

@@ -0,0 +1,41 @@
import React from 'react'
import { useFieldContext } from '../..'
import type { LabelProps } from '../label'
import Label from '../label'
import cn from '@/utils/classnames'
import type { TextareaProps } from '../../../textarea'
import Textarea from '../../../textarea'
type TextAreaFieldProps = {
label: string
labelOptions?: Omit<LabelProps, 'htmlFor' | 'label'>
className?: string
} & Omit<TextareaProps, 'className' | 'onChange' | 'onBlur' | 'value' | 'id'>
const TextAreaField = ({
label,
labelOptions,
className,
...inputProps
}: TextAreaFieldProps) => {
const field = useFieldContext<string>()
return (
<div className={cn('flex flex-col gap-y-0.5', className)}>
<Label
htmlFor={field.name}
label={label}
{...(labelOptions ?? {})}
/>
<Textarea
id={field.name}
value={field.state.value}
onChange={e => field.handleChange(e.target.value)}
onBlur={field.handleBlur}
{...inputProps}
/>
</div>
)
}
export default TextAreaField

View File

@@ -1,25 +1,20 @@
import React from 'react'
import { useFieldContext } from '../..'
import Input, { type InputProps } from '../../../input'
import type { LabelProps } from '../label'
import Label from '../label'
import cn from '@/utils/classnames'
type TextFieldProps = {
label: string
isRequired?: boolean
showOptional?: boolean
tooltip?: string
labelOptions?: Omit<LabelProps, 'htmlFor' | 'label'>
className?: string
labelClassName?: string
} & Omit<InputProps, 'className' | 'onChange' | 'onBlur' | 'value' | 'id'>
const TextField = ({
label,
isRequired,
showOptional,
tooltip,
labelOptions,
className,
labelClassName,
...inputProps
}: TextFieldProps) => {
const field = useFieldContext<string>()
@@ -29,10 +24,7 @@ const TextField = ({
<Label
htmlFor={field.name}
label={label}
isRequired={isRequired}
showOptional={showOptional}
tooltip={tooltip}
className={labelClassName}
{...(labelOptions ?? {})}
/>
<Input
id={field.name}

View File

@@ -0,0 +1,58 @@
import cn from '@/utils/classnames'
import type { LabelProps } from '../label'
import { useFieldContext } from '../..'
import Label from '../label'
import OptionCard from '@/app/components/workflow/nodes/_base/components/option-card'
import { useTranslation } from 'react-i18next'
import { TransferMethod } from '@/types/app'
import { useCallback } from 'react'
type UploadMethodFieldProps = {
label: string
labelOptions?: Omit<LabelProps, 'htmlFor' | 'label'>
className?: string
}
const UploadMethodField = ({
label,
labelOptions,
className,
}: UploadMethodFieldProps) => {
const { t } = useTranslation()
const field = useFieldContext<TransferMethod[]>()
const { value } = field.state
const handleUploadMethodChange = useCallback((method: TransferMethod) => {
field.handleChange(method === TransferMethod.all ? [TransferMethod.local_file, TransferMethod.remote_url] : [method])
}, [field])
return (
<div className={cn('flex flex-col gap-y-0.5', className)}>
<Label
htmlFor={field.name}
label={label}
{...(labelOptions ?? {})}
/>
<div className='grid grid-cols-3 gap-2'>
<OptionCard
title={t('appDebug.variableConfig.localUpload')}
selected={value.length === 1 && value.includes(TransferMethod.local_file)}
onSelect={handleUploadMethodChange.bind(null, TransferMethod.local_file)}
/>
<OptionCard
title="URL"
selected={value.length === 1 && value.includes(TransferMethod.remote_url)}
onSelect={handleUploadMethodChange.bind(null, TransferMethod.remote_url)}
/>
<OptionCard
title={t('appDebug.variableConfig.both')}
selected={value.includes(TransferMethod.local_file) && value.includes(TransferMethod.remote_url)}
onSelect={handleUploadMethodChange.bind(null, TransferMethod.all)}
/>
</div>
</div>
)
}
export default UploadMethodField

View File

@@ -0,0 +1,86 @@
import type { ChangeEvent } from 'react'
import { useState } from 'react'
import { RiEditLine } from '@remixicon/react'
import cn from '@/utils/classnames'
import SegmentedControl from '@/app/components/base/segmented-control'
import { VariableX } from '@/app/components/base/icons/src/vender/workflow'
import Input from '@/app/components/base/input'
import VarReferencePicker from '@/app/components/workflow/nodes/_base/components/variable/var-reference-picker'
import type { LabelProps } from '../label'
import Label from '../label'
type VariableOrConstantInputFieldProps = {
label: string
labelOptions?: Omit<LabelProps, 'htmlFor' | 'label'>
className?: string
}
const VariableOrConstantInputField = ({
className,
label,
labelOptions,
}: VariableOrConstantInputFieldProps) => {
const [variableType, setVariableType] = useState('variable')
const options = [
{
Icon: VariableX,
value: 'variable',
},
{
Icon: RiEditLine,
value: 'constant',
},
]
const handleVariableOrConstantChange = (value: string) => {
setVariableType(value)
}
const handleVariableValueChange = () => {
console.log('Variable value changed')
}
const handleConstantValueChange = (e: ChangeEvent<HTMLInputElement>) => {
console.log('Constant value changed:', e.target.value)
}
return (
<div className={cn('flex flex-col gap-y-0.5', className)}>
<Label
htmlFor={'variable-or-constant'}
label={label}
{...(labelOptions ?? {})}
/>
<div className='flex items-center'>
<SegmentedControl
className='mr-1 shrink-0'
value={variableType}
onChange={handleVariableOrConstantChange as any}
options={options as any}
/>
{
variableType === 'variable' && (
<VarReferencePicker
className='grow'
nodeId=''
readonly={false}
value={[]}
onChange={handleVariableValueChange}
/>
)
}
{
variableType === 'constant' && (
<Input
className='ml-1'
onChange={handleConstantValueChange}
/>
)
}
</div>
</div>
)
}
export default VariableOrConstantInputField

View File

@@ -0,0 +1,41 @@
import cn from '@/utils/classnames'
import VarReferencePicker from '@/app/components/workflow/nodes/_base/components/variable/var-reference-picker'
import type { LabelProps } from '../label'
import Label from '../label'
type VariableOrConstantInputFieldProps = {
label: string
labelOptions?: Omit<LabelProps, 'htmlFor' | 'label'>
className?: string
}
const VariableOrConstantInputField = ({
className,
label,
labelOptions,
}: VariableOrConstantInputFieldProps) => {
const handleVariableValueChange = () => {
console.log('Variable value changed')
}
return (
<div className={cn('flex flex-col gap-y-0.5', className)}>
<Label
htmlFor={'variable-or-constant'}
label={label}
{...(labelOptions ?? {})}
/>
<div className='flex items-center'>
<VarReferencePicker
className='grow'
nodeId=''
readonly={false}
value={[]}
onChange={handleVariableValueChange}
/>
</div>
</div>
)
}
export default VariableOrConstantInputField

View File

@@ -0,0 +1,43 @@
import { useStore } from '@tanstack/react-form'
import type { FormType } from '../..'
import { useFormContext } from '../..'
import Button from '../../../button'
import { useTranslation } from 'react-i18next'
export type CustomActionsProps = {
form: FormType
isSubmitting: boolean
canSubmit: boolean
}
type ActionsProps = {
CustomActions?: (props: CustomActionsProps) => React.ReactNode | React.JSX.Element
}
const Actions = ({
CustomActions,
}: ActionsProps) => {
const { t } = useTranslation()
const form = useFormContext()
const [isSubmitting, canSubmit] = useStore(form.store, state => [
state.isSubmitting,
state.canSubmit,
])
if (CustomActions)
return CustomActions({ form, isSubmitting, canSubmit })
return (
<Button
variant='primary'
disabled={isSubmitting || !canSubmit}
loading={isSubmitting}
onClick={() => form.handleSubmit()}
>
{t('common.operation.submit')}
</Button>
)
}
export default Actions

View File

@@ -1,25 +0,0 @@
import { useStore } from '@tanstack/react-form'
import { useFormContext } from '../..'
import Button, { type ButtonProps } from '../../../button'
type SubmitButtonProps = Omit<ButtonProps, 'disabled' | 'loading' | 'onClick'>
const SubmitButton = ({ ...buttonProps }: SubmitButtonProps) => {
const form = useFormContext()
const [isSubmitting, canSubmit] = useStore(form.store, state => [
state.isSubmitting,
state.canSubmit,
])
return (
<Button
disabled={isSubmitting || !canSubmit}
loading={isSubmitting}
onClick={() => form.handleSubmit()}
{...buttonProps}
/>
)
}
export default SubmitButton

View File

@@ -0,0 +1,197 @@
import React from 'react'
import { type BaseConfiguration, BaseFieldType } from './types'
import { withForm } from '../..'
import { useStore } from '@tanstack/react-form'
type BaseFieldProps = {
initialData?: Record<string, any>
config: BaseConfiguration
}
const BaseField = ({
initialData,
config,
}: BaseFieldProps) => withForm({
defaultValues: initialData,
render: function Render({
form,
}) {
const {
type,
label,
placeholder,
variable,
tooltip,
showConditions,
max,
min,
options,
required,
showOptional,
popupProps,
allowedFileExtensions,
allowedFileTypes,
allowedFileUploadMethods,
maxLength,
unit,
} = config
const isAllConditionsMet = useStore(form.store, (state) => {
const fieldValues = state.values
if (!showConditions.length) return true
return showConditions.every((condition) => {
const { variable, value } = condition
const fieldValue = fieldValues[variable as keyof typeof fieldValues]
return fieldValue === value
})
})
if (!isAllConditionsMet)
return <></>
if (type === BaseFieldType.textInput) {
return (
<form.AppField
name={variable}
children={field => (
<field.TextField
label={label}
labelOptions={{
tooltip,
isRequired: required,
showOptional,
}}
placeholder={placeholder}
/>
)}
/>
)
}
if (type === BaseFieldType.paragraph) {
return (
<form.AppField
name={variable}
children={field => (
<field.TextAreaField
label={label}
labelOptions={{
tooltip,
isRequired: required,
showOptional,
}}
placeholder={placeholder}
/>
)}
/>
)
}
if (type === BaseFieldType.numberInput) {
return (
<form.AppField
name={variable}
children={field => (
<field.NumberInputField
label={label}
labelOptions={{
tooltip,
isRequired: required,
showOptional,
}}
placeholder={placeholder}
max={max}
min={min}
unit={unit}
/>
)}
/>
)
}
if (type === BaseFieldType.checkbox) {
return (
<form.AppField
name={variable}
children={field => (
<field.CheckboxField
label={label}
/>
)}
/>
)
}
if (type === BaseFieldType.select) {
return (
<form.AppField
name={variable}
children={field => (
<field.SelectField
label={label}
labelOptions={{
tooltip,
isRequired: required,
showOptional,
}}
options={options!}
popupProps={popupProps}
/>
)}
/>
)
}
if (type === BaseFieldType.file) {
return (
<form.AppField
name={variable}
children={field => (
<field.FileUploaderField
label={label}
labelOptions={{
tooltip,
isRequired: required,
showOptional,
}}
fileConfig={{
allowed_file_extensions: allowedFileExtensions,
allowed_file_types: allowedFileTypes,
allowed_file_upload_methods: allowedFileUploadMethods,
number_limits: 1,
}}
/>
)}
/>
)
}
if (type === BaseFieldType.fileList) {
return (
<form.AppField
name={variable}
children={field => (
<field.FileUploaderField
label={label}
labelOptions={{
tooltip,
isRequired: required,
showOptional,
}}
fileConfig={{
allowed_file_extensions: allowedFileExtensions,
allowed_file_types: allowedFileTypes,
allowed_file_upload_methods: allowedFileUploadMethods,
number_limits: maxLength,
}}
/>
)}
/>
)
}
return <></>
},
})
export default BaseField

View File

@@ -0,0 +1,63 @@
import React, { useMemo } from 'react'
import { useAppForm } from '../..'
import BaseField from './field'
import type { BaseFormProps } from './types'
import { generateZodSchema } from './utils'
const BaseForm = ({
initialData,
configurations,
onSubmit,
CustomActions,
}: BaseFormProps) => {
const schema = useMemo(() => {
const schema = generateZodSchema(configurations)
return schema
}, [configurations])
const baseForm = useAppForm({
defaultValues: initialData,
validators: {
onChange: ({ value }) => {
const result = schema.safeParse(value)
if (!result.success) {
const issues = result.error.issues
const firstIssue = issues[0].message
return firstIssue
}
return undefined
},
},
onSubmit: ({ value }) => {
onSubmit(value)
},
})
return (
<form
className='w-full'
onSubmit={(e) => {
e.preventDefault()
e.stopPropagation()
baseForm.handleSubmit()
}}
>
<div className='flex flex-col gap-4 px-4 py-2'>
{configurations.map((config, index) => {
const FieldComponent = BaseField({
initialData,
config,
})
return <FieldComponent key={index} form={baseForm} />
})}
</div>
<baseForm.AppForm>
<baseForm.Actions
CustomActions={CustomActions}
/>
</baseForm.AppForm>
</form>
)
}
export default React.memo(BaseForm)

View File

@@ -0,0 +1,61 @@
import type { TransferMethod } from '@/types/app'
import type { Option } from '../../../select/pure'
import type { CustomActionsProps } from '../../components/form/actions'
export enum BaseFieldType {
textInput = 'text-input',
paragraph = 'paragraph',
numberInput = 'number-input',
checkbox = 'checkbox',
select = 'select',
file = 'file',
fileList = 'file-list',
}
export type ShowCondition = {
variable: string
value: any
}
export type NumberConfiguration = {
max?: number
min?: number
unit?: string
}
export type SelectConfiguration = {
options: Option[] // Options for select field
popupProps?: {
wrapperClassName?: string
className?: string
itemClassName?: string
title?: string
}
}
export type FileConfiguration = {
allowedFileTypes: string[]
allowedFileExtensions: string[]
allowedFileUploadMethods: TransferMethod[]
}
export type BaseConfiguration = {
label: string
variable: string // Variable name
maxLength?: number // Max length for text input
placeholder?: string
required: boolean
showOptional?: boolean // show optional label
showConditions: ShowCondition[] // Show this field only when all conditions are met
type: BaseFieldType
tooltip?: string // Tooltip for this field
} & NumberConfiguration
& Partial<SelectConfiguration>
& Partial<FileConfiguration>
export type BaseFormProps = {
initialData?: Record<string, any>
configurations: BaseConfiguration[]
CustomActions?: (props: CustomActionsProps) => React.ReactNode
onSubmit: (value: Record<string, any>) => void
}

View File

@@ -0,0 +1,57 @@
import type { ZodNumber, ZodSchema, ZodString } from 'zod'
import { z } from 'zod'
import { type BaseConfiguration, BaseFieldType } from './types'
export const generateZodSchema = (fields: BaseConfiguration[]) => {
const shape: Record<string, ZodSchema> = {}
fields.forEach((field) => {
let zodType
switch (field.type) {
case BaseFieldType.textInput:
case BaseFieldType.paragraph:
zodType = z.string()
break
case BaseFieldType.numberInput:
zodType = z.number()
break
case BaseFieldType.checkbox:
zodType = z.boolean()
break
case BaseFieldType.select:
zodType = z.string()
break
default:
zodType = z.any()
break
}
if (field.maxLength) {
if ([BaseFieldType.textInput, BaseFieldType.paragraph].includes(field.type))
zodType = (zodType as ZodString).max(field.maxLength, `${field.label} exceeds max length of ${field.maxLength}`)
}
if (field.min) {
if ([BaseFieldType.numberInput].includes(field.type))
zodType = (zodType as ZodNumber).min(field.min, `${field.label} must be at least ${field.min}`)
}
if (field.max) {
if ([BaseFieldType.numberInput].includes(field.type))
zodType = (zodType as ZodNumber).max(field.max, `${field.label} exceeds max value of ${field.max}`)
}
if (field.required) {
if ([BaseFieldType.textInput, BaseFieldType.paragraph].includes(field.type))
zodType = (zodType as ZodString).nonempty(`${field.label} is required`)
}
else {
zodType = zodType.optional()
}
shape[field.variable] = zodType
})
return z.object(shape)
}

View File

@@ -24,7 +24,7 @@ const DemoForm = () => {
},
})
const name = useStore(form.store, state => state.values.name)
const name = useStore(form.store, state => state.values.name)
return (
<form
@@ -59,7 +59,7 @@ const name = useStore(form.store, state => state.values.name)
)
}
<form.AppForm>
<form.SubmitButton>Submit</form.SubmitButton>
<form.Actions />
</form.AppForm>
</form>
)

View File

@@ -0,0 +1,222 @@
import React from 'react'
import { type InputFieldConfiguration, InputFieldType } from './types'
import { withForm } from '../..'
import { useStore } from '@tanstack/react-form'
type InputFieldProps = {
initialData?: Record<string, any>
config: InputFieldConfiguration
}
const InputField = ({
initialData,
config,
}: InputFieldProps) => withForm({
defaultValues: initialData,
render: function Render({
form,
}) {
const {
type,
label,
placeholder,
variable,
tooltip,
showConditions,
max,
min,
required,
showOptional,
supportFile,
description,
options,
listeners,
popupProps,
} = config
const isAllConditionsMet = useStore(form.store, (state) => {
const fieldValues = state.values
return showConditions.every((condition) => {
const { variable, value } = condition
const fieldValue = fieldValues[variable as keyof typeof fieldValues]
return fieldValue === value
})
})
if (!isAllConditionsMet)
return <></>
if (type === InputFieldType.textInput) {
return (
<form.AppField
name={variable}
listeners={listeners}
children={field => (
<field.TextField
label={label}
labelOptions={{
tooltip,
isRequired: required,
showOptional,
}}
placeholder={placeholder}
/>
)}
/>
)
}
if (type === InputFieldType.numberInput) {
return (
<form.AppField
name={variable}
children={field => (
<field.NumberInputField
label={label}
labelOptions={{
tooltip,
isRequired: required,
showOptional,
}}
placeholder={placeholder}
max={max}
min={min}
/>
)}
/>
)
}
if (type === InputFieldType.numberSlider) {
return (
<form.AppField
name={variable}
children={field => (
<field.NumberSliderField
label={label}
labelOptions={{
tooltip,
isRequired: required,
showOptional,
}}
description={description}
max={max}
min={min}
/>
)}
/>
)
}
if (type === InputFieldType.checkbox) {
return (
<form.AppField
name={variable}
children={field => (
<field.CheckboxField
label={label}
/>
)}
/>
)
}
if (type === InputFieldType.select) {
return (
<form.AppField
name={variable}
children={field => (
<field.SelectField
label={label}
labelOptions={{
tooltip,
isRequired: required,
showOptional,
}}
options={options!}
popupProps={popupProps}
/>
)}
/>
)
}
if (type === InputFieldType.inputTypeSelect) {
return (
<form.AppField
name={variable}
listeners={listeners}
children={field => (
<field.InputTypeSelectField
label={label}
labelOptions={{
tooltip,
isRequired: required,
showOptional,
}}
supportFile={!!supportFile}
/>
)}
/>
)
}
if (type === InputFieldType.uploadMethod) {
return (
<form.AppField
name={variable}
children={field => (
<field.UploadMethodField
label={label}
labelOptions={{
tooltip,
isRequired: required,
showOptional,
}}
/>
)}
/>
)
}
if (type === InputFieldType.fileTypes) {
return (
<form.AppField
name={variable}
children={field => (
<field.FileTypesField
label={label}
labelOptions={{
tooltip,
isRequired: required,
showOptional,
}}
/>
)}
/>
)
}
if (type === InputFieldType.options) {
return (
<form.AppField
name={variable}
children={field => (
<field.OptionsField
label={label}
labelOptions={{
tooltip,
isRequired: required,
showOptional,
}}
/>
)}
/>
)
}
return <></>
},
})
export default InputField

View File

@@ -0,0 +1,39 @@
import type { DeepKeys, FieldListeners } from '@tanstack/react-form'
import type { NumberConfiguration, SelectConfiguration, ShowCondition } from '../base/types'
export enum InputFieldType {
textInput = 'textInput',
numberInput = 'numberInput',
numberSlider = 'numberSlider',
checkbox = 'checkbox',
options = 'options',
select = 'select',
inputTypeSelect = 'inputTypeSelect',
uploadMethod = 'uploadMethod',
fileTypes = 'fileTypes',
}
export type InputTypeSelectConfiguration = {
supportFile: boolean
}
export type NumberSliderConfiguration = {
description: string
max?: number
min?: number
}
export type InputFieldConfiguration = {
label: string
variable: string // Variable name
maxLength?: number // Max length for text input
placeholder?: string
required: boolean
showOptional?: boolean // show optional label
showConditions: ShowCondition[] // Show this field only when all conditions are met
type: InputFieldType
tooltip?: string // Tooltip for this field
listeners?: FieldListeners<Record<string, any>, DeepKeys<Record<string, any>>> // Listener for this field
} & NumberConfiguration & Partial<InputTypeSelectConfiguration>
& Partial<NumberSliderConfiguration>
& Partial<SelectConfiguration>

View File

@@ -0,0 +1,75 @@
import type { ZodSchema, ZodString } from 'zod'
import { z } from 'zod'
import { type InputFieldConfiguration, InputFieldType } from './types'
import { SupportedFileTypes, TransferMethod } from '@/app/components/rag-pipeline/components/input-field/editor/form/schema'
export const generateZodSchema = (fields: InputFieldConfiguration[]) => {
const shape: Record<string, ZodSchema> = {}
fields.forEach((field) => {
let zodType
switch (field.type) {
case InputFieldType.textInput:
zodType = z.string()
break
case InputFieldType.numberInput:
zodType = z.number()
break
case InputFieldType.numberSlider:
zodType = z.number()
break
case InputFieldType.checkbox:
zodType = z.boolean()
break
case InputFieldType.options:
zodType = z.array(z.string())
break
case InputFieldType.select:
zodType = z.string()
break
case InputFieldType.fileTypes:
zodType = z.object({
allowedFileExtensions: z.string().optional(),
allowedFileTypes: z.array(SupportedFileTypes),
})
break
case InputFieldType.inputTypeSelect:
zodType = z.string()
break
case InputFieldType.uploadMethod:
zodType = z.array(TransferMethod)
break
default:
zodType = z.any()
break
}
if (field.maxLength) {
if ([InputFieldType.textInput].includes(field.type))
zodType = (zodType as ZodString).max(field.maxLength, `${field.label} exceeds max length of ${field.maxLength}`)
}
if (field.min) {
if ([InputFieldType.numberInput].includes(field.type))
zodType = (zodType as ZodString).min(field.min, `${field.label} must be at least ${field.min}`)
}
if (field.max) {
if ([InputFieldType.numberInput].includes(field.type))
zodType = (zodType as ZodString).max(field.max, `${field.label} exceeds max value of ${field.max}`)
}
if (field.required) {
if ([InputFieldType.textInput].includes(field.type))
zodType = (zodType as ZodString).nonempty(`${field.label} is required`)
}
else {
zodType = zodType.optional()
}
shape[field.variable] = zodType
})
return z.object(shape)
}

View File

@@ -0,0 +1,239 @@
import React from 'react'
import { type InputFieldConfiguration, InputFieldType } from './types'
import { withForm } from '../..'
import { useStore } from '@tanstack/react-form'
type InputFieldProps = {
initialData?: Record<string, any>
config: InputFieldConfiguration
}
const NodePanelField = ({
initialData,
config,
}: InputFieldProps) => withForm({
defaultValues: initialData,
render: function Render({
form,
}) {
const {
type,
label,
placeholder,
variable,
tooltip,
showConditions,
max,
min,
required,
showOptional,
supportFile,
description,
options,
listeners,
popupProps,
} = config
const isAllConditionsMet = useStore(form.store, (state) => {
const fieldValues = state.values
return showConditions.every((condition) => {
const { variable, value } = condition
const fieldValue = fieldValues[variable as keyof typeof fieldValues]
return fieldValue === value
})
})
if (!isAllConditionsMet)
return <></>
if (type === InputFieldType.textInput) {
return (
<form.AppField
name={variable}
children={field => (
<field.TextField
label={label}
labelOptions={{
tooltip,
isRequired: required,
showOptional,
}}
placeholder={placeholder}
/>
)}
/>
)
}
if (type === InputFieldType.numberInput) {
return (
<form.AppField
name={variable}
children={field => (
<field.NumberInputField
label={label}
labelOptions={{
tooltip,
isRequired: required,
showOptional,
}}
placeholder={placeholder}
max={max}
min={min}
/>
)}
/>
)
}
if (type === InputFieldType.numberSlider) {
return (
<form.AppField
name={variable}
children={field => (
<field.NumberSliderField
label={label}
labelOptions={{
tooltip,
isRequired: required,
showOptional,
}}
description={description}
max={max}
min={min}
/>
)}
/>
)
}
if (type === InputFieldType.checkbox) {
return (
<form.AppField
name={variable}
children={field => (
<field.CheckboxField
label={label}
/>
)}
/>
)
}
if (type === InputFieldType.select) {
return (
<form.AppField
name={variable}
children={field => (
<field.SelectField
label={label}
labelOptions={{
tooltip,
isRequired: required,
showOptional,
}}
options={options!}
popupProps={popupProps}
/>
)}
/>
)
}
if (type === InputFieldType.inputTypeSelect) {
return (
<form.AppField
name={variable}
listeners={listeners}
children={field => (
<field.InputTypeSelectField
label={label}
labelOptions={{
tooltip,
isRequired: required,
showOptional,
}}
supportFile={!!supportFile}
/>
)}
/>
)
}
if (type === InputFieldType.uploadMethod) {
return (
<form.AppField
name={variable}
children={field => (
<field.UploadMethodField
label={label}
labelOptions={{
tooltip,
isRequired: required,
showOptional,
}}
/>
)}
/>
)
}
if (type === InputFieldType.fileTypes) {
return (
<form.AppField
name={variable}
children={field => (
<field.FileTypesField
label={label}
labelOptions={{
tooltip,
isRequired: required,
showOptional,
}}
/>
)}
/>
)
}
if (type === InputFieldType.options) {
return (
<form.AppField
name={variable}
children={field => (
<field.OptionsField
label={label}
labelOptions={{
tooltip,
isRequired: required,
showOptional,
}}
/>
)}
/>
)
}
if (type === InputFieldType.variableOrConstant) {
return (
<form.AppField
name={variable}
children={field => (
<field.VariableOrConstantInputField
label={label}
labelOptions={{
tooltip,
isRequired: required,
showOptional,
}}
/>
)}
/>
)
}
return <></>
},
})
export default NodePanelField

View File

@@ -0,0 +1,40 @@
import type { DeepKeys, FieldListeners } from '@tanstack/react-form'
import type { NumberConfiguration, SelectConfiguration, ShowCondition } from '../base/types'
export enum InputFieldType {
textInput = 'textInput',
numberInput = 'numberInput',
numberSlider = 'numberSlider',
checkbox = 'checkbox',
options = 'options',
select = 'select',
inputTypeSelect = 'inputTypeSelect',
uploadMethod = 'uploadMethod',
fileTypes = 'fileTypes',
variableOrConstant = 'variableOrConstant',
}
export type InputTypeSelectConfiguration = {
supportFile: boolean
}
export type NumberSliderConfiguration = {
description: string
max?: number
min?: number
}
export type InputFieldConfiguration = {
label: string
variable: string // Variable name
maxLength?: number // Max length for text input
placeholder?: string
required: boolean
showOptional?: boolean // show optional label
showConditions: ShowCondition[] // Show this field only when all conditions are met
type: InputFieldType
tooltip?: string // Tooltip for this field
listeners?: FieldListeners<Record<string, any>, DeepKeys<Record<string, any>>> // Listener for this field
} & NumberConfiguration & Partial<InputTypeSelectConfiguration>
& Partial<NumberSliderConfiguration>
& Partial<SelectConfiguration>

View File

@@ -3,8 +3,16 @@ import TextField from './components/field/text'
import NumberInputField from './components/field/number-input'
import CheckboxField from './components/field/checkbox'
import SelectField from './components/field/select'
import CustomSelectField from './components/field/custom-select'
import OptionsField from './components/field/options'
import SubmitButton from './components/form/submit-button'
import Actions from './components/form/actions'
import InputTypeSelectField from './components/field/input-type-select'
import FileTypesField from './components/field/file-types'
import UploadMethodField from './components/field/upload-method'
import NumberSliderField from './components/field/number-slider'
import VariableOrConstantInputField from './components/field/variable-selector'
import TextAreaField from './components/field/text-area'
import FileUploaderField from './components/field/file-uploader'
export const { fieldContext, useFieldContext, formContext, useFormContext }
= createFormHookContexts()
@@ -12,14 +20,24 @@ export const { fieldContext, useFieldContext, formContext, useFormContext }
export const { useAppForm, withForm } = createFormHook({
fieldComponents: {
TextField,
TextAreaField,
NumberInputField,
CheckboxField,
SelectField,
CustomSelectField,
OptionsField,
InputTypeSelectField,
FileTypesField,
UploadMethodField,
NumberSliderField,
VariableOrConstantInputField,
FileUploaderField,
},
formComponents: {
SubmitButton,
Actions,
},
fieldContext,
formContext,
})
export type FormType = ReturnType<typeof useFormContext>

View File

@@ -0,0 +1,29 @@
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M10.5996 0.5C11.7113 0.5 12.5755 0.500118 13.2676 0.556641C13.9655 0.61366 14.5329 0.730378 15.043 0.990234L15.3525 1.16406C16.0576 1.59644 16.6322 2.21605 17.0098 2.95703L17.1006 3.15137C17.2979 3.61108 17.3935 4.12184 17.4434 4.73242C17.4999 5.42447 17.5 6.28869 17.5 7.40039V10.5996C17.5 11.7113 17.4999 12.5755 17.4434 13.2676C17.3935 13.8782 17.2979 14.3889 17.1006 14.8486L17.0098 15.043C16.6322 15.7839 16.0576 16.4036 15.3525 16.8359L15.043 17.0098C14.5329 17.2696 13.9655 17.3863 13.2676 17.4434C12.5755 17.4999 11.7113 17.5 10.5996 17.5H7.40039C6.28869 17.5 5.42447 17.4999 4.73242 17.4434C4.12184 17.3935 3.61108 17.2979 3.15137 17.1006L2.95703 17.0098C2.21605 16.6322 1.59644 16.0576 1.16406 15.3525L0.990234 15.043C0.730378 14.5329 0.61366 13.9655 0.556641 13.2676C0.500118 12.5755 0.5 11.7113 0.5 10.5996V7.40039C0.5 6.28869 0.500118 5.42447 0.556641 4.73242C0.61366 4.03453 0.730378 3.46707 0.990234 2.95703L1.16406 2.64746C1.59644 1.94243 2.21605 1.36778 2.95703 0.990234L3.15137 0.899414C3.61108 0.702129 4.12184 0.606527 4.73242 0.556641C5.42447 0.500118 6.28869 0.5 7.40039 0.5H10.5996Z" stroke="white"/>
<path d="M1 7.4C1 5.15979 1 4.03969 1.43597 3.18404C1.81947 2.43139 2.43139 1.81947 3.18404 1.43597C4.03969 1 5.15979 1 7.4 1H10.6C12.8402 1 13.9603 1 14.816 1.43597C15.5686 1.81947 16.1805 2.43139 16.564 3.18404C17 4.03969 17 5.15979 17 7.4V10.6C17 12.8402 17 13.9603 16.564 14.816C16.1805 15.5686 15.5686 16.1805 14.816 16.564C13.9603 17 12.8402 17 10.6 17H7.4C5.15979 17 4.03969 17 3.18404 16.564C2.43139 16.1805 1.81947 15.5686 1.43597 14.816C1 13.9603 1 12.8402 1 10.6V7.4Z" fill="#828DAD"/>
<path d="M1 7.4C1 5.15979 1 4.03969 1.43597 3.18404C1.81947 2.43139 2.43139 1.81947 3.18404 1.43597C4.03969 1 5.15979 1 7.4 1H10.6C12.8402 1 13.9603 1 14.816 1.43597C15.5686 1.81947 16.1805 2.43139 16.564 3.18404C17 4.03969 17 5.15979 17 7.4V10.6C17 12.8402 17 13.9603 16.564 14.816C16.1805 15.5686 15.5686 16.1805 14.816 16.564C13.9603 17 12.8402 17 10.6 17H7.4C5.15979 17 4.03969 17 3.18404 16.564C2.43139 16.1805 1.81947 15.5686 1.43597 14.816C1 13.9603 1 12.8402 1 10.6V7.4Z" fill="url(#paint0_linear_5617_78238)"/>
<path d="M7.40039 1.5H10.5996C11.728 1.5 12.5446 1.50029 13.1865 1.55273C13.7434 1.59824 14.1352 1.68127 14.4561 1.81934L14.5889 1.88184C15.1651 2.17543 15.6471 2.62172 15.9834 3.16992L16.1182 3.41113C16.2942 3.75672 16.3953 4.17741 16.4473 4.81348C16.4997 5.4554 16.5 6.27204 16.5 7.40039V10.5996C16.5 11.728 16.4997 12.5446 16.4473 13.1865C16.4018 13.7434 16.3187 14.1352 16.1807 14.4561L16.1182 14.5889C15.8246 15.1651 15.3783 15.6471 14.8301 15.9834L14.5889 16.1182C14.2433 16.2942 13.8226 16.3953 13.1865 16.4473C12.5446 16.4997 11.728 16.5 10.5996 16.5H7.40039C6.27204 16.5 5.4554 16.4997 4.81348 16.4473C4.2566 16.4018 3.8648 16.3187 3.54395 16.1807L3.41113 16.1182C2.83494 15.8246 2.35287 15.3783 2.0166 14.8301L1.88184 14.5889C1.70575 14.2433 1.60471 13.8226 1.55273 13.1865C1.50029 12.5446 1.5 11.728 1.5 10.5996V7.40039C1.5 6.27204 1.50029 5.4554 1.55273 4.81348C1.59824 4.2566 1.68127 3.8648 1.81934 3.54395L1.88184 3.41113C2.17543 2.83494 2.62172 2.35287 3.16992 2.0166L3.41113 1.88184C3.75672 1.70575 4.17741 1.60471 4.81348 1.55273C5.4554 1.50029 6.27204 1.5 7.40039 1.5Z" stroke="#101828" stroke-opacity="0.08"/>
<g filter="url(#filter0_d_5617_78238)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M9 5.5C7.067 5.5 5.5 7.067 5.5 9C5.5 10.933 7.067 12.5 9 12.5C10.2949 12.5 11.4261 11.7971 12.032 10.7496C12.1703 10.5106 12.4762 10.4289 12.7152 10.5672C12.9542 10.7055 13.0359 11.0113 12.8977 11.2504C12.1204 12.5941 10.6662 13.5 9 13.5C6.68372 13.5 4.77619 11.75 4.52746 9.5H4C3.72386 9.5 3.5 9.27614 3.5 9C3.5 8.72386 3.72386 8.5 4 8.5H4.52746C4.77619 6.25002 6.68372 4.5 9 4.5C10.6662 4.5 12.1204 5.40588 12.8977 6.74964C13.0359 6.98867 12.9542 7.29454 12.7152 7.43281C12.4762 7.57107 12.1703 7.48939 12.032 7.25036C11.4261 6.20291 10.2949 5.5 9 5.5ZM9 7.5C8.17157 7.5 7.5 8.17157 7.5 9C7.5 9.82841 8.17158 10.5 9 10.5C9.82841 10.5 10.5 9.82841 10.5 9C10.5 8.17158 9.82841 7.5 9 7.5ZM6.5 9C6.5 7.61929 7.61929 6.5 9 6.5C10.2095 6.5 11.2184 7.35888 11.45 8.5H14C14.2761 8.5 14.5 8.72386 14.5 9C14.5 9.27614 14.2761 9.5 14 9.5H11.45C11.2183 10.6411 10.2095 11.5 9 11.5C7.61928 11.5 6.5 10.3807 6.5 9Z" fill="url(#paint1_linear_5617_78238)" shape-rendering="crispEdges"/>
</g>
<defs>
<filter id="filter0_d_5617_78238" x="3" y="4.25" width="12" height="10" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="0.25"/>
<feGaussianBlur stdDeviation="0.25"/>
<feComposite in2="hardAlpha" operator="out"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.2 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_5617_78238"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_5617_78238" result="shape"/>
</filter>
<linearGradient id="paint0_linear_5617_78238" x1="1" y1="1" x2="17" y2="17" gradientUnits="userSpaceOnUse">
<stop stop-color="white" stop-opacity="0.12"/>
<stop offset="1" stop-color="white" stop-opacity="0.08"/>
</linearGradient>
<linearGradient id="paint1_linear_5617_78238" x1="9" y1="4.5" x2="9" y2="13.5" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0.9"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 5.5 KiB

View File

@@ -0,0 +1,54 @@
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M10.5996 0.5C11.7113 0.5 12.5755 0.500118 13.2676 0.556641C13.9655 0.61366 14.5329 0.730378 15.043 0.990234L15.3525 1.16406C16.0576 1.59644 16.6322 2.21605 17.0098 2.95703L17.1006 3.15137C17.2979 3.61108 17.3935 4.12184 17.4434 4.73242C17.4999 5.42447 17.5 6.28869 17.5 7.40039V10.5996C17.5 11.7113 17.4999 12.5755 17.4434 13.2676C17.3935 13.8782 17.2979 14.3889 17.1006 14.8486L17.0098 15.043C16.6322 15.7839 16.0576 16.4036 15.3525 16.8359L15.043 17.0098C14.5329 17.2696 13.9655 17.3863 13.2676 17.4434C12.5755 17.4999 11.7113 17.5 10.5996 17.5H7.40039C6.28869 17.5 5.42447 17.4999 4.73242 17.4434C4.12184 17.3935 3.61108 17.2979 3.15137 17.1006L2.95703 17.0098C2.21605 16.6322 1.59644 16.0576 1.16406 15.3525L0.990234 15.043C0.730378 14.5329 0.61366 13.9655 0.556641 13.2676C0.500118 12.5755 0.5 11.7113 0.5 10.5996V7.40039C0.5 6.28869 0.500118 5.42447 0.556641 4.73242C0.61366 4.03453 0.730378 3.46707 0.990234 2.95703L1.16406 2.64746C1.59644 1.94243 2.21605 1.36778 2.95703 0.990234L3.15137 0.899414C3.61108 0.702129 4.12184 0.606527 4.73242 0.556641C5.42447 0.500118 6.28869 0.5 7.40039 0.5H10.5996Z" stroke="white"/>
<path d="M1 7.4C1 5.15979 1 4.03969 1.43597 3.18404C1.81947 2.43139 2.43139 1.81947 3.18404 1.43597C4.03969 1 5.15979 1 7.4 1H10.6C12.8402 1 13.9603 1 14.816 1.43597C15.5686 1.81947 16.1805 2.43139 16.564 3.18404C17 4.03969 17 5.15979 17 7.4V10.6C17 12.8402 17 13.9603 16.564 14.816C16.1805 15.5686 15.5686 16.1805 14.816 16.564C13.9603 17 12.8402 17 10.6 17H7.4C5.15979 17 4.03969 17 3.18404 16.564C2.43139 16.1805 1.81947 15.5686 1.43597 14.816C1 13.9603 1 12.8402 1 10.6V7.4Z" fill="#444CE7"/>
<path d="M1 7.4C1 5.15979 1 4.03969 1.43597 3.18404C1.81947 2.43139 2.43139 1.81947 3.18404 1.43597C4.03969 1 5.15979 1 7.4 1H10.6C12.8402 1 13.9603 1 14.816 1.43597C15.5686 1.81947 16.1805 2.43139 16.564 3.18404C17 4.03969 17 5.15979 17 7.4V10.6C17 12.8402 17 13.9603 16.564 14.816C16.1805 15.5686 15.5686 16.1805 14.816 16.564C13.9603 17 12.8402 17 10.6 17H7.4C5.15979 17 4.03969 17 3.18404 16.564C2.43139 16.1805 1.81947 15.5686 1.43597 14.816C1 13.9603 1 12.8402 1 10.6V7.4Z" fill="url(#paint0_linear_5617_78288)"/>
<path d="M7.40039 1.5H10.5996C11.728 1.5 12.5446 1.50029 13.1865 1.55273C13.7434 1.59824 14.1352 1.68127 14.4561 1.81934L14.5889 1.88184C15.1651 2.17543 15.6471 2.62172 15.9834 3.16992L16.1182 3.41113C16.2942 3.75672 16.3953 4.17741 16.4473 4.81348C16.4997 5.4554 16.5 6.27204 16.5 7.40039V10.5996C16.5 11.728 16.4997 12.5446 16.4473 13.1865C16.4018 13.7434 16.3187 14.1352 16.1807 14.4561L16.1182 14.5889C15.8246 15.1651 15.3783 15.6471 14.8301 15.9834L14.5889 16.1182C14.2433 16.2942 13.8226 16.3953 13.1865 16.4473C12.5446 16.4997 11.728 16.5 10.5996 16.5H7.40039C6.27204 16.5 5.4554 16.4997 4.81348 16.4473C4.2566 16.4018 3.8648 16.3187 3.54395 16.1807L3.41113 16.1182C2.83494 15.8246 2.35287 15.3783 2.0166 14.8301L1.88184 14.5889C1.70575 14.2433 1.60471 13.8226 1.55273 13.1865C1.50029 12.5446 1.5 11.728 1.5 10.5996V7.40039C1.5 6.27204 1.50029 5.4554 1.55273 4.81348C1.59824 4.2566 1.68127 3.8648 1.81934 3.54395L1.88184 3.41113C2.17543 2.83494 2.62172 2.35287 3.16992 2.0166L3.41113 1.88184C3.75672 1.70575 4.17741 1.60471 4.81348 1.55273C5.4554 1.50029 6.27204 1.5 7.40039 1.5Z" stroke="#101828" stroke-opacity="0.08"/>
<g filter="url(#filter0_d_5617_78288)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.25 5.5C11.25 5.08579 11.5858 4.75 12 4.75H13.5C13.9142 4.75 14.25 5.08579 14.25 5.5C14.25 5.91421 13.9142 6.25 13.5 6.25H12C11.5858 6.25 11.25 5.91421 11.25 5.5Z" fill="url(#paint1_linear_5617_78288)" shape-rendering="crispEdges"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.75 5.5C3.75 5.08579 4.08579 4.75 4.5 4.75H9.5C9.91421 4.75 10.25 5.08579 10.25 5.5C10.25 5.91421 9.91421 6.25 9.5 6.25H4.5C4.08579 6.25 3.75 5.91421 3.75 5.5Z" fill="url(#paint2_linear_5617_78288)" shape-rendering="crispEdges"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.75 9C3.75 8.58579 4.08579 8.25 4.5 8.25H6C6.41421 8.25 6.75 8.58579 6.75 9C6.75 9.41421 6.41421 9.75 6 9.75H4.5C4.08579 9.75 3.75 9.41421 3.75 9Z" fill="url(#paint3_linear_5617_78288)" shape-rendering="crispEdges"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.75 9C7.75 8.58579 8.08579 8.25 8.5 8.25H13.5C13.9142 8.25 14.25 8.58579 14.25 9C14.25 9.41421 13.9142 9.75 13.5 9.75H8.5C8.08579 9.75 7.75 9.41421 7.75 9Z" fill="url(#paint4_linear_5617_78288)" shape-rendering="crispEdges"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.25 12.5C11.25 12.0858 11.5858 11.75 12 11.75H13.5C13.9142 11.75 14.25 12.0858 14.25 12.5C14.25 12.9142 13.9142 13.25 13.5 13.25H12C11.5858 13.25 11.25 12.9142 11.25 12.5Z" fill="url(#paint5_linear_5617_78288)" shape-rendering="crispEdges"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.75 12.5C3.75 12.0858 4.08579 11.75 4.5 11.75H9.5C9.91421 11.75 10.25 12.0858 10.25 12.5C10.25 12.9142 9.91421 13.25 9.5 13.25H4.5C4.08579 13.25 3.75 12.9142 3.75 12.5Z" fill="url(#paint6_linear_5617_78288)" shape-rendering="crispEdges"/>
</g>
<defs>
<filter id="filter0_d_5617_78288" x="3.25" y="4.5" width="11.5" height="9.5" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="0.25"/>
<feGaussianBlur stdDeviation="0.25"/>
<feComposite in2="hardAlpha" operator="out"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.2 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_5617_78288"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_5617_78288" result="shape"/>
</filter>
<linearGradient id="paint0_linear_5617_78288" x1="1" y1="1" x2="17" y2="17" gradientUnits="userSpaceOnUse">
<stop stop-color="white" stop-opacity="0.12"/>
<stop offset="1" stop-color="white" stop-opacity="0.08"/>
</linearGradient>
<linearGradient id="paint1_linear_5617_78288" x1="9" y1="4.75" x2="9" y2="13.25" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0.9"/>
</linearGradient>
<linearGradient id="paint2_linear_5617_78288" x1="9" y1="4.75" x2="9" y2="13.25" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0.9"/>
</linearGradient>
<linearGradient id="paint3_linear_5617_78288" x1="9" y1="4.75" x2="9" y2="13.25" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0.9"/>
</linearGradient>
<linearGradient id="paint4_linear_5617_78288" x1="9" y1="4.75" x2="9" y2="13.25" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0.9"/>
</linearGradient>
<linearGradient id="paint5_linear_5617_78288" x1="9" y1="4.75" x2="9" y2="13.25" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0.9"/>
</linearGradient>
<linearGradient id="paint6_linear_5617_78288" x1="9" y1="4.75" x2="9" y2="13.25" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0.9"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 7.2 KiB

View File

@@ -0,0 +1,124 @@
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M10.5996 0.5C11.7113 0.5 12.5755 0.500118 13.2676 0.556641C13.9655 0.61366 14.5329 0.730378 15.043 0.990234L15.3525 1.16406C16.0576 1.59644 16.6322 2.21605 17.0098 2.95703L17.1006 3.15137C17.2979 3.61108 17.3935 4.12184 17.4434 4.73242C17.4999 5.42447 17.5 6.28869 17.5 7.40039V10.5996C17.5 11.7113 17.4999 12.5755 17.4434 13.2676C17.3935 13.8782 17.2979 14.3889 17.1006 14.8486L17.0098 15.043C16.6322 15.7839 16.0576 16.4036 15.3525 16.8359L15.043 17.0098C14.5329 17.2696 13.9655 17.3863 13.2676 17.4434C12.5755 17.4999 11.7113 17.5 10.5996 17.5H7.40039C6.28869 17.5 5.42447 17.4999 4.73242 17.4434C4.12184 17.3935 3.61108 17.2979 3.15137 17.1006L2.95703 17.0098C2.21605 16.6322 1.59644 16.0576 1.16406 15.3525L0.990234 15.043C0.730378 14.5329 0.61366 13.9655 0.556641 13.2676C0.500118 12.5755 0.5 11.7113 0.5 10.5996V7.40039C0.5 6.28869 0.500118 5.42447 0.556641 4.73242C0.61366 4.03453 0.730378 3.46707 0.990234 2.95703L1.16406 2.64746C1.59644 1.94243 2.21605 1.36778 2.95703 0.990234L3.15137 0.899414C3.61108 0.702129 4.12184 0.606527 4.73242 0.556641C5.42447 0.500118 6.28869 0.5 7.40039 0.5H10.5996Z" stroke="white"/>
<path d="M1 7.4C1 5.15979 1 4.03969 1.43597 3.18404C1.81947 2.43139 2.43139 1.81947 3.18404 1.43597C4.03969 1 5.15979 1 7.4 1H10.6C12.8402 1 13.9603 1 14.816 1.43597C15.5686 1.81947 16.1805 2.43139 16.564 3.18404C17 4.03969 17 5.15979 17 7.4V10.6C17 12.8402 17 13.9603 16.564 14.816C16.1805 15.5686 15.5686 16.1805 14.816 16.564C13.9603 17 12.8402 17 10.6 17H7.4C5.15979 17 4.03969 17 3.18404 16.564C2.43139 16.1805 1.81947 15.5686 1.43597 14.816C1 13.9603 1 12.8402 1 10.6V7.4Z" fill="#7839EE"/>
<path d="M1 7.4C1 5.15979 1 4.03969 1.43597 3.18404C1.81947 2.43139 2.43139 1.81947 3.18404 1.43597C4.03969 1 5.15979 1 7.4 1H10.6C12.8402 1 13.9603 1 14.816 1.43597C15.5686 1.81947 16.1805 2.43139 16.564 3.18404C17 4.03969 17 5.15979 17 7.4V10.6C17 12.8402 17 13.9603 16.564 14.816C16.1805 15.5686 15.5686 16.1805 14.816 16.564C13.9603 17 12.8402 17 10.6 17H7.4C5.15979 17 4.03969 17 3.18404 16.564C2.43139 16.1805 1.81947 15.5686 1.43597 14.816C1 13.9603 1 12.8402 1 10.6V7.4Z" fill="url(#paint0_linear_5617_78246)"/>
<path d="M7.40039 1.5H10.5996C11.728 1.5 12.5446 1.50029 13.1865 1.55273C13.7434 1.59824 14.1352 1.68127 14.4561 1.81934L14.5889 1.88184C15.1651 2.17543 15.6471 2.62172 15.9834 3.16992L16.1182 3.41113C16.2942 3.75672 16.3953 4.17741 16.4473 4.81348C16.4997 5.4554 16.5 6.27204 16.5 7.40039V10.5996C16.5 11.728 16.4997 12.5446 16.4473 13.1865C16.4018 13.7434 16.3187 14.1352 16.1807 14.4561L16.1182 14.5889C15.8246 15.1651 15.3783 15.6471 14.8301 15.9834L14.5889 16.1182C14.2433 16.2942 13.8226 16.3953 13.1865 16.4473C12.5446 16.4997 11.728 16.5 10.5996 16.5H7.40039C6.27204 16.5 5.4554 16.4997 4.81348 16.4473C4.2566 16.4018 3.8648 16.3187 3.54395 16.1807L3.41113 16.1182C2.83494 15.8246 2.35287 15.3783 2.0166 14.8301L1.88184 14.5889C1.70575 14.2433 1.60471 13.8226 1.55273 13.1865C1.50029 12.5446 1.5 11.728 1.5 10.5996V7.40039C1.5 6.27204 1.50029 5.4554 1.55273 4.81348C1.59824 4.2566 1.68127 3.8648 1.81934 3.54395L1.88184 3.41113C2.17543 2.83494 2.62172 2.35287 3.16992 2.0166L3.41113 1.88184C3.75672 1.70575 4.17741 1.60471 4.81348 1.55273C5.4554 1.50029 6.27204 1.5 7.40039 1.5Z" stroke="#101828" stroke-opacity="0.08"/>
<g clip-path="url(#clip0_5617_78246)">
<g filter="url(#filter0_d_5617_78246)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.00004 5.31818C9.27619 5.31818 9.50004 5.54204 9.50004 5.81818V8.09091C9.50004 8.36705 9.27619 8.59091 9.00004 8.59091C8.7239 8.59091 8.50004 8.36705 8.50004 8.09091V5.81818C8.50004 5.54204 8.7239 5.31818 9.00004 5.31818Z" fill="url(#paint1_linear_5617_78246)" shape-rendering="crispEdges"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.00004 9.40909C9.27619 9.40909 9.50004 9.63295 9.50004 9.90909V12.1818C9.50004 12.458 9.27619 12.6818 9.00004 12.6818C8.7239 12.6818 8.50004 12.458 8.50004 12.1818V9.90909C8.50004 9.63295 8.7239 9.40909 9.00004 9.40909Z" fill="url(#paint2_linear_5617_78246)" shape-rendering="crispEdges"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.64355 5.1094C8.77894 5.35007 8.6936 5.65493 8.45293 5.79033L6.40065 6.94487C6.15998 7.08027 5.85512 6.99492 5.71973 6.75425C5.58433 6.51358 5.66968 6.20872 5.91035 6.07332L7.96262 4.91878C8.20329 4.78338 8.50815 4.86873 8.64355 5.1094Z" fill="url(#paint3_linear_5617_78246)" shape-rendering="crispEdges"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.35653 5.1094C9.49193 4.86873 9.79679 4.78338 10.0375 4.91878L12.0897 6.07332C12.3304 6.20872 12.4158 6.51358 12.2804 6.75425C12.145 6.99492 11.8401 7.08027 11.5994 6.94487L9.54715 5.79033C9.30648 5.65493 9.22114 5.35007 9.35653 5.1094Z" fill="url(#paint4_linear_5617_78246)" shape-rendering="crispEdges"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.71973 11.2458C5.85512 11.0051 6.15998 10.9197 6.40065 11.0551L8.45293 12.2097C8.6936 12.3451 8.77894 12.6499 8.64355 12.8906C8.50815 13.1313 8.20329 13.2166 7.96262 13.0812L5.91035 11.9267C5.66968 11.7913 5.58433 11.4864 5.71973 11.2458Z" fill="url(#paint5_linear_5617_78246)" shape-rendering="crispEdges"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.2804 11.2458C12.4158 11.4864 12.3304 11.7913 12.0897 11.9267L10.0375 13.0812C9.79679 13.2166 9.49193 13.1313 9.35653 12.8906C9.22114 12.6499 9.30648 12.3451 9.54715 12.2097L11.5994 11.0551C11.8401 10.9197 12.145 11.0051 12.2804 11.2458Z" fill="url(#paint6_linear_5617_78246)" shape-rendering="crispEdges"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.36368 7.36364C5.63982 7.36364 5.86368 7.58749 5.86368 7.86364V10.1364C5.86368 10.4125 5.63982 10.6364 5.36368 10.6364C5.08754 10.6364 4.86368 10.4125 4.86368 10.1364V7.86364C4.86368 7.58749 5.08754 7.36364 5.36368 7.36364Z" fill="url(#paint7_linear_5617_78246)" shape-rendering="crispEdges"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.6364 7.36364C12.9126 7.36364 13.1364 7.58749 13.1364 7.86364V10.1364C13.1364 10.4125 12.9126 10.6364 12.6364 10.6364C12.3603 10.6364 12.1364 10.4125 12.1364 10.1364V7.86364C12.1364 7.58749 12.3603 7.36364 12.6364 7.36364Z" fill="url(#paint8_linear_5617_78246)" shape-rendering="crispEdges"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.71928 7.1544C5.85467 6.91373 6.15953 6.82838 6.4002 6.96377L8.45338 8.11877C8.69406 8.25416 8.77941 8.55902 8.64402 8.79969C8.50863 9.04037 8.20377 9.12572 7.96309 8.99033L5.90991 7.83533C5.66924 7.69994 5.58389 7.39508 5.71928 7.1544Z" fill="url(#paint9_linear_5617_78246)" shape-rendering="crispEdges"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.2799 7.15488C12.4153 7.39557 12.3299 7.70042 12.0892 7.8358L10.0374 8.98989C9.79675 9.12527 9.49189 9.0399 9.35652 8.79922C9.22114 8.55854 9.30651 8.25368 9.54719 8.1183L11.599 6.96421C11.8397 6.82884 12.1445 6.9142 12.2799 7.15488Z" fill="url(#paint10_linear_5617_78246)" shape-rendering="crispEdges"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.64402 9.20031C8.77941 9.44099 8.69406 9.74585 8.45338 9.88124L6.4002 11.0362C6.15953 11.1716 5.85467 11.0863 5.71928 10.8456C5.58389 10.6049 5.66924 10.3001 5.90991 10.1647L7.96309 9.00968C8.20377 8.87429 8.50863 8.95964 8.64402 9.20031Z" fill="url(#paint11_linear_5617_78246)" shape-rendering="crispEdges"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.35652 9.20078C9.49189 8.9601 9.79675 8.87473 10.0374 9.01011L12.0892 10.1642C12.3299 10.2996 12.4153 10.6044 12.2799 10.8451C12.1445 11.0858 11.8397 11.1712 11.599 11.0358L9.54719 9.8817C9.30651 9.74632 9.22114 9.44146 9.35652 9.20078Z" fill="url(#paint12_linear_5617_78246)" shape-rendering="crispEdges"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.36368 10.6364C5.13775 10.6364 4.95459 10.8195 4.95459 11.0455C4.95459 11.2714 5.13775 11.4545 5.36368 11.4545C5.58962 11.4545 5.77277 11.2714 5.77277 11.0455C5.77277 10.8195 5.58962 10.6364 5.36368 10.6364ZM3.95459 11.0455C3.95459 10.2672 4.58546 9.63636 5.36368 9.63636C6.1419 9.63636 6.77277 10.2672 6.77277 11.0455C6.77277 11.8237 6.1419 12.4545 5.36368 12.4545C4.58546 12.4545 3.95459 11.8237 3.95459 11.0455Z" fill="url(#paint13_linear_5617_78246)" shape-rendering="crispEdges"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.36368 6.54545C5.13775 6.54545 4.95459 6.72861 4.95459 6.95455C4.95459 7.18048 5.13775 7.36364 5.36368 7.36364C5.58962 7.36364 5.77277 7.18048 5.77277 6.95455C5.77277 6.72861 5.58962 6.54545 5.36368 6.54545ZM3.95459 6.95455C3.95459 6.17633 4.58546 5.54545 5.36368 5.54545C6.1419 5.54545 6.77277 6.17633 6.77277 6.95455C6.77277 7.73276 6.1419 8.36364 5.36368 8.36364C4.58546 8.36364 3.95459 7.73276 3.95459 6.95455Z" fill="url(#paint14_linear_5617_78246)" shape-rendering="crispEdges"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.6364 10.6364C12.4105 10.6364 12.2273 10.8195 12.2273 11.0455C12.2273 11.2714 12.4105 11.4545 12.6364 11.4545C12.8623 11.4545 13.0455 11.2714 13.0455 11.0455C13.0455 10.8195 12.8623 10.6364 12.6364 10.6364ZM11.2273 11.0455C11.2273 10.2672 11.8582 9.63636 12.6364 9.63636C13.4146 9.63636 14.0455 10.2672 14.0455 11.0455C14.0455 11.8237 13.4146 12.4545 12.6364 12.4545C11.8582 12.4545 11.2273 11.8237 11.2273 11.0455Z" fill="url(#paint15_linear_5617_78246)" shape-rendering="crispEdges"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.6364 6.54545C12.4105 6.54545 12.2273 6.72861 12.2273 6.95455C12.2273 7.18048 12.4105 7.36364 12.6364 7.36364C12.8623 7.36364 13.0455 7.18048 13.0455 6.95455C13.0455 6.72861 12.8623 6.54545 12.6364 6.54545ZM11.2273 6.95455C11.2273 6.17633 11.8582 5.54545 12.6364 5.54545C13.4146 5.54545 14.0455 6.17633 14.0455 6.95455C14.0455 7.73276 13.4146 8.36364 12.6364 8.36364C11.8582 8.36364 11.2273 7.73276 11.2273 6.95455Z" fill="url(#paint16_linear_5617_78246)" shape-rendering="crispEdges"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.00004 8.59091C8.77411 8.59091 8.59095 8.77407 8.59095 9C8.59095 9.22593 8.77411 9.40909 9.00004 9.40909C9.22598 9.40909 9.40914 9.22593 9.40914 9C9.40914 8.77407 9.22598 8.59091 9.00004 8.59091ZM7.59095 9C7.59095 8.22178 8.22182 7.59091 9.00004 7.59091C9.77826 7.59091 10.4091 8.22178 10.4091 9C10.4091 9.77822 9.77826 10.4091 9.00004 10.4091C8.22182 10.4091 7.59095 9.77822 7.59095 9Z" fill="url(#paint17_linear_5617_78246)" shape-rendering="crispEdges"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.00004 4.5C8.77411 4.5 8.59095 4.68316 8.59095 4.90909C8.59095 5.13503 8.77411 5.31818 9.00004 5.31818C9.22598 5.31818 9.40914 5.13503 9.40914 4.90909C9.40914 4.68316 9.22598 4.5 9.00004 4.5ZM7.59095 4.90909C7.59095 4.13087 8.22182 3.5 9.00004 3.5C9.77826 3.5 10.4091 4.13087 10.4091 4.90909C10.4091 5.68731 9.77826 6.31818 9.00004 6.31818C8.22182 6.31818 7.59095 5.68731 7.59095 4.90909Z" fill="url(#paint18_linear_5617_78246)" shape-rendering="crispEdges"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.00004 12.6818C8.77411 12.6818 8.59095 12.865 8.59095 13.0909C8.59095 13.3168 8.77411 13.5 9.00004 13.5C9.22598 13.5 9.40914 13.3168 9.40914 13.0909C9.40914 12.865 9.22598 12.6818 9.00004 12.6818ZM7.59095 13.0909C7.59095 12.3127 8.22182 11.6818 9.00004 11.6818C9.77826 11.6818 10.4091 12.3127 10.4091 13.0909C10.4091 13.8691 9.77826 14.5 9.00004 14.5C8.22182 14.5 7.59095 13.8691 7.59095 13.0909Z" fill="url(#paint19_linear_5617_78246)" shape-rendering="crispEdges"/>
</g>
</g>
<defs>
<filter id="filter0_d_5617_78246" x="3.45459" y="3.25" width="11.0908" height="12" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="0.25"/>
<feGaussianBlur stdDeviation="0.25"/>
<feComposite in2="hardAlpha" operator="out"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.2 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_5617_78246"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_5617_78246" result="shape"/>
</filter>
<linearGradient id="paint0_linear_5617_78246" x1="1" y1="1" x2="17" y2="17" gradientUnits="userSpaceOnUse">
<stop stop-color="white" stop-opacity="0.12"/>
<stop offset="1" stop-color="white" stop-opacity="0.08"/>
</linearGradient>
<linearGradient id="paint1_linear_5617_78246" x1="9.00004" y1="3.5" x2="9.00004" y2="14.5" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0.9"/>
</linearGradient>
<linearGradient id="paint2_linear_5617_78246" x1="9.00004" y1="3.5" x2="9.00004" y2="14.5" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0.9"/>
</linearGradient>
<linearGradient id="paint3_linear_5617_78246" x1="9.00004" y1="3.5" x2="9.00004" y2="14.5" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0.9"/>
</linearGradient>
<linearGradient id="paint4_linear_5617_78246" x1="9.00004" y1="3.5" x2="9.00004" y2="14.5" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0.9"/>
</linearGradient>
<linearGradient id="paint5_linear_5617_78246" x1="9.00004" y1="3.5" x2="9.00004" y2="14.5" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0.9"/>
</linearGradient>
<linearGradient id="paint6_linear_5617_78246" x1="9.00004" y1="3.5" x2="9.00004" y2="14.5" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0.9"/>
</linearGradient>
<linearGradient id="paint7_linear_5617_78246" x1="9.00004" y1="3.5" x2="9.00004" y2="14.5" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0.9"/>
</linearGradient>
<linearGradient id="paint8_linear_5617_78246" x1="9.00004" y1="3.5" x2="9.00004" y2="14.5" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0.9"/>
</linearGradient>
<linearGradient id="paint9_linear_5617_78246" x1="9.00004" y1="3.5" x2="9.00004" y2="14.5" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0.9"/>
</linearGradient>
<linearGradient id="paint10_linear_5617_78246" x1="9.00004" y1="3.5" x2="9.00004" y2="14.5" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0.9"/>
</linearGradient>
<linearGradient id="paint11_linear_5617_78246" x1="9.00004" y1="3.5" x2="9.00004" y2="14.5" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0.9"/>
</linearGradient>
<linearGradient id="paint12_linear_5617_78246" x1="9.00004" y1="3.5" x2="9.00004" y2="14.5" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0.9"/>
</linearGradient>
<linearGradient id="paint13_linear_5617_78246" x1="9.00004" y1="3.5" x2="9.00004" y2="14.5" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0.9"/>
</linearGradient>
<linearGradient id="paint14_linear_5617_78246" x1="9.00004" y1="3.5" x2="9.00004" y2="14.5" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0.9"/>
</linearGradient>
<linearGradient id="paint15_linear_5617_78246" x1="9.00004" y1="3.5" x2="9.00004" y2="14.5" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0.9"/>
</linearGradient>
<linearGradient id="paint16_linear_5617_78246" x1="9.00004" y1="3.5" x2="9.00004" y2="14.5" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0.9"/>
</linearGradient>
<linearGradient id="paint17_linear_5617_78246" x1="9.00004" y1="3.5" x2="9.00004" y2="14.5" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0.9"/>
</linearGradient>
<linearGradient id="paint18_linear_5617_78246" x1="9.00004" y1="3.5" x2="9.00004" y2="14.5" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0.9"/>
</linearGradient>
<linearGradient id="paint19_linear_5617_78246" x1="9.00004" y1="3.5" x2="9.00004" y2="14.5" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0.9"/>
</linearGradient>
<clipPath id="clip0_5617_78246">
<rect width="12" height="12" fill="white" transform="translate(3 3)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -0,0 +1,44 @@
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M10.5996 0.5C11.7113 0.5 12.5755 0.500118 13.2676 0.556641C13.9655 0.61366 14.5329 0.730378 15.043 0.990234L15.3525 1.16406C16.0576 1.59644 16.6322 2.21605 17.0098 2.95703L17.1006 3.15137C17.2979 3.61108 17.3935 4.12184 17.4434 4.73242C17.4999 5.42447 17.5 6.28869 17.5 7.40039V10.5996C17.5 11.7113 17.4999 12.5755 17.4434 13.2676C17.3935 13.8782 17.2979 14.3889 17.1006 14.8486L17.0098 15.043C16.6322 15.7839 16.0576 16.4036 15.3525 16.8359L15.043 17.0098C14.5329 17.2696 13.9655 17.3863 13.2676 17.4434C12.5755 17.4999 11.7113 17.5 10.5996 17.5H7.40039C6.28869 17.5 5.42447 17.4999 4.73242 17.4434C4.12184 17.3935 3.61108 17.2979 3.15137 17.1006L2.95703 17.0098C2.21605 16.6322 1.59644 16.0576 1.16406 15.3525L0.990234 15.043C0.730378 14.5329 0.61366 13.9655 0.556641 13.2676C0.500118 12.5755 0.5 11.7113 0.5 10.5996V7.40039C0.5 6.28869 0.500118 5.42447 0.556641 4.73242C0.61366 4.03453 0.730378 3.46707 0.990234 2.95703L1.16406 2.64746C1.59644 1.94243 2.21605 1.36778 2.95703 0.990234L3.15137 0.899414C3.61108 0.702129 4.12184 0.606527 4.73242 0.556641C5.42447 0.500118 6.28869 0.5 7.40039 0.5H10.5996Z" stroke="white"/>
<path d="M1 7.4C1 5.15979 1 4.03969 1.43597 3.18404C1.81947 2.43139 2.43139 1.81947 3.18404 1.43597C4.03969 1 5.15979 1 7.4 1H10.6C12.8402 1 13.9603 1 14.816 1.43597C15.5686 1.81947 16.1805 2.43139 16.564 3.18404C17 4.03969 17 5.15979 17 7.4V10.6C17 12.8402 17 13.9603 16.564 14.816C16.1805 15.5686 15.5686 16.1805 14.816 16.564C13.9603 17 12.8402 17 10.6 17H7.4C5.15979 17 4.03969 17 3.18404 16.564C2.43139 16.1805 1.81947 15.5686 1.43597 14.816C1 13.9603 1 12.8402 1 10.6V7.4Z" fill="#0BA5EC"/>
<path d="M1 7.4C1 5.15979 1 4.03969 1.43597 3.18404C1.81947 2.43139 2.43139 1.81947 3.18404 1.43597C4.03969 1 5.15979 1 7.4 1H10.6C12.8402 1 13.9603 1 14.816 1.43597C15.5686 1.81947 16.1805 2.43139 16.564 3.18404C17 4.03969 17 5.15979 17 7.4V10.6C17 12.8402 17 13.9603 16.564 14.816C16.1805 15.5686 15.5686 16.1805 14.816 16.564C13.9603 17 12.8402 17 10.6 17H7.4C5.15979 17 4.03969 17 3.18404 16.564C2.43139 16.1805 1.81947 15.5686 1.43597 14.816C1 13.9603 1 12.8402 1 10.6V7.4Z" fill="url(#paint0_linear_5617_78274)"/>
<path d="M7.40039 1.5H10.5996C11.728 1.5 12.5446 1.50029 13.1865 1.55273C13.7434 1.59824 14.1352 1.68127 14.4561 1.81934L14.5889 1.88184C15.1651 2.17543 15.6471 2.62172 15.9834 3.16992L16.1182 3.41113C16.2942 3.75672 16.3953 4.17741 16.4473 4.81348C16.4997 5.4554 16.5 6.27204 16.5 7.40039V10.5996C16.5 11.728 16.4997 12.5446 16.4473 13.1865C16.4018 13.7434 16.3187 14.1352 16.1807 14.4561L16.1182 14.5889C15.8246 15.1651 15.3783 15.6471 14.8301 15.9834L14.5889 16.1182C14.2433 16.2942 13.8226 16.3953 13.1865 16.4473C12.5446 16.4997 11.728 16.5 10.5996 16.5H7.40039C6.27204 16.5 5.4554 16.4997 4.81348 16.4473C4.2566 16.4018 3.8648 16.3187 3.54395 16.1807L3.41113 16.1182C2.83494 15.8246 2.35287 15.3783 2.0166 14.8301L1.88184 14.5889C1.70575 14.2433 1.60471 13.8226 1.55273 13.1865C1.50029 12.5446 1.5 11.728 1.5 10.5996V7.40039C1.5 6.27204 1.50029 5.4554 1.55273 4.81348C1.59824 4.2566 1.68127 3.8648 1.81934 3.54395L1.88184 3.41113C2.17543 2.83494 2.62172 2.35287 3.16992 2.0166L3.41113 1.88184C3.75672 1.70575 4.17741 1.60471 4.81348 1.55273C5.4554 1.50029 6.27204 1.5 7.40039 1.5Z" stroke="#101828" stroke-opacity="0.08"/>
<g clip-path="url(#clip0_5617_78274)">
<g filter="url(#filter0_d_5617_78274)">
<path d="M6.70834 6.87516C7.51375 6.87516 8.16667 6.22224 8.16667 5.41683C8.16667 4.61141 7.51375 3.9585 6.70834 3.9585C5.90292 3.9585 5.25001 4.61141 5.25001 5.41683C5.25001 6.22224 5.90292 6.87516 6.70834 6.87516Z" fill="url(#paint1_linear_5617_78274)" shape-rendering="crispEdges"/>
<path d="M11.2917 6.87516C12.0971 6.87516 12.75 6.22224 12.75 5.41683C12.75 4.61141 12.0971 3.9585 11.2917 3.9585C10.4863 3.9585 9.83334 4.61141 9.83334 5.41683C9.83334 6.22224 10.4863 6.87516 11.2917 6.87516Z" fill="url(#paint2_linear_5617_78274)" shape-rendering="crispEdges"/>
<path d="M11.2917 7.70849C10.8377 7.709 10.3912 7.82377 9.99324 8.04222C9.59529 8.26067 9.25874 8.57578 9.01459 8.95849C9.34482 8.96235 9.66011 9.09673 9.89159 9.33229C10.1231 9.56785 10.2519 9.88545 10.25 10.2157C10.2481 10.5459 10.1155 10.862 9.8813 11.0949C9.6471 11.3277 9.33026 11.4584 9 11.4584C8.66975 11.4584 8.35291 11.3277 8.1187 11.0949C7.8845 10.862 7.75195 10.5459 7.75003 10.2157C7.7481 9.88545 7.87695 9.56785 8.10842 9.33229C8.3399 9.09673 8.65519 8.96235 8.98542 8.95849C8.67086 8.46429 8.20432 8.08561 7.656 7.87941C7.10767 7.67321 6.50721 7.65065 5.94496 7.81512C5.3827 7.97959 4.88906 8.32219 4.53831 8.79139C4.18755 9.26059 3.99864 9.83101 4.00001 10.4168V13.1252C4.00001 13.2357 4.04391 13.3416 4.12205 13.4198C4.20019 13.4979 4.30617 13.5418 4.41667 13.5418H7.33334V12.5002L5.83334 11.3752C5.78957 11.3423 5.75269 11.3012 5.72481 11.2541C5.69693 11.207 5.6786 11.1549 5.67086 11.1008C5.65523 10.9914 5.6837 10.8802 5.75001 10.7918C5.81631 10.7034 5.91502 10.645 6.02441 10.6293C6.13381 10.6137 6.24493 10.6422 6.33334 10.7085L7.88875 11.8752H10.1113L11.6667 10.7085C11.7551 10.6422 11.8662 10.6137 11.9756 10.6293C12.085 10.645 12.1837 10.7034 12.25 10.7918C12.3163 10.8802 12.3448 10.9914 12.3291 11.1008C12.3135 11.2101 12.2551 11.3089 12.1667 11.3752L10.6667 12.5002V13.5418H13.5833C13.6938 13.5418 13.7998 13.4979 13.878 13.4198C13.9561 13.3416 14 13.2357 14 13.1252V10.4168C13.9991 9.6988 13.7135 9.01044 13.2058 8.50272C12.6981 7.995 12.0097 7.70938 11.2917 7.70849Z" fill="url(#paint3_linear_5617_78274)" shape-rendering="crispEdges"/>
</g>
</g>
<defs>
<filter id="filter0_d_5617_78274" x="3.5" y="3.7085" width="11" height="10.5835" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="0.25"/>
<feGaussianBlur stdDeviation="0.25"/>
<feComposite in2="hardAlpha" operator="out"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.2 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_5617_78274"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_5617_78274" result="shape"/>
</filter>
<linearGradient id="paint0_linear_5617_78274" x1="1" y1="1" x2="17" y2="17" gradientUnits="userSpaceOnUse">
<stop stop-color="white" stop-opacity="0.12"/>
<stop offset="1" stop-color="white" stop-opacity="0.08"/>
</linearGradient>
<linearGradient id="paint1_linear_5617_78274" x1="9" y1="3.9585" x2="9" y2="13.5418" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0.9"/>
</linearGradient>
<linearGradient id="paint2_linear_5617_78274" x1="9" y1="3.9585" x2="9" y2="13.5418" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0.9"/>
</linearGradient>
<linearGradient id="paint3_linear_5617_78274" x1="9" y1="3.9585" x2="9" y2="13.5418" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0.9"/>
</linearGradient>
<clipPath id="clip0_5617_78274">
<rect width="12" height="12" fill="white" transform="translate(3 3)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 7.2 KiB

View File

@@ -0,0 +1,29 @@
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M10.5996 0.5C11.7113 0.5 12.5755 0.500118 13.2676 0.556641C13.9655 0.61366 14.5329 0.730378 15.043 0.990234L15.3525 1.16406C16.0576 1.59644 16.6322 2.21605 17.0098 2.95703L17.1006 3.15137C17.2979 3.61108 17.3935 4.12184 17.4434 4.73242C17.4999 5.42447 17.5 6.28869 17.5 7.40039V10.5996C17.5 11.7113 17.4999 12.5755 17.4434 13.2676C17.3935 13.8782 17.2979 14.3889 17.1006 14.8486L17.0098 15.043C16.6322 15.7839 16.0576 16.4036 15.3525 16.8359L15.043 17.0098C14.5329 17.2696 13.9655 17.3863 13.2676 17.4434C12.5755 17.4999 11.7113 17.5 10.5996 17.5H7.40039C6.28869 17.5 5.42447 17.4999 4.73242 17.4434C4.12184 17.3935 3.61108 17.2979 3.15137 17.1006L2.95703 17.0098C2.21605 16.6322 1.59644 16.0576 1.16406 15.3525L0.990234 15.043C0.730378 14.5329 0.61366 13.9655 0.556641 13.2676C0.500118 12.5755 0.5 11.7113 0.5 10.5996V7.40039C0.5 6.28869 0.500118 5.42447 0.556641 4.73242C0.61366 4.03453 0.730378 3.46707 0.990234 2.95703L1.16406 2.64746C1.59644 1.94243 2.21605 1.36778 2.95703 0.990234L3.15137 0.899414C3.61108 0.702129 4.12184 0.606527 4.73242 0.556641C5.42447 0.500118 6.28869 0.5 7.40039 0.5H10.5996Z" stroke="white"/>
<path d="M1 7.4C1 5.15979 1 4.03969 1.43597 3.18404C1.81947 2.43139 2.43139 1.81947 3.18404 1.43597C4.03969 1 5.15979 1 7.4 1H10.6C12.8402 1 13.9603 1 14.816 1.43597C15.5686 1.81947 16.1805 2.43139 16.564 3.18404C17 4.03969 17 5.15979 17 7.4V10.6C17 12.8402 17 13.9603 16.564 14.816C16.1805 15.5686 15.5686 16.1805 14.816 16.564C13.9603 17 12.8402 17 10.6 17H7.4C5.15979 17 4.03969 17 3.18404 16.564C2.43139 16.1805 1.81947 15.5686 1.43597 14.816C1 13.9603 1 12.8402 1 10.6V7.4Z" fill="#0E9384"/>
<path d="M1 7.4C1 5.15979 1 4.03969 1.43597 3.18404C1.81947 2.43139 2.43139 1.81947 3.18404 1.43597C4.03969 1 5.15979 1 7.4 1H10.6C12.8402 1 13.9603 1 14.816 1.43597C15.5686 1.81947 16.1805 2.43139 16.564 3.18404C17 4.03969 17 5.15979 17 7.4V10.6C17 12.8402 17 13.9603 16.564 14.816C16.1805 15.5686 15.5686 16.1805 14.816 16.564C13.9603 17 12.8402 17 10.6 17H7.4C5.15979 17 4.03969 17 3.18404 16.564C2.43139 16.1805 1.81947 15.5686 1.43597 14.816C1 13.9603 1 12.8402 1 10.6V7.4Z" fill="url(#paint0_linear_5617_78260)"/>
<path d="M7.40039 1.5H10.5996C11.728 1.5 12.5446 1.50029 13.1865 1.55273C13.7434 1.59824 14.1352 1.68127 14.4561 1.81934L14.5889 1.88184C15.1651 2.17543 15.6471 2.62172 15.9834 3.16992L16.1182 3.41113C16.2942 3.75672 16.3953 4.17741 16.4473 4.81348C16.4997 5.4554 16.5 6.27204 16.5 7.40039V10.5996C16.5 11.728 16.4997 12.5446 16.4473 13.1865C16.4018 13.7434 16.3187 14.1352 16.1807 14.4561L16.1182 14.5889C15.8246 15.1651 15.3783 15.6471 14.8301 15.9834L14.5889 16.1182C14.2433 16.2942 13.8226 16.3953 13.1865 16.4473C12.5446 16.4997 11.728 16.5 10.5996 16.5H7.40039C6.27204 16.5 5.4554 16.4997 4.81348 16.4473C4.2566 16.4018 3.8648 16.3187 3.54395 16.1807L3.41113 16.1182C2.83494 15.8246 2.35287 15.3783 2.0166 14.8301L1.88184 14.5889C1.70575 14.2433 1.60471 13.8226 1.55273 13.1865C1.50029 12.5446 1.5 11.728 1.5 10.5996V7.40039C1.5 6.27204 1.50029 5.4554 1.55273 4.81348C1.59824 4.2566 1.68127 3.8648 1.81934 3.54395L1.88184 3.41113C2.17543 2.83494 2.62172 2.35287 3.16992 2.0166L3.41113 1.88184C3.75672 1.70575 4.17741 1.60471 4.81348 1.55273C5.4554 1.50029 6.27204 1.5 7.40039 1.5Z" stroke="#101828" stroke-opacity="0.08"/>
<g filter="url(#filter0_d_5617_78260)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M14.001 5.5C14.001 4.94772 13.5533 4.5 13.001 4.5H7.00098C6.44869 4.5 6.00098 4.94772 6.00098 5.5V6.5H5.00098C4.44869 6.5 4.00098 6.94772 4.00098 7.5V11.5C4.00098 12.0523 4.44869 12.5 5.00098 12.5H5.50098V13.25C5.50098 13.4271 5.59473 13.5911 5.74742 13.681C5.9001 13.7708 6.08894 13.7731 6.2438 13.6871L8.38055 12.5H11.001C11.5533 12.5 12.001 12.0523 12.001 11.5V10.5H13.001C13.5533 10.5 14.001 10.0523 14.001 9.5V5.5ZM11.001 6.5H7.00098V5.5H13.001V9.5H12.001V7.5C12.001 6.94772 11.5533 6.5 11.001 6.5ZM6.5 8C6.22386 8 6 8.22386 6 8.5C6 8.77614 6.22386 9 6.5 9H9.5C9.77614 9 10 8.77614 10 8.5C10 8.22386 9.77614 8 9.5 8H6.5ZM6.5 10C6.22386 10 6 10.2239 6 10.5C6 10.7761 6.22386 11 6.5 11H8C8.27614 11 8.5 10.7761 8.5 10.5C8.5 10.2239 8.27614 10 8 10H6.5Z" fill="url(#paint1_linear_5617_78260)" shape-rendering="crispEdges"/>
</g>
<defs>
<filter id="filter0_d_5617_78260" x="3.50098" y="4.25" width="11" height="10.25" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="0.25"/>
<feGaussianBlur stdDeviation="0.25"/>
<feComposite in2="hardAlpha" operator="out"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.2 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_5617_78260"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_5617_78260" result="shape"/>
</filter>
<linearGradient id="paint0_linear_5617_78260" x1="1" y1="1" x2="17" y2="17" gradientUnits="userSpaceOnUse">
<stop stop-color="white" stop-opacity="0.12"/>
<stop offset="1" stop-color="white" stop-opacity="0.08"/>
</linearGradient>
<linearGradient id="paint1_linear_5617_78260" x1="9.00099" y1="4.5" x2="9.00099" y2="13.75" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="1" stop-color="white" stop-opacity="0.9"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 5.3 KiB

View File

@@ -0,0 +1,4 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.66667 1.34356C8.66667 1.32602 8.66667 1.31725 8.66591 1.30135C8.65018 0.972168 8.3607 0.682824 8.03151 0.667251C8.01562 0.666499 8.0104 0.666501 8.00001 0.666504H5.8391C5.30248 0.666497 4.85957 0.666491 4.49878 0.695968C4.12405 0.726585 3.77958 0.792295 3.45603 0.957155C2.95426 1.21282 2.54631 1.62077 2.29065 2.12253C2.12579 2.44609 2.06008 2.79056 2.02946 3.16529C1.99999 3.52608 1.99999 3.96899 2 4.50562V11.494C1.99999 12.0307 1.99999 12.4736 2.02946 12.8344C2.06008 13.2091 2.12579 13.5536 2.29065 13.8771C2.54631 14.3789 2.95426 14.7869 3.45603 15.0425C3.77958 15.2074 4.12405 15.2731 4.49878 15.3037C4.85958 15.3332 5.30248 15.3332 5.83912 15.3332H10.1609C10.6975 15.3332 11.1404 15.3332 11.5012 15.3037C11.8759 15.2731 12.2204 15.2074 12.544 15.0425C13.0457 14.7869 13.4537 14.3789 13.7093 13.8771C13.8742 13.5536 13.9399 13.2091 13.9705 12.8344C14 12.4736 14 12.0307 14 11.4941V6.66646C14 6.65611 14 6.65093 13.9993 6.63505C13.9837 6.30583 13.6943 6.01631 13.3651 6.0006C13.3492 5.99985 13.3405 5.99985 13.323 5.99985L10.3787 5.99985C10.2105 5.99987 10.0466 5.99989 9.90785 5.98855C9.75545 5.9761 9.57563 5.94672 9.39468 5.85452C9.1438 5.72669 8.93983 5.52272 8.81199 5.27183C8.7198 5.09088 8.69042 4.91106 8.67797 4.75867C8.66663 4.61989 8.66665 4.45603 8.66667 4.28778L8.66667 1.34356ZM5.33333 8.6665C4.96514 8.6665 4.66667 8.96498 4.66667 9.33317C4.66667 9.70136 4.96514 9.99984 5.33333 9.99984H10.6667C11.0349 9.99984 11.3333 9.70136 11.3333 9.33317C11.3333 8.96498 11.0349 8.6665 10.6667 8.6665H5.33333ZM5.33333 11.3332C4.96514 11.3332 4.66667 11.6316 4.66667 11.9998C4.66667 12.368 4.96514 12.6665 5.33333 12.6665H9.33333C9.70152 12.6665 10 12.368 10 11.9998C10 11.6316 9.70152 11.3332 9.33333 11.3332H5.33333Z" fill="#444CE7"/>
<path d="M12.6053 4.6665C12.8011 4.6665 12.8989 4.6665 12.9791 4.61735C13.0923 4.54794 13.16 4.3844 13.129 4.25526C13.107 4.16382 13.0432 4.10006 12.9155 3.97253L10.694 1.75098C10.5664 1.62333 10.5027 1.5595 10.4112 1.53752C10.2821 1.50648 10.1186 1.57417 10.0492 1.6874C10 1.76757 10 1.86545 10 2.0612L10 4.13315C10 4.31982 10 4.41316 10.0363 4.48446C10.0683 4.54718 10.1193 4.59818 10.182 4.63014C10.2533 4.66647 10.3466 4.66647 10.5333 4.66647L12.6053 4.6665Z" fill="#444CE7"/>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@@ -1,5 +0,0 @@
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="Icon L">
<path id="Vector" fill-rule="evenodd" clip-rule="evenodd" d="M6 0.5C6.27615 0.5 6.5 0.72386 6.5 1V1.52755C6.95855 1.57831 7.3967 1.69804 7.80355 1.87619L8.067 1.41997C8.20505 1.18083 8.51085 1.09889 8.75 1.23696C8.98915 1.37503 9.07105 1.68082 8.933 1.91998L8.6692 2.37685C9.033 2.64523 9.3548 2.96707 9.6232 3.33084L10.0801 3.06703C10.3193 2.92896 10.6251 3.0109 10.7632 3.25005C10.9012 3.4892 10.8193 3.79499 10.5801 3.93306L10.1238 4.19649C10.302 4.60333 10.4218 5.0415 10.4725 5.50005H11C11.2761 5.50005 11.5 5.7239 11.5 6.00005C11.5 6.2762 11.2761 6.50005 11 6.50005H10.4725C10.4218 6.9586 10.302 7.3968 10.1238 7.80365L10.5801 8.0671C10.8193 8.20515 10.9012 8.51095 10.7632 8.7501C10.6251 8.98925 10.3193 9.0712 10.0801 8.9331L9.6232 8.6693C9.3548 9.03305 9.03295 9.3549 8.6692 9.62325L8.933 10.0802C9.07105 10.3193 8.98915 10.6251 8.75 10.7632C8.51085 10.9012 8.20505 10.8193 8.067 10.5802L7.80355 10.1239C7.3967 10.3021 6.95855 10.4218 6.5 10.4726V11C6.5 11.2761 6.27615 11.5 6 11.5C5.72385 11.5 5.5 11.2761 5.5 11V10.4726C5.04145 10.4218 4.60328 10.3021 4.19644 10.1239L3.933 10.5802C3.79493 10.8194 3.48914 10.9013 3.24999 10.7633C3.01084 10.6252 2.92891 10.3194 3.06698 10.0802L3.3308 9.62325C2.96702 9.3549 2.64517 9.03305 2.37678 8.66925L1.91986 8.93305C1.68071 9.07115 1.37492 8.9892 1.23685 8.75005C1.09878 8.5109 1.18072 8.2051 1.41986 8.06705L1.87612 7.8036C1.69797 7.39675 1.57824 6.9586 1.52749 6.50005L0.999975 6.5C0.723835 6.5 0.499987 6.2761 0.5 6C0.500015 5.72385 0.72388 5.5 1.00003 5.5L1.5275 5.50005C1.57825 5.0415 1.69796 4.60335 1.87611 4.19652L1.41987 3.93312C1.18072 3.79504 1.09878 3.48925 1.23685 3.2501C1.37492 3.01095 1.68071 2.92901 1.91985 3.06709L2.37675 3.33086C2.64514 2.96708 2.967 2.64524 3.33078 2.37684L3.06698 1.91992C2.92891 1.68077 3.01084 1.37498 3.24999 1.23691C3.48914 1.09884 3.79493 1.18077 3.933 1.41992L4.19642 1.87619C4.60327 1.69803 5.04145 1.57831 5.5 1.52755V1C5.5 0.72386 5.72385 0.5 6 0.5ZM3.83484 3.24991C3.48643 3.52463 3.19141 3.86415 2.96808 4.25014C2.67048 4.7645 2.49999 5.3616 2.49999 6.00005C2.49999 6.6385 2.67048 7.2356 2.96809 7.75C3.19142 8.13595 3.48645 8.4755 3.83486 8.7502L4.8599 6.97475C4.63581 6.71285 4.49999 6.37245 4.49999 6.00005C4.49999 5.62765 4.63581 5.28725 4.8599 5.02535L3.83484 3.24991ZM5.7258 4.52514L4.70041 2.74911C5.10185 2.58847 5.5402 2.50005 6 2.50005C6.63845 2.50005 7.23555 2.67054 7.74995 2.96816C8.28125 3.27557 8.7245 3.71882 9.0319 4.25012C9.2503 4.62764 9.4003 5.04975 9.4646 5.50005H7.41465C7.2087 4.91745 6.6531 4.50005 6 4.50005C5.9065 4.50005 5.8148 4.50865 5.7258 4.52514ZM7.41465 6.50005C7.2087 7.08265 6.6531 7.50005 6 7.50005C5.9065 7.50005 5.8148 7.49145 5.7258 7.47495L4.70043 9.251C5.10185 9.41165 5.5402 9.50005 6 9.50005C6.63845 9.50005 7.23555 9.32955 7.7499 9.03195C8.2812 8.72455 8.72445 8.2813 9.03185 7.75C9.2503 7.3725 9.4003 6.95035 9.4646 6.50005H7.41465Z" fill="#676F83"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.0 KiB

View File

@@ -1,5 +0,0 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="Icon L">
<path id="Vector" d="M14.0002 2C14.3684 2 14.6668 2.29848 14.6668 2.66667V13.3333C14.6668 13.7015 14.3684 14 14.0002 14H2.00016C1.63198 14 1.3335 13.7015 1.3335 13.3333V2.66667C1.3335 2.29848 1.63198 2 2.00016 2H14.0002ZM13.3335 3.33333H2.66683V12.6667H13.3335V3.33333ZM14.0002 2.66667V13.3333H10.0002V2.66667H14.0002Z" fill="#354052"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 461 B

View File

@@ -0,0 +1,12 @@
<svg width="212" height="74" viewBox="0 0 212 74" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="Effect" opacity="0.8" filter="url(#filter0_f_6128_88629)">
<circle cx="24" cy="24" r="28" fill="#0BA5EC"/>
</g>
<defs>
<filter id="filter0_f_6128_88629" x="-164" y="-164" width="376" height="376" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feGaussianBlur stdDeviation="80" result="effect1_foregroundBlur_6128_88629"/>
</filter>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 611 B

View File

@@ -0,0 +1,12 @@
<svg width="214" height="124" viewBox="0 0 214 124" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="Effect" opacity="0.5" filter="url(#filter0_f_6128_89310)">
<circle cx="26" cy="26" r="28" fill="#6172F3"/>
</g>
<defs>
<filter id="filter0_f_6128_89310" x="-162" y="-162" width="376" height="376" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feGaussianBlur stdDeviation="80" result="effect1_foregroundBlur_6128_89310"/>
</filter>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 613 B

View File

@@ -0,0 +1,12 @@
<svg width="220" height="220" viewBox="0 0 220 220" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="Effect" opacity="0.8" filter="url(#filter0_f_481_16338)">
<circle cx="32" cy="32" r="28" fill="#EF6820"/>
</g>
<defs>
<filter id="filter0_f_481_16338" x="-156" y="-156" width="376" height="376" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feGaussianBlur stdDeviation="80" result="effect1_foregroundBlur_481_16338"/>
</filter>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 610 B

View File

@@ -0,0 +1,12 @@
<svg width="220" height="220" viewBox="0 0 220 220" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="Effect" opacity="0.8" filter="url(#filter0_f_5863_82395)">
<circle cx="32" cy="32" r="28" fill="#6938EF"/>
</g>
<defs>
<filter id="filter0_f_5863_82395" x="-156" y="-156" width="376" height="376" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feGaussianBlur stdDeviation="80" result="effect1_foregroundBlur_5863_82395"/>
</filter>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 613 B

View File

@@ -1,7 +0,0 @@
<svg width="10" height="11" viewBox="0 0 10 11" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="Group">
<path id="Vector" d="M2.70833 3.87501C3.51375 3.87501 4.16666 3.22209 4.16666 2.41668C4.16666 1.61126 3.51375 0.958344 2.70833 0.958344C1.90292 0.958344 1.25 1.61126 1.25 2.41668C1.25 3.22209 1.90292 3.87501 2.70833 3.87501Z" fill="#676F83"/>
<path id="Vector_2" d="M7.29158 3.87501C8.097 3.87501 8.74992 3.22209 8.74992 2.41668C8.74992 1.61126 8.097 0.958344 7.29158 0.958344C6.48617 0.958344 5.83325 1.61126 5.83325 2.41668C5.83325 3.22209 6.48617 3.87501 7.29158 3.87501Z" fill="#676F83"/>
<path id="Vector_3" d="M7.29167 4.70835C6.83771 4.70886 6.39118 4.82363 5.99324 5.04208C5.59529 5.26053 5.25874 5.57563 5.01459 5.95835C5.34482 5.9622 5.66011 6.09658 5.89159 6.33215C6.12306 6.56771 6.25191 6.8853 6.24998 7.21555C6.24805 7.5458 6.11551 7.86187 5.8813 8.09472C5.6471 8.32756 5.33026 8.45826 5 8.45826C4.66975 8.45826 4.35291 8.32756 4.1187 8.09472C3.8845 7.86187 3.75195 7.5458 3.75003 7.21555C3.7481 6.8853 3.87695 6.56771 4.10842 6.33215C4.3399 6.09658 4.65519 5.9622 4.98542 5.95835C4.67086 5.46415 4.20432 5.08546 3.656 4.87926C3.10767 4.67306 2.50721 4.6505 1.94496 4.81497C1.3827 4.97944 0.889064 5.32205 0.538306 5.79125C0.187547 6.26045 -0.00135882 6.83086 7.35834e-06 7.41668V10.125C7.35834e-06 10.2355 0.043906 10.3415 0.122046 10.4196C0.200186 10.4978 0.306167 10.5417 0.416674 10.5417H3.33334V9.50001L1.83334 8.37501C1.78957 8.34218 1.75269 8.30105 1.72481 8.25397C1.69693 8.20688 1.6786 8.15477 1.67086 8.1006C1.65523 7.99121 1.6837 7.88008 1.75001 7.79168C1.81631 7.70327 1.91502 7.64483 2.02441 7.6292C2.13381 7.61357 2.24493 7.64204 2.33334 7.70835L3.88875 8.87501H6.11125L7.66667 7.70835C7.75507 7.64204 7.8662 7.61357 7.97559 7.6292C8.08499 7.64483 8.1837 7.70327 8.25 7.79168C8.31631 7.88008 8.34478 7.99121 8.32915 8.1006C8.31352 8.21 8.25507 8.30871 8.16667 8.37501L6.66667 9.50001V10.5417H9.58333C9.69384 10.5417 9.79982 10.4978 9.87796 10.4196C9.9561 10.3415 10 10.2355 10 10.125V7.41668C9.99912 6.69866 9.71349 6.01029 9.20577 5.50257C8.69805 4.99485 8.00969 4.70923 7.29167 4.70835Z" fill="#676F83"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.1 KiB

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500">
<path style="fill: rgb(0, 23, 87); stroke: rgb(13, 14, 52);" d="M 247.794 213.903 L 246.81 76.976 L 254.345 76.963 L 254.592 213.989 L 247.794 213.903 Z"/>
<ellipse style="fill: rgb(0, 23, 87); stroke: rgb(0, 23, 87);" cx="250.025" cy="43.859" rx="33.966" ry="33.906"/>
<path style="fill: rgb(30, 141, 166); stroke: rgb(30, 141, 166);" d="M 282.472 260.389 L 414.181 330.253 L 410.563 336.234 L 279.38 265.739 L 282.472 260.389 Z"/>
<path style="fill: rgb(15, 17, 57); stroke: rgb(13, 14, 52);" d="M 255.105 281.394 L 254.485 417.656 L 246.156 417.691 L 246.688 280.51 L 255.105 281.394 Z"/>
<path style="paint-order: fill; fill: rgb(30, 141, 166); stroke: rgb(30, 141, 166);" d="M 279.486 229.517 L 410.351 160.07 L 413.923 167.04 L 283.727 235.998 L 279.486 229.517 Z"/>
<path style="fill: rgb(15, 164, 161); stroke: rgb(15, 164, 161);" d="M 88.545 164.884 L 219.797 236.07 L 222.867 229.568 L 90.887 159.47 L 88.545 164.884 Z"/>
<path style="fill: rgb(15, 164, 161); stroke: rgb(15, 164, 161);" d="M 224.76 266.9 L 95.55 334.829 L 92.878 328.37 L 219.955 261.275 L 224.76 266.9 Z"/>
<ellipse style="paint-order: fill; fill: rgb(2, 181, 225); stroke: rgb(2, 181, 225);" cx="251.242" cy="247.466" rx="33.966" ry="33.906"/>
<path style="fill: rgb(13, 14, 52); stroke: rgb(13, 14, 52);" d="M 279.502 433.617 L 408.666 359.443 C 408.666 359.443 412.398 366.965 412.398 366.916 C 412.398 366.867 281.544 440.217 281.544 440.217 L 279.502 433.617 Z"/>
<path style="fill: rgb(13, 14, 52); stroke: rgb(13, 14, 52);" d="M 223.119 431.408 L 96.643 361.068 L 93.265 368.047 L 218.895 438.099 L 223.119 431.408 Z"/>
<ellipse style="fill: rgb(0, 23, 87); stroke: rgb(0, 23, 87);" cx="250.504" cy="451.168" rx="33.966" ry="33.906"/>
<path style="fill: rgb(90, 191, 187); stroke: rgb(90, 191, 187);" d="M 435.665 180.895 L 435.859 316.869 L 443.103 315.579 L 442.56 180.697 L 435.665 180.895 Z"/>
<ellipse style="fill: rgb(0, 23, 87); stroke: rgb(0, 23, 87);" cx="441.06" cy="349.665" rx="33.966" ry="33.906"/>
<ellipse style="fill: rgb(2, 181, 225); stroke: rgb(2, 181, 225);" cx="441.512" cy="147.767" rx="33.966" ry="33.906"/>
<path style="fill: rgb(84, 187, 181); stroke: rgb(84, 187, 181);" d="M 64.755 314.523 L 57.928 315.006 L 58.307 182.961 L 65.169 182.865 L 64.755 314.523 Z"/>
<ellipse style="fill: rgb(0, 23, 87); stroke: rgb(0, 23, 87);" cx="58.177" cy="149.757" rx="33.966" ry="33.906"/>
<ellipse style="fill: rgb(61, 224, 203); stroke: rgb(61, 224, 203);" cx="65.909" cy="348.17" rx="33.966" ry="33.906"/>
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@@ -0,0 +1,3 @@
<svg width="24" height="11" viewBox="0 0 24 11" fill="none" xmlns="http://www.w3.org/2000/svg">
<path id="Arrow Shape" d="M9.87868 1.12132C11.0503 -0.0502525 12.9497 -0.0502525 14.1213 1.12132L23.3137 10.3137H0.686292L9.87868 1.12132Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 258 B

View File

Before

Width:  |  Height:  |  Size: 792 B

After

Width:  |  Height:  |  Size: 792 B

View File

Before

Width:  |  Height:  |  Size: 579 B

After

Width:  |  Height:  |  Size: 579 B

View File

@@ -0,0 +1,3 @@
<svg width="6" height="30" viewBox="0 0 6 30" fill="none" xmlns="http://www.w3.org/2000/svg">
<path id="Line 3" d="M1.44595 28.7455L5.49125 1.00004" stroke="#101828" stroke-opacity="0.08" stroke-linecap="round"/>
</svg>

After

Width:  |  Height:  |  Size: 220 B

View File

@@ -0,0 +1,8 @@
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="piggy-bank-mod">
<g id="Union">
<path d="M12.75 1.80737C12.75 3.18809 11.6307 4.30738 10.25 4.30738C8.8693 4.30738 7.74998 3.18809 7.74998 1.80737L12.75 1.80737Z" fill="#444CE7"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.29769 4.71516C6.27454 4.43606 7.31331 4.77702 7.93687 5.55738H11.8125C14.4013 5.55738 16.5 7.65605 16.5 10.2449C16.5 12.5126 14.8896 14.4043 12.75 14.8386V16.1824H11.5V14.9324H7.12498V16.1824H5.87498V14.8508C5.05321 14.6764 4.30548 14.229 3.76111 13.5695L2.99101 12.6365L1.5 12.0103V8.93745L3.29116 8.46851L4 7.56623V5.08593L5.29769 4.71516ZM7.75 7.43238H12.75V8.68239H7.75V7.43238ZM5.875 8.99489C5.875 9.51264 5.45527 9.93239 4.9375 9.93239C4.41973 9.93239 4 9.51264 4 8.99489C4 8.47714 4.41973 8.05739 4.9375 8.05739C5.45527 8.05739 5.875 8.47714 5.875 8.99489Z" fill="#444CE7"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 934 B

View File

@@ -0,0 +1,7 @@
<svg width="15" height="16" viewBox="0 0 15 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="Group">
<path id="Vector" d="M13.008 4.24996H9.62427V0.866211L13.008 4.24996Z" fill="#676F83"/>
<path id="Vector_2" d="M7.18052 12.375H3.06177C2.97889 12.375 2.8994 12.3421 2.8408 12.2835C2.78219 12.2249 2.74927 12.1454 2.74927 12.0625V11.4375C2.74927 11.3546 2.78219 11.2751 2.8408 11.2165C2.8994 11.1579 2.97889 11.125 3.06177 11.125H7.18052C7.29883 10.4268 7.61311 9.7765 8.08677 9.25H3.06177C2.97889 9.25 2.8994 9.21708 2.8408 9.15847C2.78219 9.09987 2.74927 9.02038 2.74927 8.9375V8.3125C2.74927 8.22962 2.78219 8.15013 2.8408 8.09153C2.8994 8.03292 2.97889 8 3.06177 8H10.8743C11.798 8.00025 12.6888 8.34321 13.3743 8.9625V5.5H8.99927C8.83351 5.5 8.67454 5.43415 8.55733 5.31694C8.44011 5.19973 8.37427 5.04076 8.37427 4.875V0.5H1.49927C1.33351 0.5 1.17454 0.565848 1.05733 0.683058C0.940116 0.800269 0.874268 0.95924 0.874268 1.125V14.875C0.874268 15.0408 0.940116 15.1997 1.05733 15.3169C1.17454 15.4342 1.33351 15.5 1.49927 15.5H10.2493C9.46028 15.4015 8.72775 15.0392 8.17066 14.4719C7.61356 13.9046 7.26462 13.1656 7.18052 12.375ZM3.06177 4.875H6.18677C6.26965 4.875 6.34913 4.90792 6.40774 4.96653C6.46634 5.02513 6.49927 5.10462 6.49927 5.1875V5.8125C6.49927 5.89538 6.46634 5.97487 6.40774 6.03347C6.34913 6.09208 6.26965 6.125 6.18677 6.125H3.06177C2.97889 6.125 2.8994 6.09208 2.8408 6.03347C2.78219 5.97487 2.74927 5.89538 2.74927 5.8125V5.1875C2.74927 5.10462 2.78219 5.02513 2.8408 4.96653C2.8994 4.90792 2.97889 4.875 3.06177 4.875Z" fill="#676F83"/>
<path id="Vector_3" d="M14.4411 14.4331L13.0199 13.0119C13.2496 12.6309 13.3721 12.1949 13.3743 11.75C13.3743 11.2555 13.2276 10.7722 12.9529 10.3611C12.6782 9.94995 12.2878 9.62952 11.831 9.4403C11.3742 9.25108 10.8715 9.20157 10.3865 9.29804C9.90159 9.3945 9.45613 9.6326 9.1065 9.98223C8.75687 10.3319 8.51877 10.7773 8.42231 11.2623C8.32584 11.7472 8.37535 12.2499 8.56457 12.7067C8.75379 13.1635 9.07422 13.554 9.48534 13.8287C9.89647 14.1034 10.3798 14.25 10.8743 14.25C11.3192 14.2478 11.7552 14.1254 12.1361 13.8956L13.5574 15.3169C13.6753 15.4307 13.8331 15.4937 13.997 15.4923C14.1609 15.4909 14.3176 15.4251 14.4335 15.3093C14.5494 15.1934 14.6151 15.0366 14.6166 14.8728C14.618 14.7089 14.555 14.551 14.4411 14.4331ZM9.62427 11.75C9.62427 11.5028 9.69758 11.2611 9.83493 11.0555C9.97228 10.85 10.1675 10.6898 10.3959 10.5952C10.6243 10.5005 10.8757 10.4758 11.1181 10.524C11.3606 10.5723 11.5833 10.6913 11.7582 10.8661C11.933 11.0409 12.052 11.2637 12.1003 11.5061C12.1485 11.7486 12.1237 11.9999 12.0291 12.2284C11.9345 12.4568 11.7743 12.652 11.5687 12.7893C11.3632 12.9267 11.1215 13 10.8743 13C10.5427 13 10.2248 12.8683 9.99039 12.6339C9.75597 12.3995 9.62427 12.0815 9.62427 11.75Z" fill="#676F83"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@@ -0,0 +1,12 @@
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="general">
<g id="Vector">
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.375 3.75C12.375 3.12868 12.8787 2.625 13.5 2.625H15.75C16.3713 2.625 16.875 3.12868 16.875 3.75C16.875 4.37132 16.3713 4.875 15.75 4.875H13.5C12.8787 4.875 12.375 4.37132 12.375 3.75Z" fill="#444CE7"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M1.125 3.75C1.125 3.12868 1.62868 2.625 2.25 2.625H9.75C10.3713 2.625 10.875 3.12868 10.875 3.75C10.875 4.37132 10.3713 4.875 9.75 4.875H2.25C1.62868 4.875 1.125 4.37132 1.125 3.75Z" fill="#444CE7"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M1.125 9C1.125 8.37868 1.62868 7.875 2.25 7.875H4.5C5.12132 7.875 5.625 8.37868 5.625 9C5.625 9.62132 5.12132 10.125 4.5 10.125H2.25C1.62868 10.125 1.125 9.62132 1.125 9Z" fill="#444CE7"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.125 9C7.125 8.37868 7.62868 7.875 8.25 7.875H15.75C16.3713 7.875 16.875 8.37868 16.875 9C16.875 9.62132 16.3713 10.125 15.75 10.125H8.25C7.62868 10.125 7.125 9.62132 7.125 9Z" fill="#444CE7"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.375 14.25C12.375 13.6287 12.8787 13.125 13.5 13.125H15.75C16.3713 13.125 16.875 13.6287 16.875 14.25C16.875 14.8713 16.3713 15.375 15.75 15.375H13.5C12.8787 15.375 12.375 14.8713 12.375 14.25Z" fill="#444CE7"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M1.125 14.25C1.125 13.6287 1.62868 13.125 2.25 13.125H9.75C10.3713 13.125 10.875 13.6287 10.875 14.25C10.875 14.8713 10.3713 15.375 9.75 15.375H2.25C1.62868 15.375 1.125 14.8713 1.125 14.25Z" fill="#444CE7"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -0,0 +1,5 @@
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="gold-coin">
<path id="Vector" d="M9 1.5C7.51664 1.5 6.06659 1.93987 4.83323 2.76398C3.59986 3.58809 2.63856 4.75943 2.07091 6.12987C1.50325 7.50032 1.35472 9.00832 1.64411 10.4632C1.9335 11.918 2.64781 13.2544 3.6967 14.3033C4.7456 15.3522 6.08197 16.0665 7.53683 16.3559C8.99168 16.6453 10.4997 16.4967 11.8701 15.9291C13.2406 15.3614 14.4119 14.4001 15.236 13.1668C16.0601 11.9334 16.5 10.4834 16.5 9C16.5 7.01087 15.7098 5.10322 14.3033 3.6967C12.8968 2.29018 10.9891 1.5 9 1.5ZM11.0656 5.09312L11.8006 4.08187C11.8489 4.01543 11.9098 3.95915 11.9798 3.91623C12.0498 3.87332 12.1276 3.84462 12.2087 3.83176C12.2898 3.81891 12.3726 3.82215 12.4525 3.84131C12.5323 3.86047 12.6076 3.89518 12.6741 3.94344C12.7405 3.9917 12.7968 4.05257 12.8397 4.12259C12.8826 4.1926 12.9113 4.27038 12.9242 4.35148C12.937 4.43259 12.9338 4.51543 12.9146 4.59529C12.8955 4.67514 12.8608 4.75043 12.8125 4.81687L12.0775 5.82812C11.98 5.96231 11.8333 6.05228 11.6695 6.07824C11.5057 6.1042 11.3382 6.06403 11.2041 5.96656C11.0699 5.86909 10.9799 5.72232 10.954 5.55851C10.928 5.39471 10.9682 5.22731 11.0656 5.09312ZM5.32625 3.94375C5.39271 3.89519 5.4681 3.86023 5.54811 3.84089C5.62811 3.82154 5.71115 3.81819 5.79245 3.83103C5.87375 3.84386 5.95172 3.87263 6.02187 3.91567C6.09203 3.95872 6.15299 4.0152 6.20125 4.08187L6.9375 5.09312C7.03497 5.22772 7.07498 5.39552 7.04872 5.55962C7.02247 5.72371 6.9321 5.87066 6.7975 5.96812C6.66291 6.06559 6.4951 6.1056 6.33101 6.07934C6.16691 6.05309 6.01997 5.96272 5.9225 5.82812L5.1875 4.81687C5.13927 4.75044 5.10459 4.67515 5.08546 4.59531C5.06632 4.51548 5.06311 4.43265 5.07599 4.35157C5.08888 4.27048 5.11761 4.19274 5.16055 4.12276C5.20349 4.05279 5.2598 3.99196 5.32625 3.94375ZM5.0325 10.9437L3.845 11.33C3.76604 11.3594 3.68196 11.3725 3.5978 11.3686C3.51364 11.3646 3.43114 11.3437 3.35527 11.3071C3.2794 11.2705 3.21171 11.2189 3.15629 11.1554C3.10086 11.092 3.05883 11.018 3.03274 10.9379C3.00664 10.8577 2.997 10.7732 3.00442 10.6893C3.01183 10.6053 3.03613 10.5238 3.07587 10.4495C3.1156 10.3752 3.16995 10.3097 3.23564 10.2569C3.30133 10.2042 3.37701 10.1653 3.45813 10.1425L4.64563 9.75625C4.72467 9.72655 4.80892 9.71317 4.89327 9.71693C4.97763 9.72069 5.06035 9.7415 5.13644 9.77811C5.21253 9.81472 5.28042 9.86637 5.33599 9.92994C5.39157 9.99352 5.43369 10.0677 5.45981 10.148C5.48593 10.2283 5.4955 10.3131 5.48796 10.3972C5.48041 10.4813 5.45591 10.563 5.41591 10.6373C5.37592 10.7117 5.32127 10.7772 5.25527 10.8299C5.18926 10.8825 5.11389 10.9213 5.0325 10.9437ZM9.625 14.625C9.625 14.7908 9.55915 14.9497 9.44194 15.0669C9.32473 15.1841 9.16576 15.25 9 15.25C8.83424 15.25 8.67527 15.1841 8.55806 15.0669C8.44085 14.9497 8.375 14.7908 8.375 14.625V13.375C8.375 13.2092 8.44085 13.0503 8.55806 12.9331C8.67527 12.8158 8.83424 12.75 9 12.75C9.16576 12.75 9.32473 12.8158 9.44194 12.9331C9.55915 13.0503 9.625 13.2092 9.625 13.375V14.625ZM9 11L6.6475 12.2375L7.09688 9.61812L5.19375 7.76312L7.82375 7.38125L9 5L10.1763 7.38125L12.8063 7.76312L10.9031 9.61812L11.3525 12.2375L9 11ZM14.1563 11.3312L12.9688 10.945C12.8874 10.9225 12.8114 10.8838 12.7454 10.8311C12.6794 10.7784 12.6247 10.7129 12.5847 10.6386C12.5447 10.5642 12.5202 10.4825 12.5127 10.3984C12.5051 10.3143 12.5147 10.2295 12.5408 10.1492C12.5669 10.0689 12.6091 9.99477 12.6646 9.9312C12.7202 9.86762 12.7881 9.81597 12.8642 9.77936C12.9403 9.74275 13.023 9.72194 13.1074 9.71818C13.1917 9.71442 13.276 9.7278 13.355 9.7575L14.5425 10.1437C14.6236 10.1665 14.6993 10.2054 14.765 10.2582C14.8307 10.311 14.885 10.3764 14.9248 10.4507C14.9645 10.525 14.9888 10.6066 14.9962 10.6905C15.0036 10.7744 14.994 10.859 14.9679 10.9391C14.9418 11.0192 14.8998 11.0932 14.8443 11.1567C14.7889 11.2201 14.7212 11.2717 14.6454 11.3083C14.5695 11.345 14.487 11.3659 14.4028 11.3698C14.3187 11.3738 14.2352 11.3606 14.1563 11.3312Z" fill="#EF6820"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@@ -0,0 +1,13 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="Group">
<path id="Vector" d="M2.54546 15.5001C2.1409 15.5001 1.74544 15.3801 1.40906 15.1554C1.07269 14.9306 0.810517 14.6112 0.655702 14.2374C0.500886 13.8636 0.460379 13.4524 0.539304 13.0556C0.618228 12.6588 0.813039 12.2943 1.0991 12.0083C1.38516 11.7222 1.74963 11.5274 2.14641 11.4485C2.54319 11.3696 2.95446 11.4101 3.32822 11.5649C3.70198 11.7197 4.02143 11.9819 4.24619 12.3182C4.47095 12.6546 4.59091 13.0501 4.59091 13.4546C4.59091 13.9971 4.37541 14.5174 3.99181 14.901C3.60821 15.2846 3.08794 15.5001 2.54546 15.5001Z" fill="#6938EF"/>
<path id="Vector_2" d="M8.00005 5.95459C7.59549 5.95459 7.20003 6.07455 6.86365 6.29931C6.52728 6.52407 6.26511 6.84352 6.11029 7.21728C5.95548 7.59104 5.91497 8.00231 5.99389 8.39909C6.07282 8.79587 6.26763 9.16034 6.55369 9.4464C6.83975 9.73246 7.20422 9.92727 7.601 10.0062C7.99778 10.0851 8.40905 10.0446 8.78281 9.8898C9.15656 9.73498 9.47602 9.47281 9.70078 9.13644C9.92554 8.80006 10.0455 8.4046 10.0455 8.00004C10.0455 7.45756 9.83 6.93729 9.4464 6.55369C9.0628 6.17009 8.54253 5.95459 8.00005 5.95459Z" fill="#6938EF"/>
<path id="Vector_3" d="M2.54546 0.5C2.1409 0.5 1.74544 0.619964 1.40906 0.844721C1.07269 1.06948 0.810517 1.38893 0.655702 1.76269C0.500886 2.13645 0.460379 2.54772 0.539304 2.9445C0.618228 3.34128 0.813039 3.70575 1.0991 3.99181C1.38516 4.27787 1.74963 4.47268 2.14641 4.55161C2.54319 4.63053 2.95446 4.59002 3.32822 4.43521C3.70198 4.28039 4.02143 4.01822 4.24619 3.68185C4.47095 3.34547 4.59091 2.95001 4.59091 2.54545C4.59091 2.00297 4.37541 1.4827 3.99181 1.0991C3.60821 0.715503 3.08794 0.5 2.54546 0.5Z" fill="#6938EF"/>
<path id="Vector_4" d="M13.4545 0.5C13.05 0.5 12.6545 0.619964 12.3181 0.844721C11.9817 1.06948 11.7196 1.38893 11.5648 1.76269C11.4099 2.13645 11.3694 2.54772 11.4484 2.9445C11.5273 3.34128 11.7221 3.70575 12.0082 3.99181C12.2942 4.27787 12.6587 4.47268 13.0555 4.55161C13.4522 4.63053 13.8635 4.59002 14.2373 4.43521C14.611 4.28039 14.9305 4.01822 15.1552 3.68185C15.38 3.34547 15.5 2.95001 15.5 2.54545C15.5 2.00297 15.2845 1.4827 14.9009 1.0991C14.5173 0.715503 13.997 0.5 13.4545 0.5Z" fill="#6938EF"/>
<path id="Vector_5" d="M13.4545 11.4092C13.05 11.4092 12.6545 11.5291 12.3181 11.7539C11.9817 11.9787 11.7196 12.2981 11.5648 12.6719C11.4099 13.0456 11.3694 13.4569 11.4484 13.8537C11.5273 14.2505 11.7221 14.6149 12.0082 14.901C12.2942 15.1871 12.6587 15.3819 13.0555 15.4608C13.4522 15.5397 13.8635 15.4992 14.2373 15.3444C14.611 15.1896 14.9305 14.9274 15.1552 14.591C15.38 14.2547 15.5 13.8592 15.5 13.4546C15.5 12.9121 15.2845 12.3919 14.9009 12.0083C14.5173 11.6247 13.997 11.4092 13.4545 11.4092Z" fill="#6938EF"/>
<path id="Vector_6" d="M4.59091 5.95459H0.5V10.0455H4.59091V5.95459Z" fill="#6938EF"/>
<path id="Vector_7" d="M15.5 5.95459H11.4091V10.0455H15.5V5.95459Z" fill="#6938EF"/>
<path id="Vector_8" d="M10.0455 0.5H5.95459V4.59091H10.0455V0.5Z" fill="#6938EF"/>
<path id="Vector_9" d="M10.0455 11.4092H5.95459V15.5001H10.0455V11.4092Z" fill="#6938EF"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@@ -0,0 +1,13 @@
export { default as Chunk } from './Chunk'
export { default as Collapse } from './Collapse'
export { default as Divider } from './Divider'
export { default as File } from './File'
export { default as GeneralType } from './GeneralType'
export { default as LayoutRight2LineMod } from './LayoutRight2LineMod'
export { default as OptionCardEffectBlueLight } from './OptionCardEffectBlueLight'
export { default as OptionCardEffectBlue } from './OptionCardEffectBlue'
export { default as OptionCardEffectOrange } from './OptionCardEffectOrange'
export { default as OptionCardEffectPurple } from './OptionCardEffectPurple'
export { default as ParentChildType } from './ParentChildType'
export { default as SelectionMod } from './SelectionMod'
export { default as Watercrawl } from './Watercrawl'

View File

@@ -0,0 +1,9 @@
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="parent-child">
<g id="Vector">
<path d="M5.56251 5.8125C6.77063 5.8125 7.75001 4.83312 7.75001 3.625C7.75001 2.41688 6.77063 1.4375 5.56251 1.4375C4.35439 1.4375 3.37501 2.41688 3.37501 3.625C3.37501 4.83312 4.35439 5.8125 5.56251 5.8125Z" fill="#0BA5EC"/>
<path d="M12.4375 5.8125C13.6456 5.8125 14.625 4.83312 14.625 3.625C14.625 2.41688 13.6456 1.4375 12.4375 1.4375C11.2294 1.4375 10.25 2.41688 10.25 3.625C10.25 4.83312 11.2294 5.8125 12.4375 5.8125Z" fill="#0BA5EC"/>
<path d="M12.4375 7.0625C11.7566 7.06326 11.0868 7.23541 10.4899 7.56309C9.89294 7.89077 9.38811 8.36342 9.02188 8.9375C9.51723 8.94327 9.99017 9.14485 10.3374 9.49819C10.6846 9.85154 10.8779 10.3279 10.875 10.8233C10.8721 11.3187 10.6733 11.7928 10.322 12.1421C9.97065 12.4913 9.49539 12.6874 9.00001 12.6874C8.50462 12.6874 8.02937 12.4913 7.67805 12.1421C7.32674 11.7928 7.12793 11.3187 7.12504 10.8233C7.12215 10.3279 7.31542 9.85154 7.66263 9.49819C8.00984 9.14485 8.48278 8.94327 8.97813 8.9375C8.50629 8.1962 7.80649 7.62817 6.984 7.31887C6.16151 7.00957 5.26082 6.97572 4.41744 7.22243C3.57406 7.46914 2.8336 7.98305 2.30746 8.68685C1.78132 9.39065 1.49796 10.2463 1.50001 11.125V15.1875C1.50001 15.3533 1.56586 15.5122 1.68307 15.6294C1.80028 15.7466 1.95925 15.8125 2.12501 15.8125H6.50001V14.25L4.25001 12.5625C4.18435 12.5132 4.12903 12.4515 4.08721 12.3809C4.0454 12.3103 4.0179 12.2321 4.00629 12.1509C3.98285 11.9868 4.02555 11.8201 4.12501 11.6875C4.22447 11.5549 4.37253 11.4672 4.53662 11.4438C4.70072 11.4203 4.8674 11.463 5.00001 11.5625L7.33313 13.3125H10.6669L13 11.5625C13.1326 11.463 13.2993 11.4203 13.4634 11.4438C13.6275 11.4672 13.7755 11.5549 13.875 11.6875C13.9745 11.8201 14.0172 11.9868 13.9937 12.1509C13.9703 12.315 13.8826 12.463 13.75 12.5625L11.5 14.25V15.8125H15.875C16.0408 15.8125 16.1997 15.7466 16.3169 15.6294C16.4342 15.5122 16.5 15.3533 16.5 15.1875V11.125C16.4987 10.048 16.0702 9.01541 15.3087 8.25383C14.5471 7.49226 13.5145 7.06382 12.4375 7.0625Z" fill="#0BA5EC"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@@ -0,0 +1,5 @@
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="qa">
<path id="Vector" fill-rule="evenodd" clip-rule="evenodd" d="M16.5015 3.75C16.5015 2.92157 15.8299 2.25 15.0015 2.25H6.00146C5.17304 2.25 4.50146 2.92157 4.50146 3.75V5.25H3.00146C2.17304 5.25 1.50146 5.92157 1.50146 6.75V12.75C1.50146 13.5784 2.17304 14.25 3.00146 14.25H3.75146V15.375C3.75146 15.6407 3.89209 15.8867 4.12112 16.0214C4.35015 16.1562 4.6334 16.1597 4.8657 16.0307L8.07083 14.25H12.0015C12.8299 14.25 13.5015 13.5784 13.5015 12.75V11.25H15.0015C15.8299 11.25 16.5015 10.5785 16.5015 9.75V3.75ZM12.0015 5.25H6.00146V3.75H15.0015V9.75H13.5015V6.75C13.5015 5.92157 12.8299 5.25 12.0015 5.25ZM5.25 7.5C4.83579 7.5 4.5 7.83579 4.5 8.25C4.5 8.66421 4.83579 9 5.25 9H9.75C10.1642 9 10.5 8.66421 10.5 8.25C10.5 7.83579 10.1642 7.5 9.75 7.5H5.25ZM5.25 10.5C4.83579 10.5 4.5 10.8358 4.5 11.25C4.5 11.6642 4.83579 12 5.25 12H7.5C7.91421 12 8.25 11.6642 8.25 11.25C8.25 10.8358 7.91421 10.5 7.5 10.5H5.25Z" fill="#676F83"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@@ -0,0 +1,13 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="Group">
<path id="Vector" d="M4.25 15.5H0.5V11.75H4.25V15.5Z" fill="#676F83"/>
<path id="Vector_2" d="M9.875 9.875H6.125V6.125H9.875V9.875Z" fill="#676F83"/>
<path id="Vector_3" d="M4.25 9.875H0.5V6.125H4.25V9.875Z" fill="#676F83"/>
<path id="Vector_4" d="M9.875 4.25H6.125V0.5H9.875V4.25Z" fill="#676F83"/>
<path id="Vector_5" d="M4.25 4.25H0.5V0.5H4.25V4.25Z" fill="#676F83"/>
<path id="Vector_6" d="M15.5 4.25H11.75V0.5H15.5V4.25Z" fill="#676F83"/>
<path id="Vector_7" d="M14.875 12.375H12.375V14.875H14.875V12.375Z" fill="#676F83"/>
<path id="Vector_8" d="M14.875 6.75H12.375V9.25H14.875V6.75Z" fill="#676F83"/>
<path id="Vector_9" d="M9.25 12.375H6.75V14.875H9.25V12.375Z" fill="#676F83"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 810 B

View File

@@ -0,0 +1,9 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="Icon L">
<g id="Subtract">
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.3333 1.66667C11.3333 1.29848 11.0348 1 10.6666 1C10.2984 1 9.99992 1.29848 9.99992 1.66667V14.3333C9.99992 14.7015 10.2984 15 10.6666 15C11.0348 15 11.3333 14.7015 11.3333 14.3333V13.3333H12.6666C13.7712 13.3333 14.6666 12.4379 14.6666 11.3333V4.66667C14.6666 3.5621 13.7712 2.66667 12.6666 2.66667H11.3333V1.66667ZM12.6666 12H11.3333V4H12.6666C13.0348 4 13.3333 4.29847 13.3333 4.66667V11.3333C13.3333 11.7015 13.0348 12 12.6666 12Z" fill="#354052"/>
<path d="M8.66658 13.3333V12H3.33325C2.96506 12 2.66659 11.7015 2.66659 11.3333V4.66667C2.66659 4.29848 2.96506 4 3.33325 4H8.66658V2.66667H3.33325C2.22868 2.66667 1.33325 3.5621 1.33325 4.66667V11.3333C1.33325 12.4379 2.22869 13.3333 3.33325 13.3333H8.66658Z" fill="#354052"/>
<path d="M8.66658 5.24892C8.63219 5.24484 8.59703 5.24339 8.56132 5.24478L8.51461 5.24659C7.98481 5.26717 7.48663 5.51351 7.15247 5.92673L6.57985 6.63483L6.44192 6.22222C6.26445 5.69137 5.75558 5.35376 5.20721 5.37506L4.4811 5.40327C4.11319 5.41756 3.82653 5.7274 3.84082 6.09531C3.85511 6.46322 4.16494 6.74989 4.53286 6.7356L5.19902 6.70972L5.58518 7.86484L4.47727 9.23487C4.38815 9.34509 4.25098 9.41522 4.10014 9.42108L4.05343 9.4229C3.68552 9.43719 3.39885 9.74702 3.41314 10.1149C3.42743 10.4828 3.73727 10.7695 4.10518 10.7552L4.15189 10.7534C4.68169 10.7328 5.17987 10.4865 5.51403 10.0733L6.08671 9.3651L6.22466 9.77778C6.40213 10.3086 6.911 10.6462 7.45937 10.6249C7.46692 10.6246 7.47448 10.6242 7.48202 10.6237L8.66658 10.5372V9.20033L7.46676 9.2879L7.08138 8.13509L8.18923 6.76513C8.27836 6.65491 8.41553 6.58478 8.56637 6.57892L8.61307 6.5771C8.63111 6.5764 8.64896 6.57499 8.66658 6.5729V5.24892Z" fill="#354052"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -0,0 +1,11 @@
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="pipeline-fill">
<g id="Vector">
<path d="M3.7501 2.56885C2.6835 2.56885 1.81885 3.4335 1.81885 4.5001C1.81885 5.5667 2.6835 6.43135 3.7501 6.43135H6.0001C7.0667 6.43135 7.93135 5.5667 7.93135 4.5001C7.93135 3.4335 7.0667 2.56885 6.0001 2.56885H3.7501Z" fill="#155AEF"/>
<path d="M11.2501 7.06885C10.1835 7.06885 9.31885 7.9335 9.31885 9.0001C9.31885 10.0667 10.1835 10.9313 11.2501 10.9313H13.5001C14.5667 10.9313 15.4313 10.0667 15.4313 9.0001C15.4313 7.9335 14.5667 7.06885 13.5001 7.06885H11.2501Z" fill="#155AEF"/>
<path d="M1.81885 13.5001C1.81885 12.4335 2.6835 11.5688 3.7501 11.5688H6.0001C7.0667 11.5688 7.93135 12.4335 7.93135 13.5001C7.93135 14.5667 7.0667 15.4313 6.0001 15.4313H3.7501C2.6835 15.4313 1.81885 14.5667 1.81885 13.5001Z" fill="#155AEF"/>
<path d="M9.75011 5.25011H9.00011V3.75011H9.75011C10.9927 3.75011 12.0001 4.75747 12.0001 6.00011H10.5001C10.5001 5.58589 10.1643 5.25011 9.75011 5.25011Z" fill="#155AEF"/>
<path d="M12.0001 12.0001C12.0001 13.2427 10.9927 14.2501 9.75011 14.2501H9.00011V12.7501H9.75011C10.1643 12.7501 10.5001 12.4143 10.5001 12.0001H12.0001Z" fill="#155AEF"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1,5 @@
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="pipeline-line">
<path id="Vector" d="M3.75 15.75C2.50733 15.75 1.5 14.7426 1.5 13.5C1.5 12.2574 2.50733 11.25 3.75 11.25H6C6.97943 11.25 7.81268 11.8758 8.12175 12.7493L9 12.75C9.825 12.75 10.5 12.075 10.5 11.25L10.4993 11.1217C9.6258 10.8127 9 9.97942 9 9C9 8.02058 9.6258 7.18732 10.4993 6.87825L10.5 6.75C10.5 5.925 9.825 5.25 9 5.25L8.12197 5.24993C7.81313 6.12383 6.97973 6.75 6 6.75L3.75 6.75C2.50733 6.75 1.5 5.74268 1.5 4.5C1.5 3.25733 2.50732 2.25 3.75 2.25L6 2.25C6.97942 2.25 7.81268 2.8758 8.12175 3.74932L9 3.75C10.6575 3.75 12 5.0925 12 6.75L13.5 6.75C14.7426 6.75 15.75 7.75732 15.75 9C15.75 10.2427 14.7426 11.25 13.5 11.25H12C12 12.9069 10.6569 14.25 9 14.25L8.12198 14.2499C7.81313 15.1239 6.97973 15.75 6 15.75H3.75ZM3.75 5.25L6 5.25C6.41423 5.25 6.75 4.91423 6.75 4.5C6.75 4.08578 6.41423 3.75 6 3.75L3.75 3.75C3.33578 3.75 3 4.08578 3 4.5C3 4.91423 3.33578 5.25 3.75 5.25ZM11.25 9.75H13.5C13.9142 9.75 14.25 9.41422 14.25 9C14.25 8.58577 13.9142 8.25 13.5 8.25L11.25 8.25C10.8358 8.25 10.5 8.58577 10.5 9C10.5 9.41422 10.8358 9.75 11.25 9.75ZM3.75 14.25H6C6.41423 14.25 6.75 13.9142 6.75 13.5C6.75 13.0858 6.41423 12.75 6 12.75H3.75C3.33578 12.75 3 13.0858 3 13.5C3 13.9142 3.33578 14.25 3.75 14.25Z" fill="#495464"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -0,0 +1,3 @@
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M6.99967 1.16675C8.17599 1.16675 9.26631 1.33585 10.0833 1.6276C10.4891 1.77255 10.8588 1.95906 11.1383 2.19499C11.415 2.42869 11.6663 2.76876 11.6663 3.20841V10.7917C11.6663 11.2314 11.415 11.5715 11.1383 11.8052C10.8588 12.0411 10.4891 12.2276 10.0833 12.3726C9.26631 12.6643 8.17599 12.8334 6.99967 12.8334C5.82336 12.8334 4.73304 12.6643 3.9161 12.3726C3.51024 12.2276 3.14054 12.0411 2.86108 11.8052C2.58431 11.5715 2.33301 11.2314 2.33301 10.7917V3.20841C2.33301 2.76876 2.58431 2.42869 2.86108 2.19499C3.14054 1.95906 3.51023 1.77256 3.9161 1.6276C4.73304 1.33585 5.82336 1.16675 6.99967 1.16675ZM10.4997 8.40942C10.367 8.47176 10.2275 8.52936 10.0833 8.58089C9.26631 8.87265 8.17599 9.04175 6.99967 9.04175C5.82336 9.04175 4.73304 8.87265 3.9161 8.58089C3.77181 8.52936 3.6324 8.47176 3.49967 8.40942V10.7815C3.50345 10.7927 3.52369 10.8377 3.61361 10.9137C3.74739 11.0266 3.97559 11.1548 4.30859 11.2737C4.96952 11.5097 5.92091 11.6667 6.99967 11.6667C8.07844 11.6667 9.02984 11.5097 9.69076 11.2737C10.0238 11.1548 10.252 11.0266 10.3857 10.9137C10.4757 10.8377 10.4959 10.7927 10.4997 10.7815V8.40942ZM10.4997 4.61776C10.367 4.68009 10.2275 4.73769 10.0833 4.78923C9.26631 5.08098 8.17599 5.25008 6.99967 5.25008C5.82336 5.25008 4.73304 5.08098 3.9161 4.78923C3.77181 4.73769 3.6324 4.68009 3.49967 4.61776V6.98983C3.50345 7.00103 3.52369 7.04607 3.61361 7.12199C3.74739 7.23495 3.97559 7.36309 4.30859 7.48201C4.96952 7.71804 5.92091 7.87508 6.99967 7.87508C8.07844 7.87508 9.02984 7.71804 9.69076 7.48201C10.0238 7.36309 10.252 7.23495 10.3857 7.12199C10.4757 7.04607 10.4959 7.00103 10.4997 6.98983V4.61776ZM6.99967 2.33341C5.92091 2.33341 4.96951 2.49046 4.30859 2.72648C3.97559 2.84541 3.74739 2.97355 3.61361 3.08651C3.54094 3.14787 3.51356 3.189 3.50366 3.20841C3.51356 3.22783 3.54094 3.26896 3.61361 3.33032C3.74739 3.44328 3.97559 3.57142 4.30859 3.69035C4.96951 3.92637 5.92091 4.08341 6.99967 4.08341C8.07844 4.08341 9.02984 3.92637 9.69076 3.69035C10.0238 3.57142 10.252 3.44328 10.3857 3.33032C10.4581 3.26921 10.4851 3.22792 10.4951 3.20841C10.4851 3.18891 10.4581 3.14762 10.3857 3.08651C10.252 2.97355 10.0238 2.84541 9.69076 2.72648C9.02984 2.49046 8.07844 2.33341 6.99967 2.33341Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@@ -0,0 +1,5 @@
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="Knowledge Base">
<path id="Vector" d="M5.25016 3.49999C4.928 3.49999 4.66683 3.76116 4.66683 4.08332C4.66683 4.40549 4.928 4.66666 5.25016 4.66666V3.49999ZM8.75016 4.66666C9.07234 4.66666 9.3335 4.40549 9.3335 4.08332C9.3335 3.76116 9.07234 3.49999 8.75016 3.49999V4.66666ZM5.25016 5.83332C4.928 5.83332 4.66683 6.09448 4.66683 6.41666C4.66683 6.73883 4.928 6.99999 5.25016 6.99999V5.83332ZM7.00016 6.99999C7.32234 6.99999 7.5835 6.73883 7.5835 6.41666C7.5835 6.09448 7.32234 5.83332 7.00016 5.83332V6.99999ZM4.0835 2.33332H9.91683V1.16666H4.0835V2.33332ZM10.5002 2.91666V11.0833H11.6668V2.91666H10.5002ZM9.91683 11.6667H4.0835V12.8333H9.91683V11.6667ZM3.50016 11.0833V2.91666H2.3335V11.0833H3.50016ZM4.0835 11.6667C3.76133 11.6667 3.50016 11.4055 3.50016 11.0833H2.3335C2.3335 12.0498 3.117 12.8333 4.0835 12.8333V11.6667ZM10.5002 11.0833C10.5002 11.4055 10.239 11.6667 9.91683 11.6667V12.8333C10.8834 12.8333 11.6668 12.0498 11.6668 11.0833H10.5002ZM9.91683 2.33332C10.239 2.33332 10.5002 2.59449 10.5002 2.91666H11.6668C11.6668 1.95016 10.8834 1.16666 9.91683 1.16666V2.33332ZM4.0835 1.16666C3.117 1.16666 2.3335 1.95016 2.3335 2.91666H3.50016C3.50016 2.59449 3.76133 2.33332 4.0835 2.33332V1.16666ZM10.5002 6.99999V8.74999H11.6668V6.99999H10.5002ZM9.91683 9.33332H4.0835V10.5H9.91683V9.33332ZM4.0835 12.8333H5.8335V11.6667H4.0835V12.8333ZM4.0835 9.33332C3.117 9.33332 2.3335 10.1168 2.3335 11.0833H3.50016C3.50016 10.7611 3.76133 10.5 4.0835 10.5V9.33332ZM10.5002 8.74999C10.5002 9.07216 10.239 9.33332 9.91683 9.33332V10.5C10.8834 10.5 11.6668 9.71651 11.6668 8.74999H10.5002ZM5.25016 4.66666H8.75016V3.49999H5.25016V4.66666ZM5.25016 6.99999H7.00016V5.83332H5.25016V6.99999Z" fill="white"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -89,4 +89,4 @@
]
},
"name": "Robot"
}
}

View File

@@ -86,4 +86,4 @@
]
},
"name": "User"
}
}

View File

@@ -26,4 +26,4 @@
]
},
"name": "ArCube1"
}
}

View File

@@ -35,4 +35,4 @@
]
},
"name": "Asterisk"
}
}

View File

@@ -176,4 +176,4 @@
]
},
"name": "AwsMarketplace"
}
}

View File

@@ -190,4 +190,4 @@
]
},
"name": "Azure"
}
}

View File

@@ -36,4 +36,4 @@
]
},
"name": "Buildings"
}
}

Some files were not shown because too many files have changed in this diff Show More